【问题标题】:Combining sampled videos from multiple sources using ffmpeg使用 ffmpeg 组合来自多个来源的采样视频
【发布时间】:2016-01-06 16:15:04
【问题描述】:

如果我有两个视频从不同的角度拍摄相同的主题,然后我想创建一个视频,但组合不仅仅是串联,而是每个视频的线性时间线样本以创建相同的时间线路输出视频。有可能吗?

例如如果两个视频分别拍摄 1 分钟。然后当我合并时,我想合并第一个视频的 0-15 秒,第二个视频的 15-30 秒,第一个视频的 30-45 秒,第二个视频的 45-60 秒。制作一个 1 分钟的视频。

如果上述情况可能,作为一般情况,时间样本不必均匀分布,而是从每个视频中随机分布,只要总剪辑加起来等于原始拍摄时间。

如果上述情况可行,作为更通用的情况,将其扩展到两个以上的视频源,假设 3 个视频以上述方式组合在随机时间剪辑中以创建单个视频。

非常感谢

【问题讨论】:

  • 我们是否可以假设所有视频都使用相同的 GOP 结构进行编码,并且您将仅在 I 帧上剪切?
  • 是的,为了简单起见,所有视频都将使用相同的相机,以保持编码相同并设置同质化。但是,如果我们假设摄像头略有不同,因为我知道一些高清网络摄像头具有板载处理功能,而有些则不然,那么要获得类似的结果会有多困难。

标签: video ffmpeg


【解决方案1】:

您可以通过将问题分为以下三个子任务来做到这一点:

  1. 为每个视频创建 15 秒的块。

你可以这样做:

ffmpeg -y -i vid1.mp4 -vcodec copy -ss 00:00:00 -t 00:00:15 vid1_chunk_0.mp4
ffmpeg -y -i vid1.mp4 -vcodec copy -ss 00:00:15 -t 00:00:15 vid1_chunk_1.mp4
...
  1. 按照here 所述的顺序创建一个包含所有块的简单文本文件。

这个文件(我们称之为list.txt)应该是这样的:

file '/path/to/vid1_chunk_0.mp4'
file '/path/to/vid2_chunk_1.mp4'
file '/path/to/vid1_chunk_2.mp4'
...
  1. 连接使用:ffmpeg -y -f concat -i list.txt -c copy final.mp4

这是一个示例 python 脚本:

import os

def sec2hms(seconds):
    m, s = divmod(seconds, 60)
    h, m = divmod(m, 60)
    return "%02d:%02d:%02d" % (h, m, s)

def createchunks(video, vid_dur, chunk_dur):
    chunks = list()
    for n in range(0, vid_dur / chunk_dur):
        cmd = 'ffmpeg -y -v quiet'
        cmd += ' -i ' + video
        cmd += ' -vcodec copy'
        cmd += ' -ss ' + sec2hms(n*chunk_dur)
        cmd += ' -t ' + sec2hms(chunk_dur)
        cmd += ' ' + video[:-4] + '_chunk_' + str(n) + '.mp4'
        print cmd
        os.system(cmd)
        chunks.append(video[:-4] + '_chunk_' + str(n) + '.mp4')
    return chunks

# step 1. create 15 sec. chunks of first 60 sec. of content
vid1_chunks = createchunks('vid1.mp4', 60, 15)
vid2_chunks = createchunks('vid2.mp4', 60, 15)

# step 2. create a list.txt file (alternating order)
filenames = [None] * len(vid1_chunks)
filenames[::2] = vid1_chunks[::2]
filenames[1::2] = vid2_chunks[1::2]
with open('list.txt', 'w') as listfile:
    for fname in filenames:
        listfile.write('file \'' + fname + '\'\n')

# step 3. concatenate
cmd = 'ffmpeg -y -v quiet -f concat -i list.txt -c copy final.mp4'
os.system(cmd)

【讨论】:

  • 非常感谢详细的回复和脚本。我真诚地感谢它。我会拿这个做一些实验。在我的实验中,我还有一些事情要问。
  • @MrunalGawade 不客气。试试这个,如果(且仅当)它解决了你的问题,别忘了接受答案,这样有同样问题的其他人可以更快地找到解决方案。
  • 好的。但由于我要出站几天,因此可能需要一些时间来尝试一下。要接受答案,我必须点击左侧答案的向上箭头?
  • @MrunalGawade 不,这是为了投票,如果您认为答案有用,您应该投票。只有在提供的答案解决了您的问题时,您才应该接受。您可以阅读更多关于投票here 和接受here 的信息。
  • 好的。所以脚本有效:) 我接受了答案。非常感谢。
【解决方案2】:

如果帧精度不重要,您可以分两步完成,跳过创建块。

创建连接列表

file 'video1.mp4'
inpoint 0
outpoint 15
file 'video2.mp4'
inpoint 15
outpoint 30
file 'video1.mp4'
inpoint 30
outpoint 45
file 'video2.mp4'
inpoint 45
outpoint 60
(fill out the text file in this manner...)

运行 concat

ffmpeg -y -f concat -i list.txt -c copy final.mp4

【讨论】:

  • 执行上述脚本时出现以下错误。 [concat @ 0xbf7ca0] 第 2 行:未知关键字 'inpoint' list.txt:处理输入时发现无效数据
  • 你用的是哪个版本的ffmpeg?
  • ffmpeg 版本 2.7.2-1build1 版权所有 (c) 2000-2015 FFmpeg 开发者
  • 好的,那是 7 月的版本。范围关键字是后来添加的。尝试最近的构建。
  • 好的。我会尽快尝试的。谢谢。几天前我在我的 ubuntu 上做了“sudo apt-get install ffmpeg”来安装这个版本,所以我现在必须检查手动源安装。
猜你喜欢
  • 2011-11-25
  • 1970-01-01
  • 2016-05-03
  • 2012-10-07
  • 2018-12-22
  • 2011-08-07
  • 2019-09-12
  • 1970-01-01
相关资源
最近更新 更多