交互式连接视频文件

Sly*_*lyx 9 bash ffmpeg shell-script video-encoding avconv

如何以交互方式将多个 MP4 视频文件连接(连接)为一个文件?

有很多程序可以从命令行对两个文件执行此操作。例如:

  • ffmpeg
  • 转换
  • MP4Box

但是我们经常需要一个解决方案来以交互方式执行此操作。

slm*_*slm 8

我最近没有尝试过这种方法,但不明白为什么它仍然不起作用。我相信cat .mp4如果你不想做任何事情而不是连接它们,你可以将文件放在一起。

1.使用猫

$ cat file1.mp4 file2.mp4 > file3.mp4
$ ffmpeg -i file3.mp4 -qscale:v 2 output.avi
Run Code Online (Sandbox Code Playgroud)

我一直在用ffmpeg,它也可以连接文件。

2.使用ffmpeg

  1. 制作要连接的文件列表

    $ cat inputs.txt 
    file sample_mpeg4.mp4
    file sample_mpeg4.mp4
    
    Run Code Online (Sandbox Code Playgroud)
  2. 连接

    $ ffmpeg -f concat -i inputs.txt -c copy out.mp4
    
    $ ll |grep -E "sample|out"
    -rw-rw-r--. 1 saml saml 491860 Feb 19 23:36 out.mp4
    -rw-r--r--. 1 saml saml 245779 Feb 19 23:32 sample_mpeg4.mp4
    
    Run Code Online (Sandbox Code Playgroud)

    FFmpeg wiki 中介绍了其他方法:How to concatenate (join, merge) media files

    注意: Ubuntu 似乎不支持该concat格式。您必须使用 concat 协议。此外,它还具有每个流编解码器选项。因此,使用 concat 协议结果如下:

    $ ffmpeg -i input1.mp4 -vcodec copy -acodec copy \
         -vbsf h264_mp4toannexb -f mpegts intermediate1.ts
    
    $ ffmpeg -i input2.mp4 -vcodec copy -acodec copy \
         -vbsf h264_mp4toannexb -f mpegts intermediate2.ts
    
    $ ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" \
         -vcodec copy -acodec copy -absf aac_adtstoasc output.mp4
    
    Run Code Online (Sandbox Code Playgroud)

    此处记录Ubuntu ffmpeg 选项。

  • 我证实了这一点。使用 `cat` 不是一个有效的解决方案。`cat`ing 生成的两个文件只显示第一个输入文件的内容! (2认同)

Sly*_*lyx 4

我使用 MP4Box 作为工作基础。
\n我建议的脚本一一读取所有文件,验证每个文件(如果它是普通文件),要求用户输入要创建的文件名。

\n\n
#!/bin/bash\nprintf "###  Concatenate Media files ###\\n"\nfInputCount=0\n# Reading input files\nIFS=\'\'\nwhile (true)\ndo\n    let currentNumber=$fInputCount+1 \n    printf "File n\xc2\xb0%s (\\"ok\\" to finish): " $currentNumber\n    read inputFile\n    [ "$inputFile" == "ok" ] && break\n    [ ! -e "$inputFile" ] || [ ! -f "$inputFile" ] && printf "\\"%s\\" : Invalid filename. Skipped !\\n" "$inputFile" && continue\n    ((fInputCount++))\n    inputFileList[$fInputCount]=$inputFile\n    printf "\\"%s\\" : Added to queue !\\n" "$inputFile"\ndone\n[ "$fInputCount" == "0" ] || [ "$fInputCount" == "1" ] && echo "No enough input data. BYE ! " && exit\n# Listing the input file list \nfor ((i=1;i<=$fInputCount;i++))\ndo\n    printf "%2d : %s\\n" $i ${inputFileList[$i]}\ndone\n# Reading the output filename\nwhile (true)\ndo\n    printf "Output file without extention (\\"none\\" to dismiss) : "\n    read outputRead\n    [ "$outputRead" == "none" ] && echo "Dismissed. BYE ! " && exit\n    [ "$outputRead" == "" ] && echo "Try again ! " && continue\n    [ -e "$outputRead" ] && echo "\\"$outputRead\\" exists. Try again !" && continue\n    outputFile=$outputRead.mp4\n    echo "Output to \\"$outputFile\\". Go !" && break\ndone\n# Creating a random temporary filename\ntmpOutFile="/tmp/concatMedia"`date +"%s%N"| sha1sum | awk \'{print $1}\'`".mp4"\n# Joining the two first input files\nMP4Box -cat "${inputFileList[1]}" -cat "${inputFileList[2]}" $tmpOutFile\n# Adding all other files\nfor ((i=3;i<=$fInputCount;i++))\ndo\n    tmpIntermediateFile=$tmpOutFile\n    tmpOutFile="/tmp/concatMedia"`date +"%s%N"| sha1sum | awk \'{print $1}\'`".mp4"\n    MP4Box -cat $tmpIntermediateFile -cat "${inputFileList[$i]}" $tmpOutFile\n    rm $tmpIntermediateFile\ndone\nmv $tmpOutFile "$outputFile"\n# Finished\necho "\\"$outputFile\\" Saved !"\n
Run Code Online (Sandbox Code Playgroud)\n