Bash 脚本以 5 个为一批对 MP4 文件进行 FFmpeg concat

Bash 脚本以 5 个为一批对 MP4 文件进行 FFmpeg concat

我喜欢创建一个 Bash 脚本,使用 FFmpeg 连接 MP4 文件,对于包含 100 个 MP4 文件的目录,每次批量连接 5 个文件,这样之后就会有 20 个文件,如下所示:

001_005.mp4、006_010.mp4 等等……

而不是仅仅包含全部 100 个文件的 1 个文件。

mylist.txt的内容:

file 001.mp4
file 002.mp4
file 003.mp4
file 004.mp4
file 005.mp4
............
file 099.mp4
file 100.mp4

虽然我找到了一个可以正常工作的命令(来自此 StackOverflow 线程),它将只创建 1 个包含全部 100 个文件的文件。

#!/bin/bash

cd /home/admn/Downloads/MP4_Files;

# Create mylist.txt:
for f in *.mp4
do
    echo "file $f" >> mylist.txt
done;

# Concatenate files:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4;

那么,我该如何修改 ffmpeg 命令以便它每次批量连接 5 个文件。

所有文件都具有完全相同的分辨率(1080p)、音频和视频编解码器。

操作系统:Ubuntu MATE 21.04

ffmpeg版本:4.3.2-0+deb11u1ubuntu1

答案1

我认为下面的脚本会起作用。

  • 首先按原样尝试一下,检查它是否能达到你想要的效果
  • echo然后从行中删除ffmpeg以使其发挥作用。

检查临时文件 xat` 的内容是否xaa' ...与输出文件的名称(和内容)匹配。

#!/bin/bash

> mylist.txt
for f in *.mp4
do
 echo "file '$f'" >> mylist.txt
done

< mylist.txt sort -t \' -n -k2 | split -l 5

k=1
for j in x*
do
 inc=$(wc -l "$j" | cut -d ' ' -f 1)
 m=$(printf "%03d" $((k)))
 n=$(printf "%03d" $((k+inc-1)))
 name="${m}_${n}.mp4"
 echo ffmpeg -f concat -safe 0 -i "$j" -c copy "$name"
 k=$((k+5))
done

答案2

另一种解决方案是使用嵌套循环。

只要还有剩余的文件,内循环就会${@:1:5}取出下一片(最多) 5 个文件。

#!/bin/bash
cd /home/admn/Downloads/MP4_Files;

shopt -s failglob
set -- *.mp4
while [[ $# -gt 0 ]]; do
    from=$(basename "$1" .mp4)
    for f in "${@:1:5}"; do
        #not essential in your case, but use @Q to quote/escape special characters
        echo "file ${f@Q}" >> mylist.txt
        shift
    done
    to=$(basename "$f" .mp4)
    ffmpeg -f concat -safe 0 -i mylist.txt -c copy "${from}_${to}.mp4"
    rm mylist.txt
done

答案3

假设mylist.txt存在于您当前的工作目录中,您可以执行以下操作,

LINES=$(cat mylist.txt | wc -l)
BATCH_SIZE=5
BATCHES=$(($LINES/$BATCH_SIZE))             

for ((i=0;i<$BATCHES;i++))
do
  cat mylist.txt | head -n $((($i+1)*$BATCH_SIZE)) | tail -n $BATCH_SIZE > slist.txt
  ffmpeg -f concat -safe 0 -i slist.txt -c copy $(($i*$BATCH_SIZE+1))_$((($i+1)*$BATCH_SIZE)).mp4
done
rm slist.txt

相关内容