Skip to content

Instantly share code, notes, and snippets.

@c3333
Forked from ntrrgc/gen-edit-lists.py
Created September 3, 2020 19:38
Show Gist options
  • Save c3333/04094c14c2b5e19fc1298f55fd04347e to your computer and use it in GitHub Desktop.
Save c3333/04094c14c2b5e19fc1298f55fd04347e to your computer and use it in GitHub Desktop.
Generate crazy MP4 edit lists to be added to media files for testing.
#!/usr/bin/python3
#
# Generate crazy MP4 edit lists to be added to media files for testing.
#
# 1. Modify the timescales below with the actual values from the MP4 file.
#
# 2. Run the following commands to patch the file with Bento:
#
# # Remove previously existing edit list (optional, only if there is some)
# mp4edit --remove moov/trak/edts original.mp4 patched1.mp4
# # Generate the new ones
# python gen-edit-lists.py
# # Insert the new edit lists
# mp4edit --insert moov/trak[0]:edts_video.box:-1 patched{1,2}.mp4
# mp4edit --insert moov/trak[1]:edts_audio.box:-1 patched{2,3}.mp4
#
import struct
from collections import namedtuple
Edit = namedtuple("Edit", ["duration", "media_time", "media_rate"])
movie_timescale = 600
video_track_timescale = 24000
audio_track_timescale = 48000
def gen_desired_edits(track_timescale):
return [
# First 5 seconds of the movie consist of the track media from
# [4, 4+5) s.
Edit(5 * movie_timescale, 4 * track_timescale, 1),
# The following 90 seconds of the movie consist of the track media from
# [40, 40+90) s.
Edit(90 * movie_timescale, 40 * track_timescale, 1),
# The following 20 seconds in the movie, there is nothing.
Edit(20 * movie_timescale, -1, 1),
# Then, 10 seconds of video from the beginning of the track
Edit(10 * movie_timescale, 0 * track_timescale, 1),
# Then, 5 seconds of still image from the second 1 of the track
Edit(5 * movie_timescale, 1 * track_timescale, 0),
]
def gen_elst(desired_edits):
flags = 0
version = 1 if any(
edit.duration > 0xFFFFFFFF or edit.media_time > 0xFFFFFFFF
for edit in desired_edits
) else 0
contents = struct.pack(">LL", (version << 24) | flags, len(desired_edits))
for edit in desired_edits:
if version == 1:
contents += struct.pack(">Qq", edit.duration, edit.media_time)
else:
contents += struct.pack(">Ll", edit.duration, edit.media_time)
contents += struct.pack(">hh", edit.media_rate, 0)
# Write the header
return struct.pack(">L", 8 + len(contents)) + b"elst" + contents
def gen_edts(desired_edits):
elst = gen_elst(desired_edits)
return struct.pack(">L", 8 + len(elst)) + b"edts" + elst
if __name__ == '__main__':
with open("edts_audio.box", "wb") as f:
f.write(gen_edts(gen_desired_edits(audio_track_timescale)))
with open("edts_video.box", "wb") as f:
f.write(gen_edts(gen_desired_edits(video_track_timescale)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment