kkroening / ffmpeg-python

Python bindings for FFmpeg - with complex filtering support
Apache License 2.0
9.87k stars 883 forks source link

Concat two different video files #175

Open Stinosko opened 5 years ago

Stinosko commented 5 years ago

Hey,

I'm trying to make a python script to glue/merge multiple videos together but i'm hitting two wall were i can only merge two perfectly identical video file detail (video/audio codex, bitrate,...). My idea is how do i convert one video file to a perfectly identical video file properties?

This works to get the video properties but how do i use them to convert another video file?

from __future__ import unicode_literals, print_function
import ffmpeg
URL = "output.mp4"
try:
    probe = ffmpeg.probe(URL)
except ffmpeg.Error as e:
    print(e.stderr, file=sys.stderr)
    sys.exit(1)
video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
if video_stream is None:
    print('No video stream found', file=sys.stderr)
    sys.exit(1)
width = int(video_stream['width'])
height = int(video_stream['height'])
num_frames = int(video_stream['nb_frames'])
print('width: {}'.format(width))
print('height: {}'.format(height))
print('num_frames: {}'.format(num_frames))
jackforlit commented 4 years ago

Did you find any solution to resolve this kind of issue?

I fond the related issue in below: https://github.com/kkroening/ffmpeg-python/issues/96

BjornFJohansson commented 4 years ago

This script does not use ffmpeg, but it does work. Perhaps someone more knowledgeable could translate what is in the two cmd variables to ffmpeg-python so that we could have a function that does this ( I suspect that it is a common task).

#!/home/bjorn/anaconda3/envs/bjorn37/bin/python
# -*- coding: utf-8 -*-

"""
This script uses ffmpeg to merge all mp4 files in the
folder which the script is run. You need to have ffmpeg
installed on your computer.

https://gist.github.com/BjornFJohansson/7c56daad679223e4cdc9f1cac50197ad
"""
import pathlib
#import ffmpeg
import subprocess
import zipfile

#paths = sorted(pathlib.Path(".").glob("*.mp4"),key=lambda x: x.lstat().st_mtime)

paths = [p for p in sorted(pathlib.Path(".").glob("*.mp4")) if not p==pathlib.Path('out.mp4')]

newpaths= []
tspaths = []

for i, path in enumerate(paths):
    tspath = path.with_suffix('.ts')
    newpath = path.with_name(f"video{i:02}.mp4")
    path.rename(newpath)
    newpaths.append(newpath)
    tspaths.append(tspath)
    cmd = f"ffmpeg -i {newpath} -c copy -bsf:v h264_mp4toannexb -f mpegts {tspath}"
    result = subprocess.run( cmd, stdout=subprocess.PIPE, check=True, shell=True)

concat = "concat:"+"|".join(p.name for p in tspaths)
cmd = f"ffmpeg -i '{concat}' -c copy out.mp4"

result = subprocess.run( cmd, stdout=subprocess.PIPE, check=True, shell=True)

for tspath in tspaths:
    tspath.unlink()

with zipfile.ZipFile("zip.zip", 'w') as myzip:
    for path in newpaths:
        myzip.write(path,path.name)
        path.unlink()