# 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](https://z8.re/blog/mp4). ## 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): ```python 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 ```python 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: ```python 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) ... ```