Le 17/05/2022 à 20:06, Alexis Murzeau a écrit : > [...]
I've investigated a bit more on how the arte.tv stream is made. I've found that ffmpeg v4 is using wrong timestamp information from the input stream and that only ffmpeg v5 read the correct timestamps. So the same conclusion as upstream. Details of why (brain dump :-) ): In fact, arte.tv is not using MPEGTS at all but fragmented MP4. I've checked the original files 108210-039-B_v216.mp4 and 108210-039-B_aud_VA.mp4 that are on arte.tv servers, and it is using the fragmented MP4 format correctly, with this structure: - A "header" with metadata: ftyp + moov + sidx - Several fragments: moof + mdat - A closing header: mfra In the aud_VA.m3u8 file: - The part referenced by #EXT-X-MAP matches exactly the first 1680 bytes of the .mp4 files which is the "header"(ftyp + moov + sidx) - One fragment in the m3u8 (#EXT-X-BYTERANGE) references 3 MP4 fragments (so 3x moof + mdat) So when streamlink process this file, it will add the "header" every 3 MP4 fragments like this: - One "header" (EXT-X-MAP) - ftyp + moov + sidx - One HLS fragment (EXT-X-BYTERANGE) == 3 MP4 fragments - moof + mdat - moof + mdat - moof + mdat - One "header" (EXT-X-MAP) - ftyp + moov + sidx - One HLS fragment (EXT-X-BYTERANGE) == 3 MP4 fragments - moof + mdat - moof + mdat - moof + mdat etc... until the last fragment (the "closing header" doesn't appear anymore). When checking with the HLS RFC, everything seems fine here. The MP4 stream contains timestamp in both sidx and tfdt (which is inside moof blocks). The issue is that ffmpeg v4 sees the sidx block and decide to reset sample timestamps (PTS and DTS, presentation and decoding timestamps) according to that data in sidx. The correct timestamps are in moof/tfdt which are not part of the header, so their values are different for each fragments (and correct). Timestamp in sidx are the same for all fragment as sidx is part of the "header" which is copied before each HLS fragment. As sidx appear for each HLS fragment, the behavior of ffmpeg v4 is to ignore tfdt and resets timestamps instead (which is wrong here). Then ffmpeg try to recover from that when writing the mpegts output file. Unfortunately, this means the resulting output file has bad frame timestamps and players try to follow them, which cause the glitches. With ffmpeg v5.x, it uses the tfdt (a block in moof block) instead of sidx and that tfdt contains correct data, that's why everything work fine with that version. There is a new option in ffmpeg called "use_tfdt" in that version, which is enabled by default now. This was implemented in parts, where the first is here: https://github.com/FFmpeg/FFmpeg/commit/071930de724166bfb90fc6d368c748771188fd94 According to github, this commit is only in version v5.0 (tag n5.0) but not earlier. => So really the only option to use ffmpeg v5.x Relevant files: https://arte-cmafhls.akamaized.net/am/cmaf/108000/108200/108210-039-B/220509185705/medias/108210-039-B_v216.m3u8 https://arte-cmafhls.akamaized.net/am/cmaf/108000/108200/108210-039-B/220509185705/medias/108210-039-B_v216.mp4 https://arte-cmafhls.akamaized.net/am/cmaf/108000/108200/108210-039-B/220509185705/medias/108210-039-B_aud_VA.m3u8 https://arte-cmafhls.akamaized.net/am/cmaf/108000/108200/108210-039-B/220509185705/medias/108210-039-B_aud_VA.mp4 https://arte-cmafhls.akamaized.net/am/cmaf/108000/108200/108210-039-B/220509185705/108210-039-B_VA_XQ.m3u8 Additional sources that helped me: For MP4: https://bitmovin.com/fun-with-container-formats-2/ For MPEGTS: https://bitmovin.com/fun-with-container-formats-3/ HLS RFC: https://datatracker.ietf.org/doc/html/rfc8216#section-3.3 ffmpeg MP4 options: https://ffmpeg.org/ffmpeg-formats.html#Options-2 Raw MP4 file browser: https://github.com/sannies/isoviewer -- Alexis Murzeau PGP: B7E6 0EBB 9293 7B06 BDBC 2787 E7BD 1904 F480 937F |
signature.asc
Description: OpenPGP digital signature

