ฉันจะเปลี่ยนจาก. flac เป็น. mp3 โดยใช้ LAME & FLAC โดยใช้ Terminal เพียงอย่างเดียวได้อย่างไร


31

เป็นเวลานานที่ฉันได้ใช้เทคนิคสัมพัทธ์ clunky ซึ่งเกี่ยวข้องกับความกล้าด้วยปลั๊กอินอ่อนแอ นี่เป็นสิ่งที่ดีฉันเดาได้ แต่ความดึงดูดใจของวิธีการเทอร์มินัลคือฉันสามารถปรับขนาดเม็ดเล็ก ๆ ของฉัน[options]และอาจใช้ไบนารีที่เป็นปัจจุบันมากขึ้น

นอกจากนี้ MacBook ของฉันกำลังแก่ลงเล็กน้อยในตอนนี้และถ้าฉันสามารถกำจัด GUI ที่ไม่จำเป็นออกไปได้ทั้งหมดก็จะดีขึ้น

ขอบคุณล่วงหน้า.


1
คุณจะได้รับคะแนนสำหรับการทำเช่นนั้นจริง ๆ )
Mortimer

ฮ่าฮ่า ... ฉันได้ตอบคำถามแล้ว แต่มันบอกว่าฉันไม่สามารถยืนยันคำตอบของฉันเป็นเวลาสองวัน ขอโทษ ยังคงหาวิธีที่สิ่งต่าง ๆ ทำงานที่นี่ เว็บไซต์ที่น่ากลัว : D
boehj

คำตอบ:


41

การแปลงไฟล์เดียวโดยไม่เก็บแท็ก

brew install lame
flac --decode --stdout test.flac | lame --preset extreme - test.mp3
  • --decode --stdout = -dc
  • lame - $outfile = อินพุตจาก STDIN
  • --preset extreme= ~ 245 kbit / s VBR

เชลล์สคริปต์ที่เก็บแท็ก ID3 ไว้บางส่วน

#!/bin/bash

for f in "$@"; do
    [[ "$f" != *.flac ]] && continue
    album="$(metaflac --show-tag=album "$f" | sed 's/[^=]*=//')"
    artist="$(metaflac --show-tag=artist "$f" | sed 's/[^=]*=//')"
    date="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
    title="$(metaflac --show-tag=title "$f" | sed 's/[^=]*=//')"
    year="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
    genre="$(metaflac --show-tag=genre "$f" | sed 's/[^=]*=//')"
    tracknumber="$(metaflac --show-tag=tracknumber "$f" | sed 's/[^=]*=//')"

    flac --decode --stdout "$f" | lame --preset extreme --add-id3v2 --tt "$title" --ta "$artist" --tl "$album" --ty "$year" --tn "$tracknumber" --tg "$genre" - "${f%.flac}.mp3"
done

หากต้องการใช้สคริปต์เพียงบันทึกไว้ที่ใดที่หนึ่ง~/bin/flac2mp3และทำให้สามารถใช้งานchmod +x ~/bin/flac2mp3ได้

สิ่งนี้จะแปลงไฟล์ flac ทั้งหมดในโฟลเดอร์ Music ของคุณ:

find ~/Music/ -name '*.flac' -exec ~/bin/flac2mp3 {} \;

หรือเร็วกว่าเล็กน้อยเนื่องจากมันจะเรียก flac2mp3 เพียงครั้งเดียว:

find ~/Music/ -name '*.flac' -print0 | xargs -0 ~/bin/flac2mp3

2
คุณควรโพสต์คำตอบที่นี่ไม่ใช่การอ้างอิงถึงข้อความในคำถาม IMHO คุณควรแก้ไขทั้งคำถามและคำตอบและย้ายไปสู่ข้อสรุปที่นี่
lpacheco

ตกลงจะทำ ขอโทษ
boehj

2
${file%.flac}.mp3มันยอดเยี่ยม! ก่อนหน้านี้ฉันใช้${x:: ${#x}-3}m4aเพื่อเปลี่ยนชื่อไฟล์ของเพลงจาก. wav เป็น. m4a ยอดเยี่ยมมากที่ได้เห็นวิธีที่ดูค่อนข้างง่ายขึ้น
Jason Salaz

1
ดูเหมือนว่าจะมีข้อผิดพลาดในตัวเลือก 3 อาจเป็นเพราะรุ่นอ่อนแอ แต่รหัสปัจจุบันไม่บอกว่าอ่อนแอควรใช้กระแสข้อมูลเป็นไฟล์อินพุตและไม่ได้ระบุไฟล์เอาท์พุทเนื่องจากมีการใช้กระแสมันเป็น จำเป็น สำหรับฉันรหัสสุดท้ายคือ: !/bin/sh file="$1" outfile=${file%.flac}.mp3 eval $(metaflac --export-tags-to - "$file" | sed "s/=\(.*\)/='\1'/") flac -cd "$file" | lame --preset standard \ --add-id3v2 --tt "$TITLE" --ta "$ARTIST" --tl "$ALBUM" \ --ty "$DATE" --tn "$TRACKNUMBER" --tg "$GENRE" \ - "$outfile"
Mehal

นอกจากนี้มันเป็นเรื่องดีที่จะสร้างสคริปต์ที่ไม่สิ่งนี้ 'พบ' a ...
Mehal

10

ffmpeg จะเก็บแท็ก (แต่ไม่ใช่หน้าปก) ตามค่าเริ่มต้น

for f in *.flac; do ffmpeg -i "$f" -aq 1 "${f%flac}mp3"; done

-aq 1สอดคล้องกับ-V 1ในง่อย -acodec libfaacจะแปลงไฟล์เป็น AAC:

for f in *.flac; do ffmpeg -i "$f" -acodec libfaac -aq 200 "${f%flac}m4a"; done

ฉันเพิ่งทำสิ่งนี้และมันได้กล่าวว่า: `` `ข้อมูลเมตา: ความคิดเห็น: ตัวเข้ารหัสปก (ด้านหน้า): Lavc57.107.100 png` '' ตัวค้นหา macOS แสดงภาพปก ffmpeg 3.4.2 จากการกลั่น
Habbie

จากนั้นฉันก็รู้ว่า ffmpeg ของฉันนั้นเก่ามาก ฉันอัปเกรดเป็น 4.1.3 ด้วยผลลัพธ์เดียวกัน - ไฟล์ mp3 ที่มีขนาดเท่ากันพร้อมหน้าปกที่ใช้งานได้
Habbie

4

ฉันเอาสิ่งที่พวกคุณมี แต่จากนั้นทำให้มันทำงานได้เร็วขึ้นโดยใช้xargsการขนานงาน

find <directory> -name '*.flac' -print0 | xargs -0 -P8 -n1  /usr/local/bin/flac2mp3

นี่คือสคริปต์จากด้านบน / usr / local / bin / flac2mp3

#!/usr/bin/env bash

for f in "$@"; do
  [[ "$f" != *.flac ]] && continue
  album="$(metaflac --show-tag=album "$f" | sed 's/[^=]*=//')"
  artist="$(metaflac --show-tag=artist "$f" | sed 's/[^=]*=//')"
  date="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
  title="$(metaflac --show-tag=title "$f" | sed 's/[^=]*=//')"
  year="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
  genre="$(metaflac --show-tag=genre "$f" | sed 's/[^=]*=//')"
  tracknumber="$(metaflac --show-tag=tracknumber "$f" | sed 's/[^=]*=//')"

  flac --decode --stdout "$f" \ 
         | lame --preset extreme \
                --add-id3v2 \
                 --tt "$title" \
                 --ta "$artist" \
                 --tl "$album" \
                 --ty "$year" \
                 --tn "$tracknumber" \
                 --tg "$genre" \
                 - "${f%.flac}.mp3"
done

และมีสถิติบางอย่างสำหรับการเร่งความเร็วประสิทธิภาพโดยใช้การขนาน

find <dirOfFlac24s> -name '*.flac -print0 | xargs -0 -P8 -n1 /usr/local/bin/flac2mp320  

0.00s user 0.00s system 60% cpu 0.002 total
115.94s user 1.40s system 359% cpu 32.655 total

time /usr/local/bin/flac2mp320 <dirOfFlac24s>/*.flac
96.63s user 1.46s system 109% cpu 1:29.98 total

คุณสามารถเห็นว่ามันใช้ซีพียูของฉันได้อย่างมีประสิทธิภาพมากขึ้นฉันมี intel i7 ดังนั้น 8 อาจเป็นกระบวนการที่เหมาะสม


2

พบกระทู้นี้ในขณะที่พยายามทำการเข้ารหัส 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) เป็นกรณีตายโดยใช้ตัวเลือกที่จะทำให้มัน-igrep -i
  • ต่อไปนี้cutคำสั่ง จำกัด ในขณะนี้จะแบ่งการส่งออกเพียงขึ้นอยู่กับครั้งแรก=ในชื่อแท็กที่มีตัวเลือกซึ่งจะทำให้คำสั่ง-f 2- cut -d '=' -f 2-ตัวอย่างเช่นทางเท้ามีเพลงชื่อ“ 5-4 = Unity” และหากเลือกเฉพาะก้อนที่สองผ่านการตัดชื่อนั้นจะถูกตัดเป็น“ 5-4”
  • สำหรับการติดตามตัวเลขการติดตามและรวมผมเพิ่มท่อพิเศษในการที่ได้รับการกำจัดของศูนย์ชั้นนำ:sedsed '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ตัวเลือกการทำงานได้ดีขึ้น; ข้อมูลเมตาทั้งหมดเขียนขึ้นเพื่อให้ไฟล์ที่ซ้ำกันต้องถูกสร้างขึ้น
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.