Mrunal Gawade
Mrunal Gawade

Reputation: 39

Combining sampled videos from multiple sources using ffmpeg

If I have two videos shooting the same subject but from different angles, and then I want to create a single video, but the combination is not just concatenation but a time lined sample linearly from each of the video to create the same time line output video. Is it possible?

For e.g. if both videos were shot for 1 minute each. then when I combine I want to combine 0-15 secs from 1st then 15-30 secs from second, then 30-45 from 1st, then 45-60 from second video. to create a 1 minute video.

Also as a generic case if above is possible, the time sample need not be uniformly distributed but random from each videos, as long as the total clips add upto original shoot time.

As a more generic case if above is possible, extending it to more than two video sources, lets say 3 videos combined in the above manner in a random time clips to create a single video.

many thanks Mrunal

Upvotes: 1

Views: 1042

Answers (2)

Dimitri Podborski
Dimitri Podborski

Reputation: 3774

You can do this by dividing your problem into this three subtasks:

  1. Create 15 seconds chunks of each video.

you can do it like this:

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. Create a simple text file with all the chunks in desired order like described here.

This file (let us call it list.txt) should look like this:

file '/path/to/vid1_chunk_0.mp4'
file '/path/to/vid2_chunk_1.mp4'
file '/path/to/vid1_chunk_2.mp4'
...
  1. Concatenate using: ffmpeg -y -f concat -i list.txt -c copy final.mp4

Here is an example python script:

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)

Upvotes: 1

Gyan
Gyan

Reputation: 92928

If frame accuracy isn't important, you can do this in two steps, skipping the chunk creation.

Create concat list

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...)

Run concat

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

Upvotes: 1

Related Questions