#1 Le 24/02/2017, à 19: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, à 20:39)
Hors ligne
#2 Le 25/02/2017, à 10: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, à 11:04)
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#3 Le 25/02/2017, à 14: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, à 16: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, à 16: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, à 17: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, à 17:23)
Hors ligne
#7 Le 26/02/2017, à 20: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, à 22: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, à 22:46)
Hors ligne