พบกระทู้นี้ในขณะที่พยายามทำการเข้ารหัส MP3 โดยตรงจากไฟล์ต้นฉบับ FLAC คำตอบของ Boehjให้ตัวเลือกการเขียนสคริปต์ที่ดี แต่ฉันชอบใช้ FFmpeg เป็นการส่วนตัวดังนั้นนี่คือสคริปต์ Bash ที่ฉันใช้เพื่อจัดการงานนี้ ผ่านการทดสอบและใช้งานได้ดีใน macOS Sierra (10.12.2)
สิ่งที่ต้องทำ:คุณควรติดตั้งffmpeg
และlame
ติดตั้งบน Mac แล้ว วิธีที่ง่ายที่สุดในการทำเช่นนี้คือผ่าน Homebrew ก่อนอื่นตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง Homebrew ดังนี้:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
จากนั้นรันคำสั่งนี้เพื่อติดตั้งffmpeg
และlame
:
brew install ffmpeg lame
เมื่อเสร็จแล้วคุณก็พร้อมที่จะเรียกใช้สคริปต์นี้ สคริปต์นี้จะค้นหาไฟล์ FLAC ในไดเรกทอรีpath/to/FLAC/files
แต่สามารถเปลี่ยนเป็น.
หากไฟล์ FLAC อยู่ในไดเรกทอรีเดียวกับที่คุณใช้งานสคริปต์นี้เมื่อทำงานมันจะสร้างmp3/
ไดเรกทอรีย่อยที่ไฟล์ MP3 ทั้งหมดจะเป็น วางไว้
find -E "path/to/FLAC/files" -type f -iregex ".*\.(FLAC)$" |\
while read full_audio_filepath
do
# Break up the full audio filepath stuff into different directory and filename components.
audio_dirname=$(dirname "${full_audio_filepath}");
audio_basename=$(basename "${full_audio_filepath}");
audio_filename="${audio_basename%.*}";
# audio_extension="${audio_basename##*.}";
# Set the MP3
mp3_dirpath="${audio_dirname}/mp3";
mp3_filepath="${mp3_dirpath}/${audio_filename}.mp3";
# Create the child MP3 directory.
mkdir -p "${mp3_dirpath}";
# Get the track metadata.
mp3_title=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:TITLE= | cut -d '=' -f 2- );
mp3_artist=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:ARTIST= | cut -d '=' -f 2- );
mp3_album=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:ALBUM= | cut -d '=' -f 2- );
mp3_year=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:YEAR= | cut -d '=' -f 2- );
mp3_track=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:TRACK= | cut -d '=' -f 2- | sed 's/^0*//' );
mp3_tracktotal=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:TRACKTOTAL= | cut -d '=' -f 2- | sed 's/^0*//' );
mp3_genre=$(ffprobe 2> /dev/null -show_format "${full_audio_filepath}" | grep -i TAG:GENRE= | cut -d '=' -f 2- );
# Where the magic happens.
ffmpeg -y -v quiet -nostdin -i "${full_audio_filepath}" -ar 44100 -sample_fmt s16 -ac 2 -f s16le -acodec pcm_s16le - | \
lame --quiet --add-id3v2 --pad-id3v2 --tt "${mp3_title}" --ta "${mp3_artist}" --tl "${mp3_album}" --tn "${mp3_track}"/"${mp3_tracktotal}" --tg "${mp3_genre}" -r -m s --lowpass 19.7 -V 3 --vbr-new -q 0 -b 96 --scale 0.99 --athaa-sensitivity 1 - "${mp3_filepath}";
done
บันทึกบางประการเกี่ยวกับสิ่งที่ฉันเรียนรู้“ The Hard Way ™” เพื่อให้ผู้อื่นได้รับจากสิ่งที่ฉันทำแตกต่างกันในบทนี้เมื่อเทียบกับคนอื่น ๆ บนอินเทอร์เน็ต
grep
คำสั่งสำหรับแท็กแยก (ใช้FFprobeซึ่งมีการติดตั้ง FFmpeg) เป็นกรณีตายโดยใช้ตัวเลือกที่จะทำให้มัน-i
grep -i
- ต่อไปนี้
cut
คำสั่ง จำกัด ในขณะนี้จะแบ่งการส่งออกเพียงขึ้นอยู่กับครั้งแรก=
ในชื่อแท็กที่มีตัวเลือกซึ่งจะทำให้คำสั่ง-f 2-
cut -d '=' -f 2-
ตัวอย่างเช่นทางเท้ามีเพลงชื่อ“ 5-4 = Unity” และหากเลือกเฉพาะก้อนที่สองผ่านการตัดชื่อนั้นจะถูกตัดเป็น“ 5-4”
- สำหรับการติดตามตัวเลขการติดตามและรวมผมเพิ่มท่อพิเศษในการที่ได้รับการกำจัดของศูนย์ชั้นนำ:
sed
sed 's/^0*//'
- ในสคริปต์ที่คล้ายกันในอินเทอร์เน็ตเอาต์พุต FFmpeg นั้นคล้ายกับ
-f wav
และที่จริงแล้วจะบีบอัดเอาต์พุต FFmpeg ซึ่งไม่สมเหตุสมผลในการตั้งค่าไพพ์ที่ LAME กำลังเข้ารหัสอีกครั้ง แทนที่จะตั้งค่าเอาท์พุทที่นี่-f s16le -acodec pcm_s16le
ซึ่งโดยทั่วไปคือเอาท์พุท RAW; สมบูรณ์แบบสำหรับการวางระบบเสียงให้กับกระบวนการอื่นเช่นนี้
- เพื่อจัดการกับเอาต์พุต RAW ที่ด้าน LAME ของไปป์ฉันต้องเพิ่ม
-r
ตัวเลือก
- นอกจากนี้ยังทราบ
--tt
, --ta
, --tl
, --tn
และ--tg
ตัวเลือกแท็ก ID3v2 สำหรับกะพร่องกะแพร่ง เมื่อเสียงถูกสตรีม / ไพพ์จากกระบวนการหนึ่งไปยัง LAME เมทาดาทาจากไฟล์ต้นฉบับจะหายไป ตัวเลือกปัญหาหนึ่งคือการได้รับ FFmpeg เพื่อบันทึกข้อมูลเมตาไปยังแฟ้มข้อความโดยการตั้งค่าตัวเลือกที่มี-f ffmetadata "[metadata filename here]"
แล้ววิ่ง FFmpeg -i "[metadata filename here]" -map_metadata 1 -c:a copy [destination mp3 file] id3v2_version 3 -write_id3v1 1
อีกครั้งกับบางสิ่งบางอย่างเช่นนี้: ใช้งานได้ แต่จดบันทึกข้อกำหนดสำหรับไฟล์ปลายทาง ดูเหมือนว่า FFmpeg จะนำเข้าข้อมูลเมตาเท่านั้นเมื่อสามารถคัดลอกไฟล์ซึ่งดูเหมือนว่าเป็นกระบวนการที่สิ้นเปลืองมาก ใช้ FFprobe ที่จะได้รับค่านิยมและการตั้งค่าจากนั้นพวกเขาในกะพร่องกะแพร่งกับ--tt
, --ta
, --tl
, --tn
และ--tg
ตัวเลือกการทำงานได้ดีขึ้น; ข้อมูลเมตาทั้งหมดเขียนขึ้นเพื่อให้ไฟล์ที่ซ้ำกันต้องถูกสร้างขึ้น