YYYY-MM-DD/VIDEOCHANNELNUMBER-EVENTIMERANGE.mp4
日付別、カメラチャンネル別、イベント時間別( )別に分かれた映像ファイルが多いです。
/2021-07-03/ch2_main_20210703074010_20210703074154.mp4
/2021-07-03/ch2_main_20210703074156_20210703074357.mp4
/2021-07-03/ch2_main_20210703074446_20210703074537.mp4
/2021-07-03/ch2_main_20210703074618_20210703075119.mp4
/2021-07-03/ch2_main_20210703075153_20210703075312.mp4
/2021-07-03/ch2_main_20210703075337_20210703080422.mp4
このクリップを日付とカメラのチャンネルごとにマージしたい(例/2021-04-03-CH1.mp4
:)
私のプロセスは次のとおりです
- 各日付フォルダを繰り返します(
for VIDEODIR in */
)。 - 各フォルダで各チャンネル番号を繰り返します(
for VIDEOCHANNELNUMBER in 1 2 3 4 5 6; do
)。 - 各チャンネル番号でマージするすべてのビデオファイルを見つけます(
for f in $VIDEODIR/ch$VIDEOCHANNELNUMBER*.mp4 ; do
)。 - FFMPEGはファイルをルートディレクトリ(
ffmpeg -i $VIDEOLIST -c copy "$DATE-CH$VIDEOCHANNELNUMBER.mp4"
)にマージして保存します。 - 成功すると、すべての元のクリップのディレクトリを削除します。 (
if [ $? -eq 0 ]; then rm $VIDEODIR -r fi
)
何らかの理由でビデオチャンネルが当日オフラインになり、一致するものがない場合は、手順2が間違って詰まります。 (zsh: no matches found: /2021-07-03/ch1*.mp4
)。スキップして続行するのではなく、ループ全体が中断されます。
答え1
N
glob修飾子を使用して一致するものがない場合は、エラーを返すのではなくglobを拡張しないように指定でき、修飾子を使用してディレクトリタイプ/
のファイルを選択できます。
N
配列変数に割り当てるときは、通常修飾子を使用する必要があります。
dirs=( *(N/) )
または繰り返すとき:
for dir in *(N/)
したがって、何をしたいのかわかりませんが、次のようになります。
for dir in *(N/); do
for (( channel = 1; channel <= 6; channel++ )); do
files=( $dir/ch${channel}_*.mp4(N) )
if (( $#files )); then
ffmpeg ... $file
fi
done
done
ここでは、一度にすべてのファイルを繰り返すためにさまざまなアプローチを使用できます。
typeset -A list=()
for file (<1900-2100>-<1-12>-<1-31>/ch<1-6>_*.mp4(Nn))
files[$file:h-${${file:t}%%_*}.mp4]+=$file$'\0'
for output_file (${(k)list})
ffmpeg -i ${(0)list[$output_file]} -c copy $output_file &&
rm -f ${(0)list[$output_file]}
(rmdir <1900-2100>-<1-12>-<1-31>(/^F)
その後、空のディレクトリを削除します)。
興味深いことに、これがすることですfish
。 inなどの一致がない場合は、globが(変数に割り当てられている)、またはzsh
と共に使用されない限り、globでエラーが発生します。for
set
count