Skip to content

feat(video): require PyAV during cv2 transition#2438

Merged
Borda merged 6 commits into
developfrom
cv2/6
Jul 16, 2026
Merged

feat(video): require PyAV during cv2 transition#2438
Borda merged 6 commits into
developfrom
cv2/6

Conversation

@Borda

@Borda Borda commented Jul 16, 2026

Copy link
Copy Markdown
Member

This pull request introduces a cv2-free PyAV fallback for video capture, writing, frame seeking, and audio remuxing, reducing the library's reliance on OpenCV and external tools like ffmpeg. The PyAV backend is now required as a dependency, and the fallback implementations are integrated transparently under the supervision._cv2 namespace. The audio remuxing logic has been refactored to use PyAV instead of shelling out to ffmpeg, improving portability and maintainability.

PyAV Video and Audio Backend Integration:

  • Added a cv2-free PyAV fallback for file-based video capture (_VideoCapture), writing (_VideoWriter), frame seeking, video property access, and audio remuxing, with OpenCV remaining the primary backend when available. ([[1]](https://github.com/roboflow/supervision/pull/2438/files#diff-1488ec0c236c0deac62c73250a5672fb103ce34d6e4658539e611ef2052f014cR1-R364), [[2]](https://github.com/roboflow/supervision/pull/2438/files#diff-86e4f932e0a4f2028060b775cb747808c89741df6a612664a14ad5a523310876R43-R47), [[3]](https://github.com/roboflow/supervision/pull/2438/files#diff-86e4f932e0a4f2028060b775cb747808c89741df6a612664a14ad5a523310876L188-R195), [[4]](https://github.com/roboflow/supervision/pull/2438/files#diff-77f023b99d3d58008351d3e82fc06e6d06ba1bc2da9e41be6329b7fa4f419f05R51-R55))
  • Introduced _video_writer_fourcc and codec mapping logic to enable OpenCV-style fourcc handling in the PyAV backend. ([[1]](https://github.com/roboflow/supervision/pull/2438/files#diff-1488ec0c236c0deac62c73250a5672fb103ce34d6e4658539e611ef2052f014cR1-R364), [[2]](https://github.com/roboflow/supervision/pull/2438/files#diff-86e4f932e0a4f2028060b775cb747808c89741df6a612664a14ad5a523310876R43-R47), [[3]](https://github.com/roboflow/supervision/pull/2438/files#diff-86e4f932e0a4f2028060b775cb747808c89741df6a612664a14ad5a523310876L188-R195))

Dependency Updates:

  • Added av>=14.2.0 as a required dependency in pyproject.toml to support the new PyAV backend. ([pyproject.tomlR50](https://github.com/roboflow/supervision/pull/2438/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711R50))

Audio Remuxing Refactor:

  • Replaced the ffmpeg-based _mux_audio implementation with a pure-PyAV version, removing the need for subprocess calls and temporary files managed via the shell. ([[1]](https://github.com/roboflow/supervision/pull/2438/files#diff-1488ec0c236c0deac62c73250a5672fb103ce34d6e4658539e611ef2052f014cR1-R364), [[2]](https://github.com/roboflow/supervision/pull/2438/files#diff-2c1d5a304749d86bda9d86102aabaa13e24c671bd4fc4eaa08cdde8969845fbbR17), [[3]](https://github.com/roboflow/supervision/pull/2438/files#diff-2c1d5a304749d86bda9d86102aabaa13e24c671bd4fc4eaa08cdde8969845fbbL173-L239))

Code Cleanup:

  • Removed unused imports and the _unavailable fallback from supervision._cv2.__init__.py and supervision/utils/video.py now that PyAV provides the fallback implementation. ([[1]](https://github.com/roboflow/supervision/pull/2438/files#diff-86e4f932e0a4f2028060b775cb747808c89741df6a612664a14ad5a523310876L6-R6), [[2]](https://github.com/roboflow/supervision/pull/2438/files#diff-2c1d5a304749d86bda9d86102aabaa13e24c671bd4fc4eaa08cdde8969845fbbL3-L6))

Documentation:

  • Updated the changelog to document the addition of the PyAV fallback and new dependency requirements. ([[1]](https://github.com/roboflow/supervision/pull/2438/files#diff-77f023b99d3d58008351d3e82fc06e6d06ba1bc2da9e41be6329b7fa4f419f05L3-R3), [[2]](https://github.com/roboflow/supervision/pull/2438/files#diff-77f023b99d3d58008351d3e82fc06e6d06ba1bc2da9e41be6329b7fa4f419f05R51-R55))

- Add the PyAV-backed file-video and audio fallback to the compatibility layer.
- Declare PyAV alongside OpenCV until the final dependency-removal integration.

---

Co-authored-by: Codex <codex@openai.com>
@socket-security

socket-security Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedav@​17.1.088100100100100
Addedav@​18.0.092100100100100

View full report

@socket-security

socket-security Bot commented Jul 16, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: pypi av is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: pyproject.tomlpypi/av@17.1.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore pypi/av@17.1.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.37037% with 88 lines in your changes missing coverage. Please review.
✅ Project coverage is 86%. Comparing base (c349613) to head (2c3fca0).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop   #2438    +/-   ##
========================================
- Coverage       86%     86%    -0%     
========================================
  Files           83      84     +1     
  Lines        11651   11890   +239     
========================================
+ Hits         10077   10261   +184     
- Misses        1574    1629    +55     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes PyAV a required dependency and introduces a PyAV-backed, OpenCV-shaped fallback under supervision._cv2 for file-based video capture/writing, seeking, and audio remuxing—replacing the previous ffmpeg-subprocess muxing path and reducing reliance on external executables.

Changes:

  • Added a PyAV backend (_VideoCapture, _VideoWriter, fourcc/codec mapping, and _mux_audio) under src/supervision/_cv2/_video.py, and wired it into supervision._cv2.
  • Switched process_video(preserve_audio=True) to use the PyAV _mux_audio implementation.
  • Made av>=14.2.0 a required dependency and documented the change in the changelog; added/updated tests accordingly.

Review scores (n/5):

  • Code quality: 3/5
  • Testing: 4/5
  • Docs: 4/5

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
uv.lock Locks PyAV (av) versions for the supported Python/platform matrix.
pyproject.toml Adds av>=14.2.0 as a required dependency.
src/supervision/_cv2/_video.py Introduces the PyAV-backed capture/writer and audio remuxing implementation.
src/supervision/_cv2/init.py Exposes the PyAV video surface through supervision._cv2 when OpenCV isn’t available.
src/supervision/utils/video.py Uses the new PyAV _mux_audio for preserve_audio flow.
tests/utils/test_video.py Removes ffmpeg-specific mux tests and keeps process-level mux invocation tests.
tests/cv2/test_video.py Adds coverage for PyAV fallback capture/writer, OpenCV-blocked execution, and mux behavior.
docs/changelog.md Documents the new PyAV fallback and dependency requirement.

Comment thread src/supervision/_cv2/_video.py
Comment thread src/supervision/_cv2/_video.py
Comment thread src/supervision/_cv2/_video.py Outdated
Comment thread tests/cv2/test_video.py
Borda and others added 4 commits July 16, 2026 19:33
…leanup

[resolve group] PR #2438 — items 2, 3

Reviewed by @Copilot.
- _VideoWriter now rejects is_color=False (NotImplementedError) instead of
  silently dropping it, since the PyAV fallback only encodes 3-channel frames.
- _mux_audio cleanup (container closes, temp-file removal) is now best-effort
  so a failing close/remove in finally can no longer mask the primary result
  or the original exception.

---
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
[resolve group] PR #2438 — item 4

Reviewed by @Copilot.
- The subprocess used to validate the cv2-free fallback had no timeout;
  a hang (import deadlock, codec probe stall) could block the whole CI
  run. Added a 60s timeout so a hang fails fast with a clear traceback
  instead of an opaque suite-wide stall.

---
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
---
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
[resolve] PR #2438 — Step 9 QA gate findings

QA review of the PyAV video-backend PR surfaced 2 blocking issues:
- process_video(preserve_audio=True) docstring still described the old
  ffmpeg-based muxing; audio remuxing was reimplemented with PyAV and no
  longer requires an external ffmpeg executable.
- get_video_frames_generator's documented webcam fallback
  (`_cv2.VideoCapture(0)`) silently fails under the PyAV backend: the
  BackendUnavailableError raised for integer sources was swallowed with no
  logging, so isOpened() just returns False with zero diagnostic signal.
  Doc note now states the limitation explicitly and the capture logs a
  warning instead of failing silently.

---
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
@Borda Borda merged commit 20b7c08 into develop Jul 16, 2026
26 checks passed
@Borda Borda deleted the cv2/6 branch July 16, 2026 18:13
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