lame
sangat cocok untuk tugas ini, tetapi saya akan menggunakan ffmpeg
dan ffprobe
untuk jawaban ini, karena saya tahu mereka menyukai bagian belakang tangan saya dan karena mereka dapat digeneralisasikan ke lebih dari sekedar MP3. Pertama-tama:
sudo apt-get install ffmpeg
Tidak ada alat yang saya ketahui yang dapat membaca file media dan kemudian langsung menulis input: Anda perlu menggunakan file perantara. Untuk satu file, Anda dapat melakukan:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3
mv temp.mp3 file.mp3
Anda dapat menggabungkan ini menjadi satu baris:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3 && mv temp.mp3 file.mp3
di &&
sana berarti bahwa mv
perintah tidak akan dieksekusi kecuali ffmpeg
keluar dengan status 0 (yang berarti sukses).
Untuk memeriksa berapa bit rate sebuah file, Anda dapat menggunakan ffprobe
:
ffprobe -show_streams -select_streams a:0 -v quiet file.mp3 | grep -F 'bit_rate=320000'
-show_streams
memberitahu ffprobe
untuk menunjukkan informasi tentang aliran individu; -select_streams
memberi tahu yang mana yang harus dipilih, dan a:0
berarti 'aliran audio pertama (ini penting untuk file MP3 dalam kasus sampul, yang disimpan sebagai aliran video). Pipa ( |
) mengambil output standar ffprobe
dan mengumpankannya ke grep
. grep
hanya akan mencetak garis-garis yang cocok dengan pola yang diberikan - dalam hal ini, garis yang berisi string bit_rate=320000
. Jika Anda menjalankan ini pada MP3 320k kbps, Anda akan mendapatkan baris seperti ini:
bit_rate=32000
Jika Anda menjalankannya dengan bit rate berbeda, Anda tidak akan mendapatkan output sama sekali; grep akan gagal melakukan kecocokan, dan akan keluar dengan status 1. Ini berarti Anda dapat mengaitkan perintah itu dengan perintah 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
Atau, sedikit lebih mudah dibaca:
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
Itu hanya akan bekerja pada MP3 320 kbps. Cobalah dengan beberapa file uji.
Langkah selanjutnya adalah membuatnya bekerja dengan banyak file. Ada dua cara standar untuk melakukan ini: satu for
loop, dan find
perintah. Berikut ini akan bertindak pada setiap MP3 dalam direktori:
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
Ini tidak akan masuk ke subdirektori; untuk melakukannya, Anda harus mengatur globstar
opsi 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
Dengan 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"' '{}' \;
Semua ini akan berjalan sangat berurutan - mereka hanya akan mengkonversi satu file pada satu waktu. Prosesor Anda hampir pasti mampu melakukan lebih dari itu; untuk mempercepat, Anda bisa menggunakan 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
Atau:
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 {}'