大きなビデオファイル(large.mp4
)と対応する字幕ファイル(large.srt
)があります。
両方のファイルをn等しい部分に分割する最良の方法は何ですか?
これにより、large-1.mp4
、...、large-n.mp4
およびlarge-1.srt
、...、large-n.srt
が生成されます。そして、これらのファイルはすべて同じサイズになります(最後のファイルを除く)。
両方のファイルを特定の期間、たとえば15分に分割する最良の方法は何ですか?
出力は上記の出力と同様です。
スクリプトなしで、できればffmpeg
、できればダイレクトコマンドを使用して、コマンドラインツールを使用したいと思います。
このような複雑なタスク(私の知る限り)は、ffmpeg
だけでは、1回の呼び出しで行うことはできませんが、以下にonelineバージョンを追加します。スクリプトバージョンは次のとおりです。
#!/bin/bash
in=$1
dur=$2
totaldur=$(ffprobe -v -8 -show_entries format=duration -of flat large.mp4 | sed -r 's/.*"([0-9]+).*/\1/')
i=0
while (( i * dur < totaldur) )
do
ffmpeg -i $in -i ${in%%.*}.srt \
-ss $((i*dur)) -t $dur -c copy -sn ${in%%.*}-$((i+1)).${in#*.} \
-ss $((i*dur)) -t $dur -an -vn ${in%%.*}-$((i+1)).srt
((i++))
done
このスクリプトは2つの引数を取ります。最初の引数はビデオのファイル名で、2番目の引数は秒単位の長さです。以下の実行例を参照してください。最初にffprobe
の出力をsed
にパイプして、ビデオの合計時間を秒単位で取得します。この値は、パーツのwhile
ループを構築するために使用されます。ループ内でffmpeg
が呼び出され、1回の呼び出しで.mp4
と.srt
の両方のパーツが作成されます。
$ tree # the directory contains large.mp4 and large.srt
.
├── large.mp4
└── large.srt
$ ffmpeg -i large.mp4 |& awk '/Duration/' # large.mp4 has a duration of 00:02:30.07
Duration: 00:02:30.07, start: 0.000000, bitrate: 1283 kb/s
$ /path/to/above/script large.mp4 60 # let's split it after every 60 seconds
$ tree
.
├── large-1.mp4
├── large-1.srt
├── large-2.mp4
├── large-2.srt
├── large-3.mp4
├── large-3.srt
├── large.mp4
└── large.srt
最初の2つの変数は、ファイル名と秒単位の期間を保持し、必要に応じてこれら2つを調整します。
in=large.mp4;dur=60;i=0;while ((i*dur<$(ffprobe -v -8 -show_entries format=duration -of flat large.mp4|sed -r 's/.*"([0-9]+).*/\1/')));do ffmpeg -y -i $in -i ${in%%.*}.srt -ss $((i*dur)) -t $dur -c copy -sn ${in%%.*}-$((i+1)).${in#*.} -ss $((i*dur)) -t $dur -an -vn ${in%%.*}-$((i+1)).srt;((i++));done
途中で見つけたリンクをいくつか紹介します。