minimp4 icon indicating copy to clipboard operation
minimp4 copied to clipboard

Twitter does not accept minmp4 generated files, here is a possible fix.

Open Fra-Ktus opened this issue 5 years ago • 3 comments

The Twitter web interface does not accept files generated by the muxer. The web interface says: “Your media file could not be processed,” but does not give a detailed error.

The application built with minimp4 uses minih264 and the Fraunhofer FDK AAC for the audio part.

The problem only occurs if the mp4 has an audio track. Uploading an mp4 with one video track is accepted.

Copying the streams with FFmpeg without recoding fixes the issue. The command-line command used is ffmpeg -i out.mp4 -codec:a copy -codec:v copy fixed.mp4. Uploading fixed.mp4 is working.

When comparing the two files with the web tool https://www.onlinemp4parser.com the issue is located to the atom ESDS. The FFmpeg one is longer.

This discussion, a little bit old, give some details: https://stackoverflow.com/questions/30998150/build-an-esds-box-for-an-mp4-that-firefox-can-play

Modyfing the static int mp4e_flush_index(MP4E_mux_t *mux) function seems to fix the issue. Here is the modified part:

ATOM_FULL(BOX_esds, 0);
if (tr->vsps.bytes > 0)
{
    int dsi_bytes = tr->vsps.bytes - 2; //  - two bytes size field
    int dsi_size_size = od_size_of_size(dsi_bytes);
    int dcd_bytes = dsi_bytes + dsi_size_size + 1 + (1 + 1 + 3 + 4 + 4);
    dcd_bytes += 3; // FraKtus +3
    int dcd_size_size = od_size_of_size(dcd_bytes);
    int esd_bytes = dcd_bytes + dcd_size_size + 1 + 3;
    esd_bytes += 9; // FraKtus, added 3 0x80 0x80 0x80 and section 6 of 6 bytes

#define WRITE_OD_LEN(size) if (size > 0x7F) do { size -= 0x7F; WRITE_1(0x00ff); } while (size > 0x7F); WRITE_1(size)
    WRITE_1(3); // OD_ESD
    WRITE_1(0x80); WRITE_1(0x80); WRITE_1(0x80); // FraKtus
    WRITE_OD_LEN(esd_bytes);
    WRITE_2(0); // ES_ID(2) // TODO - what is this?
    WRITE_1(0); // flags(1)

    WRITE_1(4); // OD_DCD
    WRITE_1(0x80); WRITE_1(0x80); WRITE_1(0x80); // FraKtus
    WRITE_OD_LEN(dcd_bytes);
    if (tr->info.track_media_kind == e_audio)
    {
        WRITE_1(MP4_OBJECT_TYPE_AUDIO_ISO_IEC_14496_3); // OD_DCD
        WRITE_1(5 << 2); // stream_type == AudioStream
    } else
    {
        // http://xhelmboyx.tripod.com/formats/mp4-layout.txt
        WRITE_1(208); // 208 = private video
        WRITE_1(32 << 2); // stream_type == user private
    }
    WRITE_3(tr->info.u.a.channelcount * 6144/8); // bufferSizeDB in bytes, constant as in reference decoder
    WRITE_4(0); // maxBitrate TODO
    WRITE_4(0); // avg_bitrate_bps TODO

    WRITE_1(5); // OD_DSI
    WRITE_1(0x80); WRITE_1(0x80); WRITE_1(0x80); // FraKtus
    WRITE_OD_LEN(dsi_bytes);
    for (i = 0; i < dsi_bytes; i++)
    {
        WRITE_1(tr->vsps.data[2 + i]);
    }
    
    // FraKtus ->
    WRITE_1(6); // ???
    WRITE_1(0x80); WRITE_1(0x80); WRITE_1(0x80);
    WRITE_1(1); WRITE_1(2);
    // -> FraKtus
}

The modified parts have a FraKtus comment.

I do not have enough expertise to say that this should be added to master, but I hope it can fix some users' issues.

The files generated are accepted by all majors social networks (Instagram, TikTok, Twitter, YouTube...) and plays fine on macOS. FFmpeg does not complain when processing them, even at a verbose level.

Thank you for the beautiful minip4 and mnih264 projects! They allow creating fast and light applications with no dependencies.

Fra-Ktus avatar Feb 06 '21 15:02 Fra-Ktus

Thanks for such informative and useful issue) I will try to find some official documentation and fix it.

lieff avatar Feb 07 '21 12:02 lieff

My application is both online and desktop, so I can email you a link to test if you want. You can reach me at marco at hinic dot me.

Fra-Ktus avatar Feb 07 '21 16:02 Fra-Ktus

I had the same issue and I confirm the changes made by @Fra-Ktus solve the issue for Firefox (and work with others too).

bezineb5 avatar Nov 27 '21 10:11 bezineb5