Skip to main content

Cut and splice video files using a YAML definition file and ffmpeg

Project description

ffmpeg editlist utility

Often, one wants to reprocess a video file using some basic operations, such as removing certain segments. Rather than opening a video editor, it is nice to be able to define a text file (the editlist) with processing instructions, and then run it. This allows collaboration in the processing, for example sharing the editlist file via git.

This utility takes a YAML definition of an editlist (segments to cut out and re-assemble into a file), and does the re-assembling using the ffmpeg command line utility.

This is currently an alpha-level utility: it works, but expect it may not exactly fit your use case without a bit of work. Documentation is minimal but still needs improvement. However, it has been used for several large events.

Video demonstration: https://youtu.be/thvMNTBJg2Y

Features include:

  • YAML edit list definition.
  • Select segments to stitch together in the final video file. Segments are either copied raw or re-encoded (--reencode).
  • Give Table of Contents times (for example, '16:45: Lesson 2 begins') relative to the source video, output mapped to times in the output video automatically.
  • Cover certain areas of video (for example, when an audience member appears).
  • Everything scripted and non-interactive.
  • Cutting and re-splicing subtitles, too.
  • Embed subtitles, title, chapters, and description inside the final .mkv file.

Installation and dependencies

This is on PyPI, may be installed with pip install ffmpeg-editlist. The only dependency is PyYAML so it might be reasonable to install with pip install --user. This creates a ffmpeg-editlist command in your environment.

For usage without installing, ffmpeg_editlist.py works as stand-alone with only pyyaml.

It depends on the ffmpeg command line utility, which must be installed through the operating system. Version requirements of ffmpeg are currently unknown.

The mkv file properties (title, description, chapters, subtitles) require mkvtoolnix to be installed. This is used by default, but the option --no-mkv-props will disable this.

Usage

Start with a directory of your videos (example: day1-raw.mkv).

Create an edit list file (described in next section). A minimal example is:

- input: day1-raw.mkv

- output: part1.mkv
  title: This is the title of part1
  description: >-
    This is the multi-line description
    of part 1.
  editlist:
    - start: 00:00   # These are time segments to include
    - 4:00: Begin exercise 1
    - stop: 5:00
    - start: 6:13
    - -: Going over the exercises  # '-' means "latest start time".
    - stop: 99:00

The general usage is then:

python ffmpeg-editlist.py EDITLIST.yaml INPUT-DIR [-o OUTPUT-DIR]

Where INPUT-DIR is the search path for input files and OUTPUT-DIR (default .) is the output path for files. You can use the --limit PATTERN option to reprocess only a few videos (example: --limit part1).

Because of the way keyframes work, there may be missing segments around the transition points. After you have tested that your timings seem reasonable, re-run with --reencode and it will do a full re-encoding and make a seamless videos. The default encoding settings are designed to be slow but good enough for all practical purposes:

python ffmpeg-editlist.py EDITLIST.yaml --reencode INPUT-DIR [-o OUTPUT-DIR]

OUTPUT-DIR will get the encoded files, and .txt files with the video descriptions ready to upload to your video hosting site.

Subtitles: The option --srt will make ffmpeg-editlist reprocess subtitles just like video segments (cut to the segments and adjust timestamps). A .srt file is expected alongside each input file (input file's extension replaced with .srt), and an output is similarly placed alongside each output. Warning: make sure that no segment's declared stop time goes beyond the actual file length. It's possible that there will be some weird effects around the beginning/end of the segments if subtitles go beyond the start/stop.

Show realtime schedule: A - schedule-sync: SCHEDULETIME=REALTIME entry in the yaml file will allow --show-schedule --dry-run -cq [-l day2] to print the timings, translated to a real-time schedule suitable as reference for future years.

Editlist definition

Minimal example: single file

# Input is taken from command line argument `input`.
- output: output.mp4
  title: This is the title
  description: >-
    This is the multi-line description.
  editlist:
    - start: 00:00   # These are time segments to include
    - stop: 5:00
    - start: 6:13
    - stop: 99:00

Run with python ffmpeg-editlist.py editlist.yaml input.mkv.

Minimal example with multiple files

- input: raw-day1.mkv
  output: day1-part1.mkv
  editlist:
    - start: 1:12
    - stop: 55:30

# Previous input file is used if no new input is defined
- output: day1-part2.mkv
  editlist:
    - start: 1:00:12
    - stop: 1:54:00

Run with python ffmpeg-editlist.py editlist.yaml $input_directory.

Multi-file with video descriptions

This is a full example that demonstrates all features.

- workshop_description: >
    If this exists, it will be appended to the bottom of every video
    description.  For example, it can be general information about the
    overall workshop.

# This input will be used for all segments until redefined
# Input relative to the input-dir command line argument.
# If not given, use the raw input-dir argument as a filename.
- input: cr-2021may-day1-obs.mov
- schedule-sync: 00:12:20=9:00:00

# A basic example
# Output is relative to the output-dir command line argument.
- output: day1-welcome.mp4
  # If given, do not reencode this segment even if --reencode is given
  # (useful for segments that start at 00:00).  'reencode: true' does
  # nothing, this is the default and --reencode must still be
  # specified on the command line.
  #reencode: false
  editlist:
    - start: 12:20
    - stop: 31:14

# Git-intro day 1
- output: day1-git-intro-1.mp4    # Output filename
  title: YouTube Video Title
  description: >
    Description of the video.
  editlist:
    # These pairs are times to *include*
    - start: 31:14
    - stop: 38:13
    - start: 41:28
    - stop: 1:04:45

# A sample including table of contents entries.
# You need to map times from the raw file, to the output file, in
# order to make a clickable YouTube table of contents.
# They are times in the
# original video, and they are converted to the equivalent times in
# the processed videos. They must be within the ranges above (and
# you get a unhandled error if they aren't):
#   segment_start <= toc_time < segment_stop.
# These can be interspersed with the segment definitions.
# Example:
- output: day2-git-intro-2.mp4
  editlist:
    - start: 31:14
    # TOC entry:
    - 31:14: Overview of the day
    - 33:25: Motivation to version control
    - stop: 38:13
    - start: 41:28
    - -: Basics of version control        # '-' is an alias for "last start"
    - 48:35: "Exercise: record changes"   # has a ':', so must be quoted
    - stop: 1:04:45
    #- 1:18:22: This will fail, timestamp after the end

# This syntax is used to cover a segment of the video:
- output: day3-has-audience-visible.mp4
  editlist:
  - start: 00:00
  # Cover an area.  begin/end are clear.  w and h are width and
  # height.  x and y are offset (left, down) from the top-left corner
  - cover: {begin: "1:15:29", end: "1:51:34", w: 840, h: 300, x: 360}
  - stop: 5:00

Alongside the .mp4 output file, a .mp4.info.txt file is created with these contents. This is designed for easy copying and pasting into hosting sites:

Title of Video

Video description.

01:53 Table of contents entry 1
15:45 Table of contents entry 2
...


Workshop description.

Multiple inputs

Multiple inputs in one segment might be useful when you are attaching an introduction to the main video. Note that things might go wrong if the video sizes and codecs do not align perfectly. (TODO: does this work as expected?)

- output: output.mp4
  editlist:
    - input: intro.mkv
    - start: 00:00
    - stop: 99:00
    - input: main.mkv
    - start: 0:00
    - stop: 99:00
    - input: outro.mkv
    - start: 0:00
    - stop: 99:00

See also

Status / Contributing

Alpha/beta, under development, it is starting to become reusable but still development is for a few use cases. In order to use this you probably have to read some code / work around some bugs since it isn't well tested yet.

Bug reports or improvements welcome, but it is kind of a mess now. Test with pytest ffmpeg-editlist.py, but note that main functionality is not tested right now.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ffmpeg_editlist-0.5.5.tar.gz (404.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ffmpeg_editlist-0.5.5-py2.py3-none-any.whl (14.2 kB view details)

Uploaded Python 2Python 3

File details

Details for the file ffmpeg_editlist-0.5.5.tar.gz.

File metadata

  • Download URL: ffmpeg_editlist-0.5.5.tar.gz
  • Upload date:
  • Size: 404.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ffmpeg_editlist-0.5.5.tar.gz
Algorithm Hash digest
SHA256 f14ee72a8f89333d039f964df9c7e75d4a91d9450b9497dd63feadca4d55fab8
MD5 58f127dfd2ef7535c4f5e145f9305b3f
BLAKE2b-256 3ffe8c0d8db4fa0c7ab05c7b6ecea2cd913b79d0544e1677d1130272b7b3d84c

See more details on using hashes here.

Provenance

The following attestation bundles were made for ffmpeg_editlist-0.5.5.tar.gz:

Publisher: release.yml on coderefinery/ffmpeg-editlist

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ffmpeg_editlist-0.5.5-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for ffmpeg_editlist-0.5.5-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 47fd69ae2844d71810d0cd480b39c3f536d3570e6114f63a1762cd49d31c3c67
MD5 df4e8f8fd12c379243df66f44fdf9baa
BLAKE2b-256 9a662cf097f3d8db2269ee787d2b482fcd1b2074e2eb36e4488947df1e67dd70

See more details on using hashes here.

Provenance

The following attestation bundles were made for ffmpeg_editlist-0.5.5-py2.py3-none-any.whl:

Publisher: release.yml on coderefinery/ffmpeg-editlist

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page