Removing a lot of sys.exit inside cutting module.

This commit is contained in:
Frédéric Tronel
2026-08-31 08:34:52 +02:00
parent d756fede54
commit 1a616f6cbd
3 changed files with 35 additions and 35 deletions
+13 -21
View File
@@ -18,7 +18,7 @@ import hexdump
from tqdm import tqdm from tqdm import tqdm
from typeguard import typechecked from typeguard import typechecked
from tscut.exceptions import InvalidMediaError from tscut.exceptions import InvalidMediaError, TemporaryFileError
from tscut.h264.avc import get_avc_config_from_h264 from tscut.h264.avc import get_avc_config_from_h264
from tscut.matroska.codec import dump_codec_private_data from tscut.matroska.codec import dump_codec_private_data
from tscut.models import CutResult, PreparedMedia, ProcessingOptions from tscut.models import CutResult, PreparedMedia, ProcessingOptions
@@ -82,8 +82,7 @@ def concatenate_h264_ts_parts(h264_ts_parts: Sequence[TextIO], output: TextIO) -
logger.debug('Parsing file: %s. Offset=%d', part, offset) logger.debug('Parsing file: %s. Offset=%d', part, offset)
isheader = part.readline() isheader = part.readline()
if (not isheader) or (isheader != header): if (not isheader) or (isheader != header):
logger.error('Impossible to find a valid header: "%s"', isheader) raise InvalidMediaError(f"Impossible to find a valid header: {isheader}")
exit(-1)
while True: while True:
line = part.readline() line = part.readline()
if not line: if not line:
@@ -128,14 +127,14 @@ def cut_recording(media: PreparedMedia, options: ProcessingOptions,
head_frames = get_nearest_iframe(options.tools_paths['ffprobe'], media.movie, ts1, head_frames = get_nearest_iframe(options.tools_paths['ffprobe'], media.movie, ts1,
before=False) before=False)
if head_frames is None: if head_frames is None:
raise InvalidMediaError("Impossible to retrieve first I-frame") raise InvalidMediaError(f"Impossible to retrieve first I-frame")
# Get the nearest I-frame whose timestamp ... # Get the nearest I-frame whose timestamp ...
# TODO: wrong here ... # TODO: wrong here ...
tail_frames = get_nearest_iframe(options.tools_paths['ffprobe'], media.movie, tail_frames = get_nearest_iframe(options.tools_paths['ffprobe'], media.movie,
ts2, before=True) ts2, before=True)
if tail_frames is None: if tail_frames is None:
raise InvalidMediaError("Impossible to retrieve last I-frame") raise InvalidMediaError(f"Impossible to retrieve last I-frame")
nb_head_frames, head_iframe = head_frames nb_head_frames, head_iframe = head_frames
nb_tail_frames, tail_iframe = tail_frames nb_tail_frames, tail_iframe = tail_frames
@@ -147,10 +146,10 @@ def cut_recording(media: PreparedMedia, options: ProcessingOptions,
head_iframe_ts = get_ts_frame(head_iframe) head_iframe_ts = get_ts_frame(head_iframe)
if head_iframe_ts is None: if head_iframe_ts is None:
raise InvalidMediaError("Impossible to retrieve timestamp of first i-frame.") raise InvalidMediaError(f"Impossible to retrieve timestamp of first i-frame.")
tail_iframe_ts = get_ts_frame(tail_iframe) tail_iframe_ts = get_ts_frame(tail_iframe)
if tail_iframe_ts is None: if tail_iframe_ts is None:
raise InvalidMediaError("Impossible to retrieve timestamp of final i-frame.") raise InvalidMediaError(f"Impossible to retrieve timestamp of final i-frame.")
checks.append(pos+head_iframe_ts-ts1) checks.append(pos+head_iframe_ts-ts1)
@@ -211,26 +210,22 @@ def cut_recording(media: PreparedMedia, options: ProcessingOptions,
try: try:
internal_mkv = open(internal_mkv_name, 'wb+') internal_mkv = open(internal_mkv_name, 'wb+')
except OSError: except OSError:
logger.error('Impossible to create file: %s', internal_mkv_name) raise TemporaryFileError(f"Impossible to create file: {internal_mkv_name}")
exit(-1)
try: try:
internal_novideo_mkv = open(internal_novideo_mkv_name, 'wb+') internal_novideo_mkv = open(internal_novideo_mkv_name, 'wb+')
except OSError: except OSError:
logger.error('Impossible to create file: %s', internal_novideo_mkv_name) raise TemporaryFileError(f"Impossible to create file: {internal_novideo_mkv_name}")
exit(-1)
try: try:
internal_h264 = open(internal_h264_name, 'wb+') internal_h264 = open(internal_h264_name, 'wb+')
except OSError: except OSError:
logger.error('Impossible to create file: %s', internal_h264_name) raise TemporaryFileError(f"Impossible to create file: {internal_h264_name}")
exit(-1)
try: try:
internal_h264_ts = open(internal_h264_ts_name, 'w+', encoding='utf8') internal_h264_ts = open(internal_h264_ts_name, 'w+', encoding='utf8')
except OSError: except OSError:
logger.error('Impossible to create file: %s', internal_h264_ts_name) raise TemporaryFileError(f"Impossible to create file: {internal_h264_ts_name}")
exit(-1)
# logger.info('Merge header, middle and trailer subpart into: %s' % internal_mkv_name) # logger.info('Merge header, middle and trailer subpart into: %s' % internal_mkv_name)
# Extract internal part of MKV # Extract internal part of MKV
@@ -302,8 +297,7 @@ def cut_recording(media: PreparedMedia, options: ProcessingOptions,
try: try:
full_h264 = open(f'{media.basename}-full.h264', 'wb+') full_h264 = open(f'{media.basename}-full.h264', 'wb+')
except OSError: except OSError:
logger.error('Impossible to create file full H264 stream.') raise TemporaryFileError(f"Impossible to create file full H264 stream.")
exit(-1)
logger.info('Merging all H264 tracks') logger.info('Merging all H264 tracks')
concatenate_h264_parts(h264parts=h264parts, output=full_h264) concatenate_h264_parts(h264parts=h264parts, output=full_h264)
@@ -312,8 +306,7 @@ def cut_recording(media: PreparedMedia, options: ProcessingOptions,
try: try:
full_h264_ts = open(f'{media.basename}-ts.txt', 'w+', encoding='utf8') full_h264_ts = open(f'{media.basename}-ts.txt', 'w+', encoding='utf8')
except OSError: except OSError:
logger.error('Impossible to create file containing all video timestamps.') raise TemporaryFileError(f"Impossible to create file containing all video timestamps.")
exit(-1)
logger.info('Merging H264 timestamps') logger.info('Merging H264 timestamps')
concatenate_h264_ts_parts(h264_ts_parts=h264_ts, output=full_h264_ts) concatenate_h264_ts_parts(h264_ts_parts=h264_ts, output=full_h264_ts)
@@ -336,8 +329,7 @@ def cut_recording(media: PreparedMedia, options: ProcessingOptions,
try: try:
final_novideo = open(final_novideo_name, 'rb') final_novideo = open(final_novideo_name, 'rb')
except OSError: except OSError:
logger.error('Impossible to open file: %s.', final_novideo_name) raise TemporaryFileError(f"Impossible to open file: {final_novideo_name}")
exit(-1)
temporaries.append(final_novideo) temporaries.append(final_novideo)
+3 -1
View File
@@ -14,9 +14,11 @@ class MissingToolError(TSCutError):
class ExternalToolError(TSCutError): class ExternalToolError(TSCutError):
"""Raised when an external tool fails.""" """Raised when an external tool fails."""
class InvalidMediaError(TSCutError): class InvalidMediaError(TSCutError):
"""Raised when input media cannot be processed.""" """Raised when input media cannot be processed."""
class TemporaryFileError(TSCutError):
"""Raised when the manipulation of temporary file goes wrong"""
class UnimplementedFeatureError(TSCutError): class UnimplementedFeatureError(TSCutError):
"""Raised when a rare feature is encountered and not yet implemented""" """Raised when a rare feature is encountered and not yet implemented"""
+19 -13
View File
@@ -13,6 +13,7 @@ from typing import IO, Any, BinaryIO
import hexdump import hexdump
from tscut.cutting import cut_recording from tscut.cutting import cut_recording
from tscut.exceptions import InvalidMediaError
from tscut.h264.avc import parse_codec_private from tscut.h264.avc import parse_codec_private
from tscut.matroska.codec import dump_codec_private_data from tscut.matroska.codec import dump_codec_private_data
from tscut.models import PreparedMedia, ProcessingOptions, SupportedFormat from tscut.models import PreparedMedia, ProcessingOptions, SupportedFormat
@@ -32,6 +33,16 @@ from tscut.tools.mkvtoolnix import (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def detect_supported_format(format_name: str) -> SupportedFormat:
for media_format in SupportedFormat:
if format_name == str(media_format):
return media_format
raise InvalidMediaError(
f"Unsupported media format: {format_name}"
)
def process_recording(options: ProcessingOptions) -> None: def process_recording(options: ProcessingOptions) -> None:
nb_parts = len(options.parts) nb_parts = len(options.parts)
temporaries : list[IO[Any]] = [] temporaries : list[IO[Any]] = []
@@ -50,7 +61,12 @@ def process_recording(options: ProcessingOptions) -> None:
format_of_file = get_format(options.tools_paths['ffprobe'], input_file) format_of_file = get_format(options.tools_paths['ffprobe'], input_file)
if format_of_file is None: if format_of_file is None:
exit(-1) raise InvalidMediaError(f"Impossible to retrieve format of file: {input_file}")
if 'format_name' not in format_of_file:
raise InvalidMediaError(f"Impossible to retrieve format of file: {input_file}")
if 'duration' not in format_of_file:
raise InvalidMediaError(f"Impossible to retrieve duration of file: {input_file}")
format_name = format_of_file['format_name']
duration = timedelta(seconds=float(format_of_file['duration'])) duration = timedelta(seconds=float(format_of_file['duration']))
logger.info("Durée de l'enregistrement: %s", duration) logger.info("Durée de l'enregistrement: %s", duration)
@@ -58,23 +74,13 @@ def process_recording(options: ProcessingOptions) -> None:
if options.framerate is None: if options.framerate is None:
framerate = get_frame_rate(options.tools_paths['ffprobe'], input_file) framerate = get_frame_rate(options.tools_paths['ffprobe'], input_file)
if framerate is None: if framerate is None:
logger.error('Impossible to estimate frame rate !') raise InvalidMediaError('Impossible to estimate frame rate !')
exit(-1)
else: else:
framerate = options.framerate framerate = options.framerate
logger.info('Frame rate: %.1f fps', framerate) logger.info('Frame rate: %.1f fps', framerate)
found = False final_format_of_file = detect_supported_format(format_name)
for f in SupportedFormat:
if 'format_name' in format_of_file:
if format_of_file['format_name'] == str(f):
found = True
final_format_of_file = f
break
if not found:
logger.error('Unsupported format of file')
mkv: BinaryIO mkv: BinaryIO