lame
เหมาะอย่างยิ่งกับงานนี้ แต่ฉันจะใช้ffmpeg
และffprobe
สำหรับคำตอบนี้เพราะฉันรู้ว่าพวกเขาชอบด้านหลังมือของฉันและเพราะพวกเขาสามารถพูดได้มากกว่า MP3 เพียงอย่างเดียว ก่อนอื่น:
sudo apt-get install ffmpeg
ไม่มีเครื่องมือที่ฉันรู้ว่าสามารถอ่านไฟล์สื่อแล้วเขียนทับอินพุตได้ทันที: คุณต้องใช้ไฟล์ระดับกลาง สำหรับไฟล์เดียวคุณสามารถทำได้:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3
mv temp.mp3 file.mp3
คุณสามารถรวมสิ่งเหล่านี้เป็นบรรทัดเดียว:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3 && mv temp.mp3 file.mp3
&&
มีหมายความว่าmv
คำสั่งจะไม่ถูกดำเนินการเว้นแต่ffmpeg
ทางออกที่มีสถานะเป็น 0 (ซึ่งหมายถึงความสำเร็จ)
ในการตรวจสอบว่าไฟล์มีอัตราบิตเท่าใดคุณสามารถใช้ffprobe
:
ffprobe -show_streams -select_streams a:0 -v quiet file.mp3 | grep -F 'bit_rate=320000'
-show_streams
บอกffprobe
ให้แสดงข้อมูลเกี่ยวกับสตรีมแต่ละรายการ -select_streams
บอกมันซึ่งคนที่จะเลือกและa:0
หมายถึง 'สตรีมเสียงครั้งแรก (ซึ่งเป็นสิ่งสำคัญสำหรับไฟล์ MP3 ในกรณีของปกซึ่งถูกเก็บไว้เป็นสตรีมวิดีโอ) ท่อ ( |
) ใช้เวลามาตรฐานการออกและฟีดมันffprobe
จะพิมพ์บรรทัดที่ตรงกับรูปแบบที่กำหนด - ในกรณีนี้เส้นที่มีสตริง หากคุณใช้งานกับ MP3 ขนาด 320k kbps คุณจะได้รับสายเช่นนี้:grep
grep
bit_rate=320000
bit_rate=32000
หากคุณใช้งานกับอะไรก็ตามที่มีอัตราบิตแตกต่างกันคุณจะไม่ได้ผลลัพธ์เลย grep จะไม่ทำการแข่งขันและจะออกจากสถานะ 1 ซึ่งหมายความว่าคุณสามารถโยงคำสั่งนั้นด้วยคำสั่ง 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
หรืออ่านง่ายขึ้นอีกเล็กน้อย:
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
ที่จะทำงานบน MP3 ขนาด 320 kbps เท่านั้น ลองใช้กับไฟล์ทดสอบสองสามไฟล์
ขั้นตอนต่อไปคือการทำให้ไฟล์หลายไฟล์ทำงานได้ มีสองวิธีมาตรฐานในการทำเช่นนี้: for
ห่วงและfind
คำสั่ง ต่อไปนี้จะทำงานกับทุก MP3 ในไดเรกทอรี:
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
สิ่งนี้จะไม่เข้าไปในไดเรกทอรีย่อย ในการทำเช่นนั้นคุณต้องตั้งค่าglobstar
ตัวเลือกเชลล์:
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
ด้วย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"' '{}' \;
ทั้งหมดเหล่านี้จะทำงานตามลำดับอย่างเคร่งครัด - พวกเขาจะแปลงทีละไฟล์เท่านั้น โปรเซสเซอร์ของคุณเกือบจะมีความสามารถมากกว่านั้น เพื่อให้เร็วขึ้นคุณสามารถใช้ 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
หรือ:
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 {}'