From 1428edfb8bde0abfd3882dfe2e27e3ca872795e8 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Tue, 5 Mar 2024 17:21:42 -0500 Subject: [PATCH] Updated fese module to latest version to fix embedded subtitles provider. #2423 --- libs/fese-0.2.7.dist-info/RECORD | 13 ---- .../INSTALLER | 0 .../LICENSE | 0 .../METADATA | 2 +- libs/fese-0.2.9.dist-info/RECORD | 13 ++++ .../REQUESTED | 0 .../WHEEL | 0 .../top_level.txt | 0 libs/fese/__init__.py | 2 +- libs/fese/container.py | 67 +++++++++++++++++-- libs/fese/disposition.py | 4 +- libs/version.txt | 2 +- 12 files changed, 81 insertions(+), 22 deletions(-) delete mode 100644 libs/fese-0.2.7.dist-info/RECORD rename libs/{fese-0.2.7.dist-info => fese-0.2.9.dist-info}/INSTALLER (100%) rename libs/{fese-0.2.7.dist-info => fese-0.2.9.dist-info}/LICENSE (100%) rename libs/{fese-0.2.7.dist-info => fese-0.2.9.dist-info}/METADATA (97%) create mode 100644 libs/fese-0.2.9.dist-info/RECORD rename libs/{fese-0.2.7.dist-info => fese-0.2.9.dist-info}/REQUESTED (100%) rename libs/{fese-0.2.7.dist-info => fese-0.2.9.dist-info}/WHEEL (100%) rename libs/{fese-0.2.7.dist-info => fese-0.2.9.dist-info}/top_level.txt (100%) diff --git a/libs/fese-0.2.7.dist-info/RECORD b/libs/fese-0.2.7.dist-info/RECORD deleted file mode 100644 index 85252222a..000000000 --- a/libs/fese-0.2.7.dist-info/RECORD +++ /dev/null @@ -1,13 +0,0 @@ -fese-0.2.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -fese-0.2.7.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149 -fese-0.2.7.dist-info/METADATA,sha256=ZhkaLWdzqGU8X7sO3kLkpI5YsoeEoMtrbbqkxO4Tnvo,655 -fese-0.2.7.dist-info/RECORD,, -fese-0.2.7.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -fese-0.2.7.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92 -fese-0.2.7.dist-info/top_level.txt,sha256=ra2BuARVEUZpk76YpHnjVoqjR2FxvzhCdmW2OyBWGzE,5 -fese/__init__.py,sha256=3glaq0hsVZWG-ADCl2tW5z3T0NQJYsyHBIG-uscr70M,150 -fese/container.py,sha256=ztQxukjMOjEVQFqTQG9IVLYXkBhn8KhUZ_37E3W1PS4,8140 -fese/disposition.py,sha256=mtYjMCm1uwudWbjVo-8CEMp5UkVb75jEoCXEfqqWBMk,2116 -fese/exceptions.py,sha256=VZaubpq8SPpkUGp28Ryebsf9YzqbKK62nni6YZgDPYI,372 -fese/stream.py,sha256=Hgf6-amksHpuhSoY6SL6C3q4YtGCuRHl4fusBWE9nBE,4866 -fese/tags.py,sha256=qKkcjJmCKgnXIbZ9x-nngCNYAfv5cbJZ4A6EP0ckZME,5454 diff --git a/libs/fese-0.2.7.dist-info/INSTALLER b/libs/fese-0.2.9.dist-info/INSTALLER similarity index 100% rename from libs/fese-0.2.7.dist-info/INSTALLER rename to libs/fese-0.2.9.dist-info/INSTALLER diff --git a/libs/fese-0.2.7.dist-info/LICENSE b/libs/fese-0.2.9.dist-info/LICENSE similarity index 100% rename from libs/fese-0.2.7.dist-info/LICENSE rename to libs/fese-0.2.9.dist-info/LICENSE diff --git a/libs/fese-0.2.7.dist-info/METADATA b/libs/fese-0.2.9.dist-info/METADATA similarity index 97% rename from libs/fese-0.2.7.dist-info/METADATA rename to libs/fese-0.2.9.dist-info/METADATA index a999d8fe2..85f1cd160 100644 --- a/libs/fese-0.2.7.dist-info/METADATA +++ b/libs/fese-0.2.9.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: fese -Version: 0.2.7 +Version: 0.2.9 Summary: A library to extract FFmpeg subtitle streams Author-email: Vitiko Nogales Requires-Python: >=3.7 diff --git a/libs/fese-0.2.9.dist-info/RECORD b/libs/fese-0.2.9.dist-info/RECORD new file mode 100644 index 000000000..e30fae26a --- /dev/null +++ b/libs/fese-0.2.9.dist-info/RECORD @@ -0,0 +1,13 @@ +fese-0.2.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +fese-0.2.9.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149 +fese-0.2.9.dist-info/METADATA,sha256=nJz9q6FwX7fqmsO3jgM0ZgV0gsCeILWoxVRUqCbJkFI,655 +fese-0.2.9.dist-info/RECORD,, +fese-0.2.9.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +fese-0.2.9.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92 +fese-0.2.9.dist-info/top_level.txt,sha256=ra2BuARVEUZpk76YpHnjVoqjR2FxvzhCdmW2OyBWGzE,5 +fese/__init__.py,sha256=_YUpx7sq26ioEp5LZOEKa-0MrRHQUuRuDCs0EQ6Amv4,150 +fese/container.py,sha256=sLuxP0vlba4iGVohGfYtd-QcjQ-YxMU6lqMOM-Wtqlc,10340 +fese/disposition.py,sha256=hv4YmXpsvKmUdpeWvSrZkhKgtZLZ8t56dmwMddsqxus,2156 +fese/exceptions.py,sha256=VZaubpq8SPpkUGp28Ryebsf9YzqbKK62nni6YZgDPYI,372 +fese/stream.py,sha256=Hgf6-amksHpuhSoY6SL6C3q4YtGCuRHl4fusBWE9nBE,4866 +fese/tags.py,sha256=qKkcjJmCKgnXIbZ9x-nngCNYAfv5cbJZ4A6EP0ckZME,5454 diff --git a/libs/fese-0.2.7.dist-info/REQUESTED b/libs/fese-0.2.9.dist-info/REQUESTED similarity index 100% rename from libs/fese-0.2.7.dist-info/REQUESTED rename to libs/fese-0.2.9.dist-info/REQUESTED diff --git a/libs/fese-0.2.7.dist-info/WHEEL b/libs/fese-0.2.9.dist-info/WHEEL similarity index 100% rename from libs/fese-0.2.7.dist-info/WHEEL rename to libs/fese-0.2.9.dist-info/WHEEL diff --git a/libs/fese-0.2.7.dist-info/top_level.txt b/libs/fese-0.2.9.dist-info/top_level.txt similarity index 100% rename from libs/fese-0.2.7.dist-info/top_level.txt rename to libs/fese-0.2.9.dist-info/top_level.txt diff --git a/libs/fese/__init__.py b/libs/fese/__init__.py index 8a94470ce..4b0020107 100644 --- a/libs/fese/__init__.py +++ b/libs/fese/__init__.py @@ -4,4 +4,4 @@ from .container import FFprobeVideoContainer from .stream import FFprobeSubtitleStream -__version__ = "0.2.7" +__version__ = "0.2.9" diff --git a/libs/fese/container.py b/libs/fese/container.py index d65aee17f..21dfc20da 100644 --- a/libs/fese/container.py +++ b/libs/fese/container.py @@ -6,7 +6,9 @@ from __future__ import annotations import json import logging import os +import re import subprocess +import time from .exceptions import ExtractionError from .exceptions import InvalidSource @@ -23,6 +25,45 @@ FFMPEG_PATH = os.environ.get("FFMPEG_PATH", "ffmpeg") FFMPEG_STATS = True FF_LOG_LEVEL = "quiet" +_PROGRESS_RE = re.compile( + r"size=\s*(\d+\w*B|N/A)\s+time=(\d+:\d+:\d+\.\d+)\s+bitrate=\s*([\d\.]+(?:e[\+\-]?\d+)?\w*bits/s|N/A)\s+speed=([\d\.]+(?:e[\+\-]?\d+)?x|N/A)" +) + + +def _ffmpeg_call(command, log_callback=None, progress_callback=None, timeout=10000): + proc = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + ) + log_callback = log_callback or logger.debug + + start = time.time() + + while True: + line = proc.stderr.readline() + if not line: + break + + if line: + log_callback("ffmpeg: %s", line.strip()) + + if progress_callback is not None: + match = _PROGRESS_RE.search(line) + if match: + size, time_, bitrate, speed = match.groups() + info = {"size": size, "time": time_, "bitrate": bitrate, "speed": speed} + progress_callback(info) + + if timeout is not None and time.time() - start > timeout: + proc.kill() + raise subprocess.TimeoutExpired(command, timeout) + + return_code = proc.wait() + if return_code != 0: + raise subprocess.CalledProcessError(return_code, command) + class FFprobeVideoContainer: def __init__(self, path: str): @@ -81,6 +122,8 @@ class FFprobeVideoContainer: overwrite=True, timeout=600, convert_format=None, + basename_callback=None, + progress_callback=None, ): """Extracts a list of subtitles converting them. Returns a dictionary of the extracted filenames by index. @@ -95,6 +138,9 @@ class FFprobeVideoContainer: :param timeout: subprocess timeout in seconds (default: 600) :param convert_format: format to convert selected subtitles. Defaults to srt + :param basename_callback: a callback that takes the filename path. Only used if + custom_dir is set. Defaults to `os.path.basename` + :progress_callback: a callback that takes a dict :raises: ExtractionError, UnsupportedCodec, OSError """ extract_command = [FFMPEG_PATH, "-v", FF_LOG_LEVEL] @@ -116,7 +162,8 @@ class FFprobeVideoContainer: f"{os.path.splitext(self.path)[0]}.{subtitle.suffix}.{extension_to_use}" ) if custom_dir is not None: - sub_path = os.path.join(custom_dir, os.path.basename(sub_path)) + basename_callback = basename_callback or os.path.basename + sub_path = os.path.join(custom_dir, basename_callback(sub_path)) if not overwrite and sub_path in collected_paths: sub_path = f"{os.path.splitext(sub_path)[0]}.{len(collected_paths):02}.{extension_to_use}" @@ -139,7 +186,10 @@ class FFprobeVideoContainer: logger.debug("Extracting subtitle with command %s", " ".join(extract_command)) try: - subprocess.run(extract_command, timeout=timeout, check=True) + # subprocess.run(extract_command, timeout=timeout, check=True) + _ffmpeg_call( + extract_command, timeout=timeout, progress_callback=progress_callback + ) except (subprocess.SubprocessError, FileNotFoundError) as error: raise ExtractionError(f"Error calling ffmpeg: {error}") from error @@ -156,6 +206,8 @@ class FFprobeVideoContainer: overwrite=True, timeout=600, fallback_to_convert=True, + basename_callback=None, + progress_callback=None, ): """Extracts a list of subtitles with ffmpeg's copy method. Returns a dictionary of the extracted filenames by index. @@ -167,6 +219,9 @@ class FFprobeVideoContainer: :param timeout: subprocess timeout in seconds (default: 600) :param fallback_to_convert: fallback to stream's default convert format if it is incompatible with copy + :param basename_callback: a callback that takes the filename path. Only used if + custom_dir is set. Defaults to `os.path.basename` + :progress_callback: a callback that takes a dict :raises: ExtractionError, UnsupportedCodec, OSError """ extract_command = [FFMPEG_PATH, "-v", FF_LOG_LEVEL] @@ -184,7 +239,8 @@ class FFprobeVideoContainer: for subtitle in subtitles: sub_path = f"{os.path.splitext(self.path)[0]}.{subtitle.suffix}.{subtitle.extension}" if custom_dir is not None: - sub_path = os.path.join(custom_dir, os.path.basename(sub_path)) + basename_callback = basename_callback or os.path.basename + sub_path = os.path.join(custom_dir, basename_callback(sub_path)) if not overwrite and sub_path in collected_paths: sub_path = f"{os.path.splitext(sub_path)[0]}.{len(collected_paths):02}.{subtitle.extension}" @@ -216,7 +272,10 @@ class FFprobeVideoContainer: logger.debug("Extracting subtitle with command %s", " ".join(extract_command)) try: - subprocess.run(extract_command, timeout=timeout, check=True) + # subprocess.run(extract_command, timeout=timeout, check=True) + _ffmpeg_call( + extract_command, timeout=timeout, progress_callback=progress_callback + ) except (subprocess.SubprocessError, FileNotFoundError) as error: raise ExtractionError(f"Error calling ffmpeg: {error}") from error diff --git a/libs/fese/disposition.py b/libs/fese/disposition.py index 8b72323cc..66823aac8 100644 --- a/libs/fese/disposition.py +++ b/libs/fese/disposition.py @@ -57,8 +57,8 @@ class FFprobeSubtitleDisposition: def language_kwargs(self): return { - "hi": self._content_type == "hearing_impaired", - "forced": self._content_type == "forced", + "hi": self._content_type == "hearing_impaired" or self.hearing_impaired, + "forced": self._content_type == "forced" or self.forced, } def __str__(self): diff --git a/libs/version.txt b/libs/version.txt index 15e8a7e0d..966f61590 100644 --- a/libs/version.txt +++ b/libs/version.txt @@ -10,7 +10,7 @@ charset-normalizer==3.3.2 deep-translator==1.11.4 dogpile.cache==1.3.2 dynaconf==3.2.4 -fese==0.2.7 +fese==0.2.9 ffsubsync==0.4.25 flask-cors==4.0.0 flask-migrate==4.0.5