Files
unshackle/tests/tracks/test_mux_embedded_audio_metadata.py
T
imSp4rky 1036528fa3 fix(mux): address embedded audio by the file's real mkvmerge track IDs
A TS file can hold its audio first, which put the audio name on the video.
2026-10-24 12:45:25 -06:00

96 lines
3.7 KiB
Python

import json
from types import SimpleNamespace
import pytest
from unshackle.core import binaries
from unshackle.core.tracks import Tracks, Video
from unshackle.core.tracks.tracks import file_track_ids
def make_video(track_id: str, **data) -> Video:
video = Video(
id_=track_id,
url=f"https://example.test/{track_id}.m3u8",
language="zh",
codec=Video.Codec.AVC,
range_=Video.Range.SDR,
width=1920,
height=1080,
bitrate=5_000_000,
)
video.data.update(data)
return video
def downloaded(video: Video, tmp_path) -> Video:
video.path = tmp_path / "v.ts"
video.path.write_bytes(b"\x00" * 16)
return video
def mux_until_mkvmerge_check(tracks: Tracks) -> None:
# the embedded-audio metadata pass runs before the mkvmerge lookup, so a missing
# binary stops the mux right after the state under test has been written
with pytest.raises(RuntimeError, match="MKVToolNix"):
tracks.mux("Test Title")
def test_names_undeclared_video(monkeypatch):
monkeypatch.setattr(binaries, "MKVToolNix", None)
video = make_video("v1")
tracks = Tracks(video)
mux_until_mkvmerge_check(tracks)
assert video.needs_repack
assert video.data["audio_language"] == "zh"
assert video.embedded_audio_name() == "Chinese"
def test_service_declaration_is_preserved(monkeypatch):
monkeypatch.setattr(binaries, "MKVToolNix", None)
declared = make_video("v1", audio_language="th", audio_language_name="Thai [Original]")
undeclared = make_video("v2")
tracks = Tracks([declared, undeclared])
mux_until_mkvmerge_check(tracks)
assert declared.data["audio_language"] == "th"
assert declared.data["audio_language_name"] == "Thai [Original]"
assert not declared.needs_repack
assert undeclared.data["audio_language"] == "zh"
def test_embedded_audio_without_a_name_gets_the_language_name(tmp_path, mux_args):
args = mux_args(Tracks(downloaded(make_video("v1", audio_language="pt-BR"), tmp_path)), {"video": 0, "audio": 1})
assert args[args.index("--track-name") + 1] == "1:Portuguese"
def test_embedded_audio_options_use_the_file_track_ids(tmp_path, mux_args):
video = make_video("v1", audio_language="ko", audio_language_name="Korean")
args = mux_args(Tracks(downloaded(video, tmp_path)), {"audio": 0, "video": 1})
assert args[args.index("--track-name") + 1] == "0:Korean"
original = f"{video.is_original_lang}"
assert [args[i + 1] for i, arg in enumerate(args) if arg == "--original-flag"] == [f"1:{original}", f"0:{original}"]
assert "0:ko" in args and "1:zh" in args
def test_embedded_audio_options_are_left_out_when_the_file_has_no_audio(tmp_path, mux_args):
args = mux_args(Tracks(downloaded(make_video("v1", audio_language="ko"), tmp_path)), {"video": 0})
assert "--track-name" not in args
def test_repack_and_mux_share_the_embedded_audio_name():
assert make_video("v1", audio_language="zh").embedded_audio_name() == "Chinese"
assert make_video("v1", audio_language="zh", audio_language_name="Mandarin").embedded_audio_name() == "Mandarin"
def test_file_track_ids_reads_the_first_id_of_each_type(monkeypatch, tmp_path):
tracks = [{"id": 0, "type": "audio"}, {"id": 1, "type": "video"}, {"id": 2, "type": "audio"}]
reply = SimpleNamespace(stdout=json.dumps({"tracks": tracks}))
monkeypatch.setattr("unshackle.core.tracks.tracks.subprocess.run", lambda *a, **k: reply)
assert file_track_ids(tmp_path / "v.ts") == {"audio": 0, "video": 1}
monkeypatch.setattr("unshackle.core.tracks.tracks.subprocess.run", lambda *a, **k: SimpleNamespace(stdout=""))
assert file_track_ids(tmp_path / "v.ts") == {"video": 0, "audio": 1}