Jos*_*ndo 41 mp4 join concatenation
我想加入两个 mp4 文件来创建一个。视频流以 h264 编码,音频以 aac 编码。由于计算原因,我无法将视频重新编码为另一种格式。此外,我不能使用任何 GUI 程序,所有处理都必须使用 Linux 命令行实用程序执行。FFmpeg 无法对 mpeg4 文件执行此操作,因此我使用 MP4Box:
MP4Box -add video1.mp4 -cat video2.mp4 newvideo.mp4
Run Code Online (Sandbox Code Playgroud)
不幸的是,音频变得混乱了。我认为问题是音频在 aac 中,所以我将其转码为 mp3 并再次使用 MP4Box。在这种情况下,音频在newvideo.mp4(对应于video1.mp4)的前半部分很好,但随后它们没有音频,我也无法在视频中导航。
我的下一个想法是音频和视频流的长度存在一些小的差异,我应该修复。因此,对于每个输入视频,我拆分了视频和音频流,然后使用 FFmpeg 中的 -shortest 选项将它们连接起来。
因此,对于我运行的第一个视频:
avconv -y -i video1.mp4 -c copy -map 0:0 videostream1.mp4
avconv -y -i video1.mp4 -c copy -map 0:1 audiostream1.m4a
avconv -y -i videostream1.mp4 -i audiostream1.m4a -c copy -shortest video1_aligned.mp4
Run Code Online (Sandbox Code Playgroud)
第二个视频类似,然后像以前一样使用 MP4Box。不幸的是,这也不起作用。我唯一的成功是当我分别加入视频流(即 videostream1.mp4 和 videostream2.mp4)和音频流(即 audiostream1.m4a 和 audiostream2.m4a),然后在最终文件中加入视频和音频。但是,视频的后半部分将丢失同步。具体来说,音频和视频有 1 秒的延迟。任何建议都非常受欢迎。
evi*_*oup 47
目前最好的方法是使用concat demuxer。首先,创建一个名为inputs.txtformatted的文件,如下所示:
file '/path/to/input1.mp4'
file '/path/to/input2.mp4'
file '/path/to/input3.mp4'
Run Code Online (Sandbox Code Playgroud)
然后,只需运行此 ffmpeg 命令:
ffmpeg -f concat -i inputs.txt -c copy output.mp4
Run Code Online (Sandbox Code Playgroud)
为了任何使用旧版本 ffmpeg 的人的利益,我在此保留以下内容。
最新版本的 ffmpeg 可以做到这一点:您必须首先将文件重新混合到 mpeg 传输流中(相当轻量级,因为它只更改容器格式):
ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb middle.ts
Run Code Online (Sandbox Code Playgroud)
如果这引发了关于 h264的错误 [ 1 ],您可能需要使用:
ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf:v h264_mp4toannexb middle.ts
Run Code Online (Sandbox Code Playgroud)
您必须对每个输入文件分别执行此操作。要将文件连接在一起,请使用:
ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy output.mp4
Run Code Online (Sandbox Code Playgroud)
如果这引发了关于 aac 的错误,您可能需要使用
ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy -absf aac_adtstoasc output.mp4
Run Code Online (Sandbox Code Playgroud)
如果您的系统支持命名管道,则无需创建中间文件即可执行此操作。
mkfifo temp0 temp1
Run Code Online (Sandbox Code Playgroud)
您必须在三个独立的虚拟终端中执行以下操作:
ffmpeg -i input0.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp0
ffmpeg -i input1.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp1
ffmpeg -f mpegts -i "concat:temp0|temp1" -c copy -absf aac_adtstoasc output.mp4
Run Code Online (Sandbox Code Playgroud)
如果 output.mp4 已经存在,第三个 ffmpeg 会询问您是否要覆盖它,但它会在访问 FIFOs 后执行此操作,这将使第一个 ffmpegs 关闭。因此,请确保为输出文件选择一个未使用的名称。
如果您的输入文件不同,这可能不起作用 - 我相信比特率的差异是可以的,但帧大小、帧速率等必须匹配。
对于 mp4,我找到的唯一有效解决方案是使用 gpac 包中的 MP4Box
#!/bin/bash
filesList=""
for file in $(ls *.mp4|sort -n);do
filesList="$filesList -cat $file"
done
MP4Box $filesList -new merged_files_$(date +%Y%m%d_%H%M%S).mp4
Run Code Online (Sandbox Code Playgroud)
或命令是
MP4Box -cat file1.mp4 -cat file2.mp4 -new mergedFile.mp4
Run Code Online (Sandbox Code Playgroud)
使用 mencoder 和 avconv 我无法让它工作:-(
小智 5
这是一个单线,使这一切变得更加容易。它会完成所有需要做的事情,以便最终为您提供一个生成的视频文件。干杯!
find *.mp4 | sed 's:\ :\\\ :g'| sed 's/^/file /' > list.txt; ffmpeg -f concat -i list.txt -c copy output.mp4; rm list.txts
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
60207 次 |
| 最近记录: |