lame
hoàn toàn phù hợp với nhiệm vụ này, nhưng tôi sẽ sử dụng ffmpeg
và ffprobe
cho câu trả lời này, vì tôi biết chúng giống như mu bàn tay của tôi và bởi vì chúng có thể được khái quát hóa nhiều hơn là chỉ MP3. Đầu tiên:
sudo apt-get install ffmpeg
Không có công cụ nào tôi biết có thể đọc các tệp phương tiện và sau đó ghi đè lên đầu vào ngay lập tức: bạn cần sử dụng một tệp trung gian. Đối với một tệp duy nhất, bạn có thể làm:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3
mv temp.mp3 file.mp3
Bạn có thể kết hợp những thứ này thành một dòng duy nhất:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3 && mv temp.mp3 file.mp3
điều &&
đó có nghĩa là mv
lệnh sẽ không được thực thi trừ khi ffmpeg
thoát với trạng thái 0 (có nghĩa là thành công).
Để kiểm tra xem bit có tốc độ bit nào, bạn có thể sử dụng ffprobe
:
ffprobe -show_streams -select_streams a:0 -v quiet file.mp3 | grep -F 'bit_rate=320000'
-show_streams
nói ffprobe
để hiển thị thông tin về các luồng riêng lẻ; -select_streams
nói với nó mà những người thân để lựa chọn, và a:0
có nghĩa là 'dòng suối âm thanh đầu tiên (điều này rất quan trọng cho các file nhạc MP3 trong trường hợp bìa, mà được lưu giữ như một dòng video). Các ống ( |
) lấy đầu ra tiêu chuẩn của ffprobe
và cung cấp cho nó grep
. grep
sẽ chỉ in những dòng phù hợp với một mẫu nhất định - trong trường hợp này, các dòng có chứa chuỗi bit_rate=320000
. Nếu bạn chạy nó trên MP3 320k kbps, bạn sẽ nhận được một dòng như thế này:
bit_rate=32000
Nếu bạn chạy nó trên bất cứ thứ gì có tốc độ bit khác nhau, bạn sẽ không nhận được bất kỳ đầu ra nào cả; grep sẽ không thực hiện khớp và sẽ thoát với trạng thái là 1. Điều này có nghĩa là bạn có thể xâu chuỗi lệnh đó bằng lệnh 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
Hoặc, dễ đọc hơn một chút:
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
Điều đó sẽ chỉ hoạt động trên MP3 320 kbps. Hãy thử nó với một vài tập tin thử nghiệm.
Bước tiếp theo là làm cho nó hoạt động với nhiều tệp. Có hai cách tiêu chuẩn để làm điều này: for
vòng lặp và find
lệnh. Sau đây sẽ hành động trên mỗi MP3 trong một thư mục:
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
Điều này sẽ không đi vào thư mục con; Để làm như vậy, bạn phải đặt globstar
tùy chọn 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
Với 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"' '{}' \;
Tất cả những thứ này sẽ chạy một cách nghiêm ngặt theo tuần tự - chúng sẽ chỉ chuyển đổi một tệp tại một thời điểm. Bộ xử lý của bạn gần như chắc chắn có khả năng nhiều hơn thế, mặc dù; để tăng tốc mọi thứ, bạn có thể sử dụng 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
Hoặc là:
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 {}'