lame
è perfettamente adatto a questo compito, ma ho intenzione di usare ffmpeg
e ffprobe
per questa risposta, perché li conosco come il palmo della mia mano e perché possono essere generalizzati a più di un semplice MP3. Prima di tutto:
sudo apt-get install ffmpeg
Non sono a conoscenza di alcuno strumento in grado di leggere file multimediali e sovrascrivere immediatamente l'input: è necessario utilizzare un file intermedio. Per un singolo file, puoi fare:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3
mv temp.mp3 file.mp3
Puoi combinarli in un'unica riga:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3 && mv temp.mp3 file.mp3
l' &&
lì significa che il mv
comando non sarà eseguito a meno che ffmpeg
esce con stato 0 (che significa successo).
Per verificare la velocità in bit di un file, è possibile utilizzare ffprobe
:
ffprobe -show_streams -select_streams a:0 -v quiet file.mp3 | grep -F 'bit_rate=320000'
-show_streams
dice ffprobe
di mostrare informazioni sui singoli flussi; -select_streams
indica quali selezionare e a:0
indica "il primo flusso audio (questo è importante per i file MP3 nel caso della copertina, che viene archiviato come flusso video). Il pipe ( |
) prende l'output standard di ffprobe
e lo alimenta grep
. grep
stamperà solo quelle linee che corrispondono a un determinato motivo - in questo caso, le linee che contengono la stringa bit_rate=320000
. Se lo esegui su un MP3 da 320k kbps, otterrai una linea come questa:
bit_rate=32000
Se lo esegui su qualcosa con un bit rate diverso, non otterrai alcun output; grep non riuscirà a trovare una corrispondenza e uscirà con uno stato di 1. Ciò significa che puoi concatenare quel comando con il comando ffmpeg:
ffprobe -show_streams -select_streams a:0 -v quiet file.mp3 | grep -F 'bit_rate=320000' && ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3 && mv temp.mp3 file.mp3
O, un po 'più facilmente:
ffprobe -show_streams -select_streams a:0 -v quiet file.mp3 | grep -F 'bit_rate=320000' &&
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3 &&
mv temp.mp3 file.mp3
Funzionerà solo su MP3 da 320 kbps. Provalo con un paio di file di test.
Il prossimo passo è farlo funzionare con più file. Esistono due modi standard per farlo: un for
ciclo e il find
comando. Quanto segue agirà su ogni MP3 in una directory:
for f in *.mp3; do
ffprobe -show_streams -select_streams a:0 "$f" | grep -F 'bit_rate=320000' &&
ffmpeg -y -i "$f" -c:a libmp3lame -b:a 192k /tmp/temp.mp3 && mv /tmp/temp.mp3 "$f"
done
Questo non andrà nelle sottodirectory; per fare ciò, devi impostare l' globstar
opzione shell:
shopt -s globstar
for f in **/*.mp3; do
ffprobe -show_streams -select_streams a:0 "$f" | grep -F 'bit_rate=320000' &&
ffmpeg -y -i "$f" -c:a libmp3lame -b:a 192k /tmp/temp.mp3 && mv /tmp/temp.mp3 "$f"
done
Con find
:
find . -name '*.mp3' -exec sh -c 'ffprobe -show_streams -select_streams a:0 "$0" | grep -F "bit_rate=320000" &&
ffmpeg -y -i "$0" -c:a libmp3lame -b:a 192k /tmp/temp.mp3 && mv /tmp/temp.mp3 "$0"' '{}' \;
Tutti questi eseguiranno rigorosamente in sequenza: convertiranno solo un file alla volta. Il tuo processore è quasi sicuramente in grado di fare molto di più, però; per velocizzare le cose, potresti usare GNU parallel
:
sudo apt-get install parallel
shopt -s globstar
parallel 'ffprobe -show_streams -select_streams a:0 {} | grep -F "bit_rate=320000" &&
ffmpeg -y -i {} -c:a libmp3lame -b:a 192k {.}.temp.mp3 && mv {.}.temp.mp3 {}' ::: **/*.mp3
O:
find . -name '*.mp3' | parallel 'ffprobe -show_streams -select_streams a:0 {} | grep -F "bit_rate=320000" &&
ffmpeg -y -i {} -c:a libmp3lame -b:a 192k {.}.temp.mp3 && mv {.}.temp.mp3 {}'