Skip to content

v0.3.19

Choose a tag to compare

@styu12 styu12 released this 18 Apr 17:38
· 104 commits to main since this release

Fix OAK .h264 → .mp4 remux on PyAV ≥14

Field-reported on 0.3.18: the on-device H.264 encoder correctly delivered 30 fps on dual-OAK rigs, but the finalization step consistently failed, leaving the raw .h264 bitstream on disk instead of the expected .mp4. Two separate bugs were responsible.

Changes

  • PyAV API drift. output_container.add_stream(template=...) was removed in PyAV 14 in favour of a dedicated add_stream_from_template(template=...) method. 0.3.18 still called the old form, raising TypeError: add_stream() takes at least 1 positional argument (0 given). Now using the new method with a hasattr fallback so PyAV 12–13 users keep working.
  • Timestamp synthesis. Raw Annex-B has no PTS/DTS — every packet surfaces with dts=None. The previous code treated dts is None as an end-of-stream marker and skipped every real packet, so the output MP4 would have been empty even with the API call fixed. Real flush packets are detectable via size == 0 instead. The remux now synthesises a uniform 1/fps cadence at a ms-granularity timebase, matching ffmpeg -framerate N -i in.h264 -c copy out.mp4.

Added tests/integration/adapters/test_remux_h264_to_mp4.py that drives real PyAV + ffmpeg CLI to round-trip an Annex-B stream through the helper and verify the output is demuxable. The fake-av unit mock accepted any signature and so did not surface either regression — the new integration test closes the gap.

Recovering .h264 files from a 0.3.18 session

Raw bitstreams left behind by 0.3.18 are valid H.264 and can be repacked manually without re-encoding:

```bash
ffmpeg -framerate 30 -i oak_d.h264 -c copy oak_d.mp4
```

Upgrade

```bash
pip install --upgrade 'syncfield==0.3.19'
```