Skip to content

fix(mp4): tkhd track flags and duration for QuickTime and ISO compliance#4

Open
x46085 wants to merge 1 commit intoMichael-A-Kuykendall:mainfrom
elodin-sys:fix/tkhd-quicktime-compat
Open

fix(mp4): tkhd track flags and duration for QuickTime and ISO compliance#4
x46085 wants to merge 1 commit intoMichael-A-Kuykendall:mainfrom
elodin-sys:fix/tkhd-quicktime-compat

Conversation

@x46085
Copy link

@x46085 x46085 commented Feb 7, 2026

Discovered and made in support of this feature: elodin-sys/elodin#467

  • Set tkhd flags to 0x000003 (track_enabled | track_in_movie) so QuickTime and other strict players show the track.
  • Fix tkhd box layout: use three u32 (duration, reserved, reserved) instead of two u64 for version 0, and write actual track duration in movie timescale.
  • Thread duration from sample tables through build_tkhd_box and build_audio_tkhd_box.

Description

  • QuickTime on macOS refuses to play MP4s produced by muxide because the tkhd (Track Header) box has flags == 0, so the track is not marked enabled or in-movie.
  • tkhd box layout: For version 0, the spec uses three u32 fields (duration, reserved, reserved). The current code writes two u64s, making the box 4 bytes too long and misaligning following fields (e.g. on some Linux players).
  • Duration: The track duration in tkhd is written as 0 instead of the actual duration in movie timescale.

Solution

  1. Set tkhd version+flags to 0x000003 (track_enabled | track_in_movie).
  2. Replace the two u64 writes with three u32 writes (duration, reserved, reserved) and add a duration: u32 parameter to build_tkhd_box_with_id.
  3. Compute track duration from sample tables (in movie timescale) and pass it through build_tkhd_box and build_audio_tkhd_box for both video and audio tracks.

Testing

  • cargo test passes.
  • MP4s muxed with this fix play in QuickTime on macOS and in VLC/ffplay on Linux; the same file previously failed in QuickTime only.

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🎨 Style/code quality improvement
  • 🔧 Refactoring (no functional changes)
  • 🧪 Tests (adding or updating tests)
  • 📦 Build/CI changes

Testing

  • Unit tests pass
  • Property tests pass
  • Integration tests pass
  • Manual testing completed

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Related Issues

Fixes #

- Set tkhd flags to 0x000003 (track_enabled | track_in_movie) so QuickTime
  and other strict players show the track.
- Fix tkhd box layout: use three u32 (duration, reserved, reserved) instead
  of two u64 for version 0, and write actual track duration in movie
  timescale.
- Thread duration from sample tables through build_tkhd_box and
  build_audio_tkhd_box.
@x46085
Copy link
Author

x46085 commented Feb 21, 2026

@Michael-A-Kuykendall ping

@Michael-A-Kuykendall
Copy link
Owner

I'll look; this project is open source not open contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants