Skip to main content

Add is_av1_video()

ID
c10935a
date
2025-11-28 22:26:20+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
e00fa6a
message
Add is_av1_video()
changed files
10 files, 52 additions, 2 deletions

Changed files

CHANGELOG.md (89) → CHANGELOG.md (302)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c1d71ba..53d933c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
 # CHANGELOG
 
+## v2 - 2025-11-28
+
+Add the `is_av1_video()` function for [detecting AV1-encoded videos](https://alexwlchan.net/2025/detecting-av1-videos/).
+
 ## v1 - 2025-11-28
 
-Initial release on PyPI, to test the release mechanism.
+Initial release. Included functions:
+
+* `date_matches_any_format`
+* `date_matches_format`
+* `find_all_dates`
+* `reformat_date`

README.md (1550) → README.md (1648)

diff --git a/README.md b/README.md
index 5570e53..bd785aa 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ This package has some functions I share across multiple archives/sites.
 I've written blog posts about some of the code in this repo:
 
 *   [Cleaning up messy dates in JSON](https://alexwlchan.net/2025/messy-dates-in-json/)
+*   [Detecting AV1-encoded videos with Python](https://alexwlchan.net/2025/detecting-av1-videos/)
 
 ## Versioning
 

dev_requirements.in (42) → dev_requirements.in (51)

diff --git a/dev_requirements.in b/dev_requirements.in
index 803a638..89cd3ee 100644
--- a/dev_requirements.in
+++ b/dev_requirements.in
@@ -1,4 +1,4 @@
--e file
+-e file:.[media]
 
 build
 mypy

dev_requirements.txt (1710) → dev_requirements.txt (1757)

diff --git a/dev_requirements.txt b/dev_requirements.txt
index 56279a8..d465a0c 100644
--- a/dev_requirements.txt
+++ b/dev_requirements.txt
@@ -58,6 +58,8 @@ pygments==2.19.2
     #   pytest
     #   readme-renderer
     #   rich
+pymediainfo==7.0.1
+    # via alexwlchan-chives
 pyproject-hooks==1.2.0
     # via build
 pytest==9.0.1

pyproject.toml (1200) → pyproject.toml (1257)

diff --git a/pyproject.toml b/pyproject.toml
index 43e2d49..6f6c945 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -23,6 +23,9 @@ dependencies = []
 dynamic = ["version"]
 license = "MIT"
 
+[project.optional-dependencies]
+media = ["pymediainfo"]
+
 [project.urls]
 "Homepage" = "https://github.com/alexwlchan/chives"
 "Changelog" = "https://github.com/alexwlchan/chives/blob/main/CHANGELOG.md"

src/chives/__init__.py (628) → src/chives/__init__.py (680)

diff --git a/src/chives/__init__.py b/src/chives/__init__.py
index 3ac12bf..80dea03 100644
--- a/src/chives/__init__.py
+++ b/src/chives/__init__.py
@@ -11,6 +11,7 @@ I share across multiple sites.
 
 """
 
+from .media import is_av1_video
 from .timestamps import (
     find_all_dates,
     date_matches_format,
@@ -24,5 +25,6 @@ __all__ = [
     "date_matches_any_format",
     "date_matches_format",
     "find_all_dates",
+    "is_av1_video",
     "reformat_date",
 ]

src/chives/media.py (0) → src/chives/media.py (441)

diff --git a/src/chives/media.py b/src/chives/media.py
new file mode 100644
index 0000000..5679dcf
--- /dev/null
+++ b/src/chives/media.py
@@ -0,0 +1,21 @@
+"""
+Functions for interacting with images/videos.
+
+References:
+* https://alexwlchan.net/2025/detecting-av1-videos/
+
+"""
+
+from pathlib import Path
+
+from pymediainfo import MediaInfo
+
+
+def is_av1_video(path: str | Path) -> bool:
+    """
+    Returns True if a video is encoded with AV1, False otherwise.
+    """
+    media_info = MediaInfo.parse(path)
+    video_codec: str = media_info.video_tracks[0].codec_id
+
+    return video_codec == "av01"

tests/fixtures/Sintel_360_10s_1MB_AV1.mp4 (0) → tests/fixtures/Sintel_360_10s_1MB_AV1.mp4 (1054253)

diff --git a/tests/fixtures/Sintel_360_10s_1MB_AV1.mp4 b/tests/fixtures/Sintel_360_10s_1MB_AV1.mp4
new file mode 100644
index 0000000..f42219e
Binary files /dev/null and b/tests/fixtures/Sintel_360_10s_1MB_AV1.mp4 differ

tests/fixtures/Sintel_360_10s_1MB_H264.mp4 (0) → tests/fixtures/Sintel_360_10s_1MB_H264.mp4 (1047614)

diff --git a/tests/fixtures/Sintel_360_10s_1MB_H264.mp4 b/tests/fixtures/Sintel_360_10s_1MB_H264.mp4
new file mode 100644
index 0000000..d1c7c31
Binary files /dev/null and b/tests/fixtures/Sintel_360_10s_1MB_H264.mp4 differ

tests/test_media.py (0) → tests/test_media.py (439)

diff --git a/tests/test_media.py b/tests/test_media.py
new file mode 100644
index 0000000..b624cf5
--- /dev/null
+++ b/tests/test_media.py
@@ -0,0 +1,12 @@
+"""Tests for `chives.media`."""
+
+from chives import is_av1_video
+
+
+def test_is_av1_video() -> None:
+    """is_av1_video correctly detects AV1 videos."""
+    # These two videos were downloaded from
+    # https://test-videos.co.uk/sintel/mp4-h264 and
+    # https://test-videos.co.uk/sintel/mp4-av1
+    assert not is_av1_video("tests/fixtures/Sintel_360_10s_1MB_H264.mp4")
+    assert is_av1_video("tests/fixtures/Sintel_360_10s_1MB_AV1.mp4")