2

I would like to concaternate a fairly large list of videos using FFMPEG. The following answer from another question is highly relevant: https://stackoverflow.com/a/11175851/5065462. I explain below why it isn't sufficient for me. I'm using MP4 files.

I am using Windows 10. I'd like to write a bat file with arguments. I'll then call this from either Command Prompt or PowerShell.


I want to automate Option 1 https://stackoverflow.com/a/11175851/5065462 to take as input a txt (or similar) file containing the filepaths for the videos to be concatenated. I'm happy with all the default [#:v] [#:a] options.

An alternative option is just to write a small program, either in Command Prompt or python3 is fine, which outputs a text string that I just copy+paste into cmd/PS. Unfortunately, I'm not sure how to use python to get filenames.


Option 2 in https://stackoverflow.com/a/11175851/5065462 looks great. Unfortunatley, the stream-encoding has issues with my mp4 files. I found they are fixed by using Option 1 in the linked answer. However, I don't want to type every filename each time.

Sam OT
  • 420
  • 1
  • 4
  • 19

1 Answers1

2

The following python script will generate the command described in option 1. To run, use python3 script_file.py video_directory output.mkv.

video_directory should contain only video files.

import argparse
import os

parser = argparse.ArgumentParser()
parser.add_argument("dir", help="the directory to the videos")
parser.add_argument("output", help="the name of the output file")
args = parser.parse_args()

files = os.listdir(args.dir)
cmd = "ffmpeg "
for file in files:
    cmd += f"-i {file} "
cmd += '-filter_complex "'
for i in range(len(files)):
    cmd += f"[{i}:v] [{i}:a] "
cmd += f'concat=n={len(files)}:v=1:a=1 [v] [a]" '
cmd += f'-map "[v]" -map "[a]" {args.output}'
print(cmd)

NB: replacing the final line by os.system(cmd) will run the command directly from python.

Seon
  • 3,332
  • 8
  • 27
  • Great, thank you! The last comment is a helpful addition too. I am unfamiliar with the `argparse` and `os` packages---I basically only use `python` for maths/ds-type stuff and am very new to it. How can I make it so that `video_directory` doesn't have to contain only the files I want to concatenate? I guess I can just use something like adding `if file.beginswith("myVids_"):`, but it seems like there should be a nicer way. In `cmd`, I did `for %%i in (myVids_*.mp4)`. I'm not sure how to do this with the `listdir`. Maybe just adding the `if file.beginswith(...):` is the best option, though? – Sam OT Jun 06 '21 at 21:43
  • The `glob` module is pretty handy for that kind of operations, and provides support for bash-like wildcards. You can simply replace the `os.listdir` command by `glob.glob(os.path.join(args.dir, "myVids_*.mp4")` in the example above. – Seon Jun 06 '21 at 21:49
  • That's great, thank you Seon `:-)` -- I'll do that but replace `myVids` with anohter input argument – Sam OT Jun 07 '21 at 07:57