feat(subtitle): support 'original' sub_format to keep source format

This commit is contained in:
imSp4rky
2026-06-07 22:35:49 -06:00
parent 29232925d5
commit 79b884fb6b
3 changed files with 43 additions and 3 deletions

View File

@@ -0,0 +1,33 @@
"""Tests for SubtitleCodecChoice — notably the ``original`` keep-source sentinel that
services set via the ``sub_format`` override (must not be rejected as an invalid codec)."""
from __future__ import annotations
import pytest
from unshackle.core.tracks.subtitle import Subtitle
from unshackle.core.utils.click_types import SubtitleCodecChoice
choice = SubtitleCodecChoice(Subtitle.Codec)
@pytest.mark.parametrize("value", ["original", "ORIGINAL", "Original"])
def test_original_is_kept_as_sentinel(value):
assert choice.convert(value) == "original"
@pytest.mark.parametrize(
"value,expected",
[
("srt", Subtitle.Codec.SubRip),
("ass", Subtitle.Codec.SubStationAlphav4),
("vtt", Subtitle.Codec.WebVTT),
("WVTT", Subtitle.Codec.fVTT),
],
)
def test_codecs_still_map(value, expected):
assert choice.convert(value) == expected
def test_empty_is_none():
assert choice.convert(None) is None

View File

@@ -20,7 +20,7 @@ from http.cookiejar import CookieJar, MozillaCookieJar
from itertools import product from itertools import product
from pathlib import Path from pathlib import Path
from threading import Lock from threading import Lock
from typing import Any, Callable, Optional, TypedDict from typing import Any, Callable, Optional, TypedDict, Union
from uuid import UUID from uuid import UUID
import click import click
@@ -521,7 +521,7 @@ class dl:
"--sub-format", "--sub-format",
type=SubtitleCodecChoice(Subtitle.Codec), type=SubtitleCodecChoice(Subtitle.Codec),
default=None, default=None,
help="Set Output Subtitle Format, only converting if necessary.", help="Set Output Subtitle Format, only converting if necessary. Use 'original' to keep source format.",
) )
@click.option("-V", "--video-only", is_flag=True, default=False, help="Only download video tracks.") @click.option("-V", "--video-only", is_flag=True, default=False, help="Only download video tracks.")
@click.option("-A", "--audio-only", is_flag=True, default=False, help="Only download audio tracks.") @click.option("-A", "--audio-only", is_flag=True, default=False, help="Only download audio tracks.")
@@ -1110,7 +1110,7 @@ class dl:
require_subs: list[str], require_subs: list[str],
forced_subs: bool, forced_subs: bool,
exact_lang: bool, exact_lang: bool,
sub_format: Optional[Subtitle.Codec], sub_format: Optional[Union[Subtitle.Codec, str]],
video_only: bool, video_only: bool,
audio_only: bool, audio_only: bool,
subs_only: bool, subs_only: bool,
@@ -2369,6 +2369,8 @@ class dl:
with console.status("Converting Subtitles..."): with console.status("Converting Subtitles..."):
for subtitle in title.tracks.subtitles: for subtitle in title.tracks.subtitles:
if sub_format == "original":
continue
if sub_format: if sub_format:
if subtitle.codec != sub_format: if subtitle.codec != sub_format:
subtitle.convert(sub_format, forced=True) subtitle.convert(sub_format, forced=True)

View File

@@ -131,6 +131,8 @@ class SubtitleCodecChoice(click.Choice):
if value_lower not in choices: if value_lower not in choices:
choices.append(value_lower) choices.append(value_lower)
choices.append("original")
self.aliases = aliases self.aliases = aliases
super().__init__(choices, case_sensitive=False) super().__init__(choices, case_sensitive=False)
@@ -138,6 +140,9 @@ class SubtitleCodecChoice(click.Choice):
if not value: if not value:
return None return None
if str(value).lower() == "original":
return "original"
# First try to convert using the parent class # First try to convert using the parent class
converted_value = super().convert(value, param, ctx) converted_value = super().convert(value, param, ctx)