-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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