web-dev-qa-db-ja.com

シェルスクリプトを使用してmp4をmp3に変換する

mp4からmp3への変換 で、ffmpegというツールを使用しています。変換するファイルが1つしかない場合、このプロセスは素晴らしいですが、特定のディレクトリでmp4からmp3への変換を自動化しようとしています。

例として、すべてのサブディレクトリを含む以下のディレクトリ、つまりMusicVideos`を指定します。

.
├── Andra
│   └── Andra::Why.mp4
├── Ariana Grande
│   └── Dangerous Woman
│       ├── ArianaGrande::IntoYou.mp4
│       └── ArianaGrande::SideToSide.mp4
├── Justin Bieber
│   └── JustinBieber::LetMeLoveYou.mp4
├── Major Lazer
│   └── De Maxx 37
│       └── MajorLazer::ColdWater.mp4
├── Martin Garrix & Bebe Rexha
│   └── MartinGarrix&BebeRevha::InTheNameOfLove.mp4
├── Shawn Mendes
│   └── ShawnMendes::TreatYouBetter.mp4
├── Sia
│   └── The Greatest
│       └── Sia::TheGreatest.mp4
├── The Chainsmokers
│   ├── TheChainsmokers::AllWeKnow.mp4
│   └── TheChainsmokers::Closer.mp4
├── The Weekend
│   └── Starboy
│       └── TheWeekend::DaftPunk.mp4
└── TWENTY ØNE PILØTS
    └── Suicide Squad
        └── TwentyOnePilots::Heathens.mp4

スクリプトの実行後、出力ディレクトリはMusicAudioのようになります。

.
├── Andra
│   └── Andra::Why.mp3
├── Ariana Grande
│   └── Dangerous Woman
│       ├── ArianaGrande::IntoYou.mp3
│       └── ArianaGrande::SideToSide.mp3
├── Justin Bieber
│   └── JustinBieber::LetMeLoveYou.mp3
├── Major Lazer
│   └── De Maxx 37
│       └── MajorLazer::ColdWater.mp3
├── Martin Garrix & Bebe Rexha
│   └── MartinGarrix&BebeRevha::InTheNameOfLove.mp3
├── Shawn Mendes
│   └── ShawnMendes::TreatYouBetter.mp3
├── Sia
│   └── The Greatest
│       └── Sia::TheGreatest.mp3
├── The Chainsmokers
│   ├── TheChainsmokers::AllWeKnow.mp3
│   └── TheChainsmokers::Closer.mp3
├── The Weekend
│   └── Starboy
│       └── TheWeekend::DaftPunk.mp3
└── TWENTY ØNE PILØTS
    └── Suicide Squad
        └── TwentyOnePilots::Heathens.mp3

Bashスクリプトを使用してこの変換を行う方法を探していたところ、 スクリプト:wmaファイルを再帰的にMP3に変換してから、WMAファイルを削除する に出会いました。

これは私が予想していたよりも少し難しいようです。どんな助けやガイダンスも大歓迎です。

更新

いくつかの助けを借りて、スクリプトを作成しました:これが機能することを確認してください!

cp -a /$1/. /$2/  #copy the whole dir from src to dest

#cd $2 #change dir to dest
cd $2
#convert *.mp4 to *.mp3
#find . -name "*.mp4" -exec bash -c 'var=${1%.mp4}; var=${var#*/};ffmpeg -i "${1#*/}" -vn -acodec libmp3lame -ac 2 -qscale:a 4 -ar 48000 "$dest/$var".mp3' - '{}' \;

find . -name "*.mp4" -exec bash -c 'ffmpeg -i "$1" -vn -acodec libmp3lame -ac 2 -qscale:a 4 -ar 48000 "${1%.mp4}".mp3' - '{}' \;

echo "Cleaning up" 
find . -name "*.mp4" -exec bash -c 'var=${1%.mp4}; var=${var#*/}; rm "${1#*/}"' - '{}' \;

ソースコードは、私の GitHub にあります。それ以上の貢献は大歓迎です。

6
Amir

最初に、新しい最上位ディレクトリにディレクトリ構造を複製する必要があります。 .mp4ファイルを含む元のトップディレクトリ内でfind . -type d >dirs.txtを実行します。これにより、すべてのディレクトリとそのパスがdirs.txtに保存されます。次に、ディレクトリを新しいトップディレクトリに変更し、xargs mkdir -p <dirs.txtを実行します。これにより、元のディレクトリと同じディレクトリ構造が作成されます。

形式を変更してファイルを別のディレクトリに保存するには、元のトップディレクトリ内で次のコマンドを実行します。

find . -name "*.mp4" -exec bash -c 'var=${1%.mp4}; var=${var#*/};ffmpeg -i "${1#*/}" -vn -acodec libmp3lame -ac 2 -qscale:a 4 -ar 48000 "~/PATH/to/NewTopDIr/$var".mp3' - '{}' \;

説明

find . -name "*.mp4"は、.mp4タイプのすべてのファイルを検索します。 -exec bash -cは、見つかった各ファイルの後続の文字列で提供されるbashコマンドを実行します。また、bashコマンドで使用できる変数$1としてファイル名を渡します。

この時点で、$1には./path/file.mp4のようなものが含まれています。ファイルタイプ*.mp4を削除するには、var=${1%.mp4}./path/fileに保存する$varを使用します。ここで、前の./var=${var#*/}とともに削除します。したがって、$varの値はpath/fileです。

ffmpegコマンドでは、path/file.mp4を与える${var#*/}で現在のファイル名を取得し、~/PATH/to/NewTopDIr/$var".mp3で出力ファイルを取得します。ここで、$varpath/file上で説明したとおり。

9
Bilal Baqar