ターミナルのみを使用して、LAMEおよびFLACを使用して.flacから.mp3に移動するにはどうすればよいですか?


31

長い間、私はLAMEプラグインでAudacityを使用する比較的不格好なテクニックを使用してきました。これは問題ないと思いますが、Terminalアプローチの魅力は、少し細かく[options]なり、おそらくより最新のバイナリを使用できることです。

さらに、私のMacBookは少し老朽化しており、不必要なGUIを取り除くことができれば、なお良い。

前もって感謝します。


1
実際にそれを行うとポイントが得られます;)
モーティマー

ハハ...質問に答えましたが、2日間答えを確認できないと言っています。ごめんなさい。ここで物事がどのように機能するかをまだ理解しています。素晴らしいサイト。: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ます。

これにより、Musicフォルダ内のすべてのflacファイルが変換されます。

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

または、flac2mp3を1回だけ呼び出すため、わずかに高速です。

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

2
質問のテキストへの参照ではなく、ここに回答を投稿してください。私見、質問と回答の両方を編集し、結論をここに移動する必要があります。
lpacheco

OK ごめんなさい。
boehj

2
${file%.flac}.mp3すごい!以前${x:: ${#x}-3}m4aは、曲のファイル名を.wavから.m4aに変更するために使用していました。かなり簡単に見える方法を見るのは素晴らしい。
ジェイソンサラズ

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

また、この「検索」機能を実行するスクリプトを作成すると便利です
...-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ファインダーはカバーアートを示しています。brewのffmpeg 3.4.2。
ハビー

その後、ffmpegが非常に古いことに気付きました。私はそれを4.1.3にアップグレードしましたが、同じ結果で、同じサイズのmp3ファイルで、カバーアートが機能します。
ハビー

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

また、CPUをより効果的に使用していることがわかります。インテルi7を持っているので、おそらく8が適切なプロセス数です。


2

FLACソースファイルからMP3を直接エンコードしようとしたときに、このスレッドが見つかりました。Boehjの答えはまともなスクリプトオプションを提供しますが、個人的にはFFmpegを使用することを好むため、これがこのタスクを処理するために思いついたBashスクリプトです。macOS Sierra(10.12.2)でテスト済みであり、正常に動作します。

前提条件 Macにインストール済みである必要がffmpegありlameます。これを行う最も簡単な方法は、Homebrewを使用することです。まず、次のようにHomebrewがインストールされていることを確認してください。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

次に、このコマンドを実行してインストールffmpegしてlameください:

brew install ffmpeg lame

これが完了すると、このスクリプトを実行する準備が整います。このスクリプトは、ディレクトリ内でFLACファイルを探しますが、FLACファイルがこのスクリプトを実行しているのと同じディレクトリにpath/to/FLAC/filesある.場合に変更できます。実行すると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タグ解析のコマンド(FFmpegとともにインストールされるFFprobeを使用)は、-iオプションを使用して大文字と小文字を区別しませんgrep -i
  • 次のcutコマンドは、コマンドを作成するオプションで=タグ名の最初に基づいてのみ出力を分割するように制限されてい-f 2-ますcut -d '=' -f 2-。たとえば、Pavementには「5-4 = Unity」というタイトルの曲があり、カットで2番目のチャンクのみが選択された場合、そのタイトルは「5-4」に切り捨てられます。
  • トラック番号と合計トラック番号sedについて、先行ゼロを取り除くためのパイプを追加しましたsed 's/^0*//'
  • インターネット上の同様のスクリプトでは、FFmpeg出力は次のようなもので-f wavあり、実際にはFFmpeg出力を圧縮するため、LAMEが再エンコードするパイプのセットアップでは意味がありません。代わりに、ここの出力-f s16le -acodec pcm_s16leは基本的にRAW出力に設定されます。このような別のプロセスにオーディオをパイプするのに最適です。
  • パイプのLAME側のRAW出力を処理するには、-rオプションを追加する必要がありました。
  • 注意してください--tt--ta--tl--tn--tgLAMEのためのID3v2タグのオプションを。オーディオが1つのプロセスからLAMEにストリーミング/パイピングされると、ソースファイルのメタデータは失われます。推奨されるオプションの1つは、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は、ファイルをコピーできる場合にのみメタデータをインポートするようです。これは非常に無駄なプロセスのようです。値を取得し、その後でLAMEでそれらを設定するFFprobeを使用して--tt--ta--tl--tnおよび--tgオプションは、良い作品。すべてのメタデータが所定の場所に書き込まれるため、複製ファイルを生成する必要があります。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.