私のフォルダにmp3ファイルがたくさんあります。カセットテープで録音され、個々のトラックを取り外す必要がありました。これはファイル名の1つです。
Gobbolino the Witch's Cat, 10:52 The Hare & Tortoise, 14:52 The Shoe Tree, 24:22 The Emperors New Clothes, 34:11 The Red Nightcaps, 37:07 Aldo in Arcadia (1), 40:37 The Forest Troll.mp3
各トラックの先頭を示すファイル名にタイムスタンプがあることがわかります。最初のトラックは常に00:00から始まるので、タイムスタンプはありません。最後のトラックは常にmp3の最後になければなりません。どういうわけか別のファイルを作成するためにこれらのタイムスタンプを抽出したいと思います。
上記のファイルが正しく分割されると、出力は次のようになります。
Gobbolino the Witch's Cat.mp3
The Hare & Tortoise.mp3
The Shoe Tree.mp3
The Emperors New Clothes.mp3
The Red Nightcaps.mp3
Aldo in Arcadia (1).mp3
The Forest Troll.mp3
私はファイルを繰り返す方法とffmpegを使ってファイルを切り取る方法を知っていますが、ファイル名からタイムスタンプとトラック名を抽出する方法はわかりません。私はzshを使用しており、これが現在のコードです。
for file in *; do
if [[ -f "$file" ]]; then
# extract timestamps and loop thru, for each timestamped section
ffmpeg -ss TIMESTAMP_START -to TIMESTAMP_END -I "$file" -acodec copy TRACK_NAME.mp3
fi
done
修正する
この質問に対する私の基準が変わりました。ファイル名は次のとおりです。
Tape 1 - Gobbolino the Witch's Cat, 11-06 The Hare & Tortoise, 14-25 The Shoe Tree, 24-06 The Emperors New Clothes, 34-27 The Red Nightcaps, 37-29 Aldo in Arcadia (1), 40-40 The Forest Troll.mp3
つまり、最初にアルバム名があり、タイムスタンプにコロンの代わりにハイフンがあります(macOSではファイル名にコロンを含めることはできません)。また、いくつかのmp3タグをファイルに挿入し、各アルバムのトラックを独自のアルバムフォルダに入れたいと思います。
私の解決策は以下のGillesの1つに基づいています。スクリプトは次のとおりです。
setopt interactive_comments
for file in *(.); do
extension=$file:e
rest=$file:r
timestamp_start=0:00
timestamp_duration=$(ffprobe -i "$file" -show_entries format=duration -v quiet -of csv="p=0" -sexagesimal -sexagesimal)
timestamp_duration=${timestamp_duration%.*}
tracknum=1
while [[ $rest =~ ,\ *([0-9:]+-[0-9][0-9])\ * ]]; do
track_name="$rest[1,$MBEGIN-1]"
if [[ "$track_name" == *"Tape "* ]]; then
albumname="${track_name%% - *}"
track_name="${track_name#* - }"
echo "\n\nALBUM NAME $albumname\n"
mkdir $albumname
fi
rest=$rest[$MEND+1,-1]
timestamp_end=$match[1]
timestamp_end="${timestamp_end//-/:}"
# echo "$timestamp_start $timestamp_end $track_name.$extension"
ffmpeg -ss $timestamp_start -to $timestamp_end -i $file -acodec libmp3lame -ac 2 -ab 256k -ar 44100 -metadata album="$albumname" -metadata title="$track_name" -metadata track="$tracknum" $track_name.$extension
mv $track_name.$extension $albumname
timestamp_start=$timestamp_end
tracknum=$((tracknum+1))
last_track_name="$rest:r"
done
if [[ -n $timestamp_end ]]; then
# echo "$timestamp_start $timestamp_duration $last_track_name.$extension"
ffmpeg -ss $timestamp_start -to $timestamp_duration -i $file -acodec libmp3lame -ac 2 -ab 256k -ar 44100 -metadata album="$albumname" -metadata title="$last_track_name" -metadata track="$tracknum" $last_track_name.$extension
mv $last_track_name.$extension $albumname
fi
done
ベストアンサー1
トラック区切り文字と一致するように正規表現を使用してファイル名を繰り返します。=~
条件式演算子。正規表現は、,\ *([0-9:]+:[0-9][0-9])\ *
カンマとその後にオプションで周囲のスペースがあるタイムスタンプと一致します。
$file:e
$file:r
ファイル拡張子を抽出して歴史的修正。
すべてのファイルを繰り返して、通常のファイルのみを一致させるのではなく、次を使用します。グローバル予選通常のファイルのみが一致します。
for file in *(.); do
extension=$file:e
rest=$file:r
timestamp_start=0:00
timestamp_end=
while [[ $rest =~ ,\ *([0-9:]+:[0-9][0-9])\ * ]]; do
track_name=$rest[1,$MBEGIN-1]
rest=$rest[$MEND+1,-1]
timestamp_end=$match[1]
ffmpeg -ss $timestamp_start -to $timestamp_end -I $file -acodec copy $track_name.$extension
timestamp_start=$timestamp_end
done
if [[ -n $timestamp_end ]]; then
ffmpeg -ss $timestamp_end -I $file -acodec copy $rest.$extension
else
: # If you want special processing for single-track files, it goes here.
fi
done