Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 24/02/2017, à 20:54

thurston

[Resolu] merge fichiers mp3 (2>1) de taille optimale moyenne

Bonjour,

je voudrais pouvoir, dans une structure de fichier de type suivant

folder1 \ 1.mp3 2.mp3
folder2 \ folder2.1 \ 3.mp3 4.mp3 5.mp3
folder3 \ folder3.1 \ 6.mp3 7.mp3 8.mp3 9.mp3 10.mp3
            \ folder3.2 \ 11.mp3 12.mp3 13.mp3

assembler les fichiers mp3 deux à deux, en assemblant chaque fois le plus leger avec le plus gros pour obtenir

folder 1 \ 1+2.mp3
folder2 \ folder2.1 \ 3+4.mp3 5.mp3
folder3 \ folder3.1 \ 6+9.mp3 7+10.mp3
            \ folder3.2 \ 11+13.mp3 12.mp3

L'idée est de diviser par 2 le nombre de mp3 dans la structure initiale (limitation de mon player), en évitant de se retrouver avec 2 chansons très longues assemblées et 2 très courtes, au profit de la plus longue avec la plus courte etc...sur une structure folder existante. le + est symbolique dans le naming (ca se finira par un -), mais c'était confusion assurée ;-)

1. J'ai l'impression qu'un soft de type récursif (en bash absolument pour s'intégrer à mon script déjà existant) pourrait faire l'affaire et etre très rapide. Je ne sais hélas pas faire. (il faut traiter les mp3, et les assembler sans les reprendre en compte..je tente avec un listing (sort) par taille que je mets dans un fichier texte pour après prendre le premier et le dernier, puis les supprimer et recommencer...bien lourd, mais c'est mon niveau...)
2. Egalement, est ce que quelqu'un connait la manière la plus simple de mixer 2 fichiers mp3 entre eux? (je me fiche un peu des id.tags, le nom composé des deux noms serait suffisant (les numéros ci dessus sont en fait des titres, exemple 1.mp3 est en fait titre1.mp3).
Quelqu'un a peut être déjà un script dans le style?

Merci à toutes les bonnes âmes, qui sait...
A+
T

Dernière modification par thurston (Le 26/02/2017, à 21:39)

Hors ligne

#2 Le 25/02/2017, à 11:52

Hizoka

Re : [Resolu] merge fichiers mp3 (2>1) de taille optimale moyenne

Salut, je ferai un truc du genre :

ParentDossier="${HOME}"
FileOutput="Compilation"

while read Folder
do
  # modification de l'IFS
  OldIFS="${IFS}" IFS=$'\n'

  # Liste des fichiers mp3 triés par taille
  FileList=($(find "${Folder}" -maxdepth 1 -type f -iname "*.mp3" -printf "%s %p\n" | sort --version-sort))

  #  Remise en place de l'IFS
  IFS="${OldIFS}"

  # Assemblage du 1er et du dernier fichier s'il y a au moins 2 fichiers
  [[ ${#FileList[@]} -ge 2 ]] && cat "${Folder}/${FileList[0]##*/}" "${Folder}/${FileList[-1]##*/}" > "${Folder}/${FileOutput}0-1.mp3" || continue
  
  # Assemblage du 2e et de l'avant dernier fichier s'il y a au moins 4 fichiers
  [[ ${#FileList[@]} -ge 4 ]] && cat "${Folder}/${FileList[1]##*/}" "${Folder}/${FileList[-2]##*/}" > "${Folder}/${FileOutput}1-2.mp3" || continue

  # Assemblage du 3e et de l'avant avant dernier fichier s'il y a au moins 6 fichiers
  [[ ${#FileList[@]} -ge 6 ]] && cat "${Folder}/${FileList[2]##*/}" "${Folder}/${FileList[-3]##*/}" > "${Folder}/${FileOutput}2-3.mp3" || continue

  # Assemblage du 4e et de ... dernier fichier s'il y a au moins 8 fichiers
  [[ ${#FileList[@]} -ge 8 ]] && cat "${Folder}/${FileList[3]##*/}" "${Folder}/${FileList[-4]##*/}" > "${Folder}/${FileOutput}3-4.mp3" || continue

  # Assemblage du 5e et de .... dernier fichier s'il y a au moins 10 fichiers
  [[ ${#FileList[@]} -ge 10 ]] && cat "${Folder}/${FileList[4]##*/}" "${Folder}/${FileList[-5]##*/}" > "${Folder}/${FileOutput}4-5.mp3" || continue

  # Assemblage du 6e et de .... dernier fichier s'il y a au moins 12 fichiers
  [[ ${#FileList[@]} -ge 12 ]] && cat "${Folder}/${FileList[5]##*/}" "${Folder}/${FileList[-6]##*/}" > "${Folder}/${FileOutput}5-6.mp3" || continue

  # .....
done < <(find "${ParentDossier}" -type d)

Il te reste plus qu'à modifier l'adresse du dossier ParentDossier, tu peux également modifier le nom du mp3 de sortie via FileOutput. (j'ai mis l'annotation 0-1 pour dire item 0 et item -1...)

Il prend donc à chaque les extrémités de la liste pour les assembler et on continue comme ça à chaque fois....

Il faut qu'il y ait au moins 2 fichiers mp3 pour qu'il travaille.

Dernière modification par Hizoka (Le 25/02/2017, à 12:04)


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#3 Le 25/02/2017, à 15:38

thurston

Re : [Resolu] merge fichiers mp3 (2>1) de taille optimale moyenne

Bonjour Hizoka

j'avais pris un peu la meme voie.
1. Tri de tous les fichiers dans un fichier txt temporaire, tri par taille
2. je prends le dernier fichier et le premier fichier de la liste que j'assimile à min.file et max.file
3. je concatene cat min.file max.file > min.max.file
4. je supprime min et max file du fichier txt temporaire, en virant les lignes vides
5. je reprends le 1er et dernier de la liste txt etc...
6. je mets une condition si (1er et dernier sont les memes) ou fichier txt vide, alors je m'arrete.

Je trouvais que créer un fichier txt temporaire, en le faisant évoluer et en tapant dedans était un peu naif; c'était assez simple à gérer toutefois.
Merci Hizoka pour les pistes de ton script.
A+
T

Hors ligne

#4 Le 25/02/2017, à 17:13

Compte anonymisé

Re : [Resolu] merge fichiers mp3 (2>1) de taille optimale moyenne

  # Assemblage du 1er et du dernier fichier s'il y a au moins 2 fichiers
  [[ ${#FileList[@]} -ge 2 ]] && cat "${Folder}/${FileList[0]##*/}" "${Folder}/${FileList[-1]##*/}" > "${Folder}/${FileOutput}0-1.mp3" || continue
  
  # Assemblage du 2e et de l'avant dernier fichier s'il y a au moins 4 fichiers
  [[ ${#FileList[@]} -ge 4 ]] && cat "${Folder}/${FileList[1]##*/}" "${Folder}/${FileList[-2]##*/}" > "${Folder}/${FileOutput}1-2.mp3" || continue

  # Assemblage du 3e et de l'avant avant dernier fichier s'il y a au moins 6 fichiers
  [[ ${#FileList[@]} -ge 6 ]] && cat "${Folder}/${FileList[2]##*/}" "${Folder}/${FileList[-3]##*/}" > "${Folder}/${FileOutput}2-3.mp3" || continue

  # Assemblage du 4e et de ... dernier fichier s'il y a au moins 8 fichiers
  [[ ${#FileList[@]} -ge 8 ]] && cat "${Folder}/${FileList[3]##*/}" "${Folder}/${FileList[-4]##*/}" > "${Folder}/${FileOutput}3-4.mp3" || continue

  # Assemblage du 5e et de .... dernier fichier s'il y a au moins 10 fichiers
  [[ ${#FileList[@]} -ge 10 ]] && cat "${Folder}/${FileList[4]##*/}" "${Folder}/${FileList[-5]##*/}" > "${Folder}/${FileOutput}4-5.mp3" || continue

  # Assemblage du 6e et de .... dernier fichier s'il y a au moins 12 fichiers
  [[ ${#FileList[@]} -ge 12 ]] && cat "${Folder}/${FileList[5]##*/}" "${Folder}/${FileList[-6]##*/}" > "${Folder}/${FileOutput}5-6.mp3" || continue

ça me parait simplifiable. Un truc du style (à tester) :

i=0
while [ "$i" -lt "$((${#FileList[@]}/2))" ]
do
   j=$((${#FileList[@]}-i))
   cat "${Folder}/${FileList[i]}" "${Folder}/${FileList[j]}" > "${Folder}/${FileOutput}$i-$j.mp3"
   ((i++))
done

#5 Le 25/02/2017, à 17:42

Watael

Re : [Resolu] merge fichiers mp3 (2>1) de taille optimale moyenne

+1

ce n'est pas optimale les substitutions de commandes dans les assignations de tableaux.
c'est comme avec une boucle for, à un moment ça ne fonctionnera pas.

#!/bin/bash 

shopt -s globstar nullglob

for d in ./**/
do
# création du tableau
    for f in "$d"*.mp3; do test -f "$f" && ar+=( "$(stat -c'%s %n' "$f")" ); done
# tri à bulle
    for ((i=0;i<${#ar[*]}-1;i++))
    do  
        if test ${ar[i]%% *} -lt ${ar[i+1]%% *}
        then
           tmp=${ar[i+1]}
           ar[i+1]=${ar[i]}
           ar[$i]=$tmp
           i=-1
        fi  
    done
# "appairage"
    for ((i=${#ar[*]};i>1;i--))
    do  
        fMax="${ar[0]#* }"
        fMin="${ar[@]: -1}"
        fMin="${fMin#* }"
        # je vous laisse faire la concaténation, qui seule peut ne pas suffire pour faire propre, je passerais un coup de ffmpeg par-dessus
        echo "$fMax -|- $fMin"
        unset "ar[0]" "ar[${#ar[*]}-1]"
        ar=( "${ar[@]}" )
        ((i--))
    done
# on supprime le tableau
    unset ar
done

ça a l'air de fonctionner...
à  tester en conditions "réelles".


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#6 Le 25/02/2017, à 18:11

thurston

Re : [Resolu] merge fichiers mp3 (2>1) de taille optimale moyenne

Merci à tous, je regarde tout ca.
Avec mes petits moyens, j'avais pondu ca...horrible comme script, mais avait l'air de fonctionner...
Bien sur complement non optimisé. Je vais tenté de comprendre les scripts plus pro.
merci à tous
A+
T

#!/bin/bash
#

# variable check
if [ $# -ne 1 ]; then
   echo "Usage: $0 <Scan Dir>"
   echo "Usage: $0 -h > Help"
   exit 1
fi

# Use of script given variable
SCAN_DIR="$1"

function mergesongs()
{
   find "$SCAN_DIR" -type d | while read DIRECTORY
   do
      echo "$DIRECTORY"
      ls "$DIRECTORY" -Sr | egrep '\.mp3$' > /var/tmp/listmp3
      while [[ $(wc -l </var/tmp/listmp3) -ge 2 ]]
         do
         minsizefile=`head -1 /var/tmp/listmp3`;
         maxsizefile=`tail -1 /var/tmp/listmp3`
         minsizefilenamewithoutextension=${minsizefile%.*}

         cat "$DIRECTORY/$minsizefile" "$DIRECTORY/$maxsizefile" > "$DIRECTORY/$minsizefilenamewithoutextension-$maxsizefile"

         rm "$DIRECTORY/$minsizefile";
         rm "$DIRECTORY/$maxsizefile"
         sed -i '1d' /var/tmp/listmp3;
         sed -i '$ d' /var/tmp/listmp3
      done
   done
}

mergesongs

Dernière modification par thurston (Le 25/02/2017, à 18:23)

Hors ligne

#7 Le 26/02/2017, à 21:37

thurston

Re : [Resolu] merge fichiers mp3 (2>1) de taille optimale moyenne

ok, merci à tous, j'ai compris que la solution de Watael me paraissait proche de ma solution avec un fichier txt temporaire (sous la forme d'un tableau). Anonyme68, c'est ultra optimisé (surement très efficace), mais trop difficile d'accès pour ma part. Merci quand meme.
Vos inputs m'ont permis d'y voir plus clair, je clos le sujet.
A bientot
T

Hors ligne

#8 Le 11/03/2017, à 23:42

thurston

Re : [Resolu] merge fichiers mp3 (2>1) de taille optimale moyenne

Du coup, j'indique ici un script un peu plus complet, qui, quand il peut merge 3 chansons, et souvent 2 ou pas du tout si celle ci est déjà trop longue.
c'est un peu alambiqué, car ca n'optimise pas le taux de réussite du merging. (je veux dire, ca ne choisit pas les bons trio pour toujours approcher une durée définie. Je voulais avoir 2 morceaux, voire 3 quand c'était possible mais pas à tout prix. Donc la technique de trier par taille et de ne considérer dans un premier temps que les extremes me convient. Ci l'on peut y rajouter un 3eme morceau, on le fait (chanson "triolet" résultat pas trop long), sinon on s'abstient. Si j'avais "choisi" les triolets optimums, j'en aurais eu bien plus, mais trois chansons d'affilée du meme auteur, ca fait trop si trop répétitif.

Ci dessous

#!/bin/bash
#

# variable check
if [ $# -ne 1 ]; then
   echo "Usage: $0 <Scan Dir>"
   echo "Usage: $0 -h > Help"
   exit 1
fi

# Use of script given variable
SCAN_DIR="$1"

function mergesongs()
{

   find "$SCAN_DIR" -type d | while read DIRECTORY
   do
      echo "$DIRECTORY"
      ls "$DIRECTORY" -Sr | egrep '\.mp3$' > /var/tmp/listmp3
      while [[ $(wc -l </var/tmp/listmp3) -ge 2 ]]
         do
         MinSizeFile=`head -1 /var/tmp/listmp3`;
         MaxSizeFile=`tail -1 /var/tmp/listmp3`
         SizeOfMinSizeFile=$(wc -c <"$DIRECTORY/$MinSizeFile");
         SizeOfMaxSizeFile=$(wc -c <"$DIRECTORY/$MaxSizeFile");

         if [ $(( $SizeOfMinSizeFile+$SizeOfMaxSizeFile )) -gt $(( $TwoMergedSongsMaxSizeInBits )) ]
         then
            sed -i '$ d' /var/tmp/listmp3
         else
            sed -i '1d' /var/tmp/listmp3;
            sed -i '$ d' /var/tmp/listmp3;
            NextMinSizeFile=`head -1 /var/tmp/listmp3`;
            
            if [ "$NextMinSizeFile" = "" ]
            then
               if [ $(( $SizeOfMinSizeFile+$SizeOfMaxSizeFile )) -lt $(( $TwoMergedSongsMaxSizeInBits )) ]
               then                    
                  MinSizeFileNameWithoutExtension=${MinSizeFile%.*};
                  cat "$DIRECTORY/$MinSizeFile" "$DIRECTORY/$MaxSizeFile" > "$DIRECTORY/$MinSizeFileNameWithoutExtension-$MaxSizeFile";
                  rm "$DIRECTORY/$MinSizeFile";
                  rm "$DIRECTORY/$MaxSizeFile";
               fi
            else
               SizeOfNextMinSizeFile=$(wc -c <"$DIRECTORY/$NextMinSizeFile");
               if [ $(( $SizeOfMinSizeFile+$SizeOfMaxSizeFile+$SizeOfNextMinSizeFile )) -lt $ThreeMergedSongsMaxSizeInBits ]
               then
                  MinSizeFileNameWithoutExtension=${MinSizeFile%.*};
                  MaxSizeFileNameWithoutExtension=${MaxSizeFile%.*};
                  cat "$DIRECTORY/$MinSizeFile" "$DIRECTORY/$MaxSizeFile" "$DIRECTORY/$NextMinSizeFile"> "$DIRECTORY/$MinSizeFileNameWithoutExtension-$MaxSizeFileNameWithoutExtension-$NextMinSizeFile";
                  sed -i '1d' /var/tmp/listmp3;
                  rm "$DIRECTORY/$MinSizeFile";
                  rm "$DIRECTORY/$MaxSizeFile";
                  rm "$DIRECTORY/$NextMinSizeFile";
               else
                  if [ $(( $SizeOfMinSizeFile+$SizeOfMaxSizeFile )) -lt $TwoMergedSongsMaxSizeInBits ]
                  then                    
                     MinSizeFileNameWithoutExtension=${MinSizeFile%.*};
                     cat "$DIRECTORY/$MinSizeFile" "$DIRECTORY/$MaxSizeFile" > "$DIRECTORY/$MinSizeFileNameWithoutExtension-$MaxSizeFile";
                     rm "$DIRECTORY/$MinSizeFile";
                     rm "$DIRECTORY/$MaxSizeFile";
                  fi
               fi
            fi
         fi
      done
   done
}

bitrate=192
TwoMergedSongsMaxDurationInMin=10
ThreeMergedSongsMaxDurationInMin=10
TwoMergedSongsMaxSizeInBits=$(( $bitrate*1024/8*$TwoMergedSongsMaxDurationInMin*60 ))
ThreeMergedSongsMaxSizeInBits=$(( $bitrate*1024/8*$ThreeMergedSongsMaxDurationInMin*60 ))
mergesongs

Dernière modification par thurston (Le 11/03/2017, à 23:46)

Hors ligne