Files
2021-12-08 19:49:06 +01:00

2.6 KiB

MP4 muxer

Info

This code is only meant to work with ALAC and EAC3 (JOC) streams, for any other codecs you're on your own. Use at your own risk. If you use this to create files and don't validate them afterwards, don't blame me if something goes wrong.

None of this code will parse MP4 files for you. If your source file is a different MP4 file (or a different format entirely), you will have to figure out how to parse the required information (see Usage) yourself.

For more information, see here.

Usage

You will need to provide the following info:

  • Sample rate
  • Bit depth
  • mdat box as a bytearray
  • Sizes for all samples contained within the mdat box
  • Total duration
  • (optional: Tags)

Writing tags is optional, even without them the file will play back just fine. They're written to moov/udta/meta/ilst.

If you do not create a Tags object and/or do not use set_tags(), then the udta box will not be created.

Note for EAC3 JOC: This code assumes that there is only a single independed substream present and that the values in the EAC3 specific box within stsd of the source file match the following (I left out the reserved bits here):

fscod = 0
bsid = 16
asvc = 0
bsmod = 0
acmod = 7
lfeon = 1
num_dep_sub = 0
ec3_job_flag = 1
joc_complexity_index = 16

Example

from mp4muxer_alac import MP4MuxerALAC

m = MP4MuxerALAC()
m.set_sample_rate(44100)
m.set_bit_depth(16)
sample_sizes = [7424, 6915, 6830, 6737, ..., 2700, 1443]
m.set_sample_sizes(sample_sizes)
m.set_total_duration(10442880)
with open("m.dat", "rb") as f:
    mdat = bytearray(f.read())
m.set_mdat_data(mdat)

t = Tags()
t.track_name = "Insert Interesting Title Here"
t.artist = "Artist X & Y"
t.album_artist = "Artist X"
t.composer = "X, Y, Z"
t.album_name = "First Track - Single"
t.genre = "Dubstep;Country"
t.track_number = 1
t.total_number_of_tracks = 1
t.disc_number = 1
t.total_number_of_discs = 1
t.date = "2020-05-22"
t.upc = "5556667778889"
t.label = "We Sell Records Rec."
with open("cover.jpg", "rb") as f:
    t.cover_data = bytearray(f.read())
t.cover_format = "jpeg"
t.isrc = "CYZXL20044078"
t.copyright = "℗ 2021 We Sell Records Rec."
t.apple_store_catalog_id = 9999998
t.album_title_id = 9999999
t.playlist_id = 32423444

m.set_tags(t)
m.create()
m.out("A Piece of Music.m4a")

For EAC3 JOC the process is similar:

from mp4muxer_eac3 import MP4MuxerEAC3

m = MP4MuxerEAC3()
m.set_sample_rate(sr)
m.set_bit_depth(bd)
m.set_bit_rate(768)
m.set_sample_sizes(sample_sizes)
m.set_timestamp(timestamp)
m.set_mdat_data(mdat)

...