Linting and typing fixes.
This commit is contained in:
+20
-42
@@ -3,31 +3,24 @@
|
||||
# Copyright (C) 2026 Frédéric Tronel
|
||||
|
||||
import logging
|
||||
from math import floor, ceil, log
|
||||
from datetime import timedelta
|
||||
from os import (
|
||||
read,
|
||||
SEEK_SET,
|
||||
lseek,
|
||||
memfd_create,
|
||||
set_inheritable,
|
||||
write,
|
||||
close
|
||||
)
|
||||
from typing import IO
|
||||
from subprocess import PIPE, Popen
|
||||
from io import TextIOWrapper
|
||||
from math import ceil, floor, log
|
||||
from os import SEEK_SET, close, lseek, memfd_create, read, set_inheritable, write
|
||||
from subprocess import PIPE, Popen
|
||||
from typing import IO
|
||||
|
||||
from typeguard import typechecked
|
||||
from tqdm import tqdm
|
||||
from typeguard import typechecked
|
||||
|
||||
from tscut.exceptions import ExternalToolError, InvalidMediaError
|
||||
from tscut.tools.ffprobe import (
|
||||
get_frames_in_stream,
|
||||
get_video_dimensions,
|
||||
with_subtitles,
|
||||
get_frames_in_stream,
|
||||
)
|
||||
from tscut.tools.ppm import dump_ppm
|
||||
from tscut.tools.timeframe import parse_timestamp, get_packet_duration
|
||||
from tscut.tools.timeframe import get_packet_duration, parse_timestamp
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -46,10 +39,7 @@ def ffmpeg_convert(ffmpeg_path:str, ffprobe_path:str, input_file: IO[bytes], inp
|
||||
set_inheritable(infd, True)
|
||||
set_inheritable(outfd, True)
|
||||
|
||||
if logger.getEffectiveLevel() == logging.DEBUG:
|
||||
log_level = []
|
||||
else:
|
||||
log_level = [ '-loglevel', 'quiet' ]
|
||||
log_level = [] if logger.getEffectiveLevel() == logging.DEBUG else ['-loglevel', 'quiet']
|
||||
|
||||
params = [ffmpeg_path, '-y',]+log_level+['-progress', '/dev/stdout', '-canvas_size',
|
||||
f'{width:d}x{height:d}', '-f', input_format,
|
||||
@@ -82,7 +72,7 @@ def ffmpeg_convert(ffmpeg_path:str, ffprobe_path:str, input_file: IO[bytes], inp
|
||||
|
||||
@typechecked
|
||||
def extract_pictures(ffmpeg_path:str, input_file:IO[bytes], begin:timedelta, nb_frames:int,
|
||||
width:int=640, height:int=480) -> tuple[bytes,int]|tuple[None,None]:
|
||||
width:int=640, height:int=480) -> tuple[bytes,int]:
|
||||
"""
|
||||
Extract pictures from a video file using FFmpeg.
|
||||
|
||||
@@ -126,13 +116,13 @@ def extract_pictures(ffmpeg_path:str, input_file:IO[bytes], begin:timedelta, nb_
|
||||
status = ffmpeg.wait()
|
||||
if status != 0:
|
||||
logger.error('Conversion failed with status code: %d', status)
|
||||
return None, None
|
||||
raise ExternalToolError("")
|
||||
|
||||
lseek(outfd, 0, SEEK_SET)
|
||||
images = read(outfd,length)
|
||||
if len(images) != length:
|
||||
logger.error("Received %d bytes but %d were expected.", len(images), length)
|
||||
return None, None
|
||||
raise InvalidMediaError("")
|
||||
|
||||
lseek(outfd, 0, SEEK_SET)
|
||||
return images, outfd
|
||||
@@ -141,7 +131,7 @@ def extract_pictures(ffmpeg_path:str, input_file:IO[bytes], begin:timedelta, nb_
|
||||
def extract_sound(ffmpeg_path:str, input_file: IO[bytes], begin:timedelta, output_filename:str,
|
||||
packet_duration:int, sub_channel:int=0,
|
||||
nb_packets:int=0, sample_rate:int=48000,
|
||||
nb_channels:int=2) -> tuple[bytes,int]|tuple[None,None]:
|
||||
nb_channels:int=2) -> tuple[bytes,int]:
|
||||
outfd = memfd_create(output_filename, flags=0)
|
||||
infd = input_file.fileno()
|
||||
lseek(infd, 0, SEEK_SET)
|
||||
@@ -160,7 +150,7 @@ def extract_sound(ffmpeg_path:str, input_file: IO[bytes], begin:timedelta, outpu
|
||||
status = ffmpeg.wait()
|
||||
if status != 0:
|
||||
logger.error('Sound extraction returns error code: %d', status)
|
||||
return None, None
|
||||
raise ExternalToolError("")
|
||||
|
||||
lseek(outfd, 0, SEEK_SET)
|
||||
sound = read(outfd, length)
|
||||
@@ -169,7 +159,7 @@ def extract_sound(ffmpeg_path:str, input_file: IO[bytes], begin:timedelta, outpu
|
||||
logger.info("Received %d bytes but %d were expected (channels=%d, freq=%d, packets=%d,\
|
||||
duration=%d ms).", len(sound), length, nb_channels, sample_rate, nb_packets,
|
||||
packet_duration)
|
||||
return None, None
|
||||
raise InvalidMediaError("")
|
||||
|
||||
return sound, outfd
|
||||
|
||||
@@ -236,9 +226,6 @@ def extract_all_streams(ffmpeg_path:str, ffprobe_path:str, input_file:IO[bytes],
|
||||
images_bytes, memfd = extract_pictures(ffmpeg_path, input_file=input_file,
|
||||
begin=begin, nb_frames=nb_frames,
|
||||
width=width, height=height)
|
||||
if images_bytes is None or memfd is None:
|
||||
logger.error('Impossible to extract picture from video stream.')
|
||||
exit(-1)
|
||||
|
||||
memfds.append(memfd)
|
||||
if dump_mem_fd:
|
||||
@@ -262,14 +249,10 @@ def extract_all_streams(ffmpeg_path:str, ffprobe_path:str, input_file:IO[bytes],
|
||||
logger.debug('Audio stream: %s', stream)
|
||||
sample_rate = int(stream['sample_rate'])
|
||||
nb_channels = int(stream['channels'])
|
||||
if 'bit_rate' in stream:
|
||||
bit_rate = int(stream['bit_rate'])
|
||||
else:
|
||||
bit_rate = 128000
|
||||
bit_rate = int(stream['bit_rate']) if 'bit_rate' in stream else 128000
|
||||
codec = stream['codec_name']
|
||||
if 'tags' in stream:
|
||||
if 'language' in stream['tags']:
|
||||
generic_codec_params.extend([f'-metadata:s:a:{audio_id:d}',
|
||||
if 'tags' in stream and 'language' in stream['tags']:
|
||||
generic_codec_params.extend([f'-metadata:s:a:{audio_id:d}',
|
||||
f"language={stream['tags']['language']}"])
|
||||
packets = get_frames_in_stream(ffprobe_path, input_file=input_file, begin=begin,
|
||||
end=end, stream_kind='a', sub_stream_id=audio_id)
|
||||
@@ -294,10 +277,6 @@ def extract_all_streams(ffmpeg_path:str, ffprobe_path:str, input_file:IO[bytes],
|
||||
output_filename=tmpname,
|
||||
sample_rate=sample_rate, nb_channels=nb_channels)
|
||||
|
||||
if sound_bytes is None or memfd is None:
|
||||
logger.error('Impossible to extract sound track')
|
||||
exit(-1)
|
||||
|
||||
memfds.append(memfd)
|
||||
|
||||
if dump_mem_fd:
|
||||
@@ -325,9 +304,8 @@ def extract_all_streams(ffmpeg_path:str, ffprobe_path:str, input_file:IO[bytes],
|
||||
logger.info("Extracting a subtitle stream: s:%d", subtitle_id)
|
||||
codec = stream['codec_name']
|
||||
generic_input_params.extend(['-i', './empty.idx'])
|
||||
if 'tags' in stream:
|
||||
if 'language' in stream['tags']:
|
||||
generic_codec_params.extend([f'-metadata:s:s:{subtitle_id:d}',
|
||||
if 'tags' in stream and 'language' in stream['tags']:
|
||||
generic_codec_params.extend([f'-metadata:s:s:{subtitle_id:d}',
|
||||
f"language={stream['tags']['language']}"])
|
||||
generic_codec_params.extend([f'-c:s:{subtitle_id:d}', 'copy'])
|
||||
subtitle_id=subtitle_id+1
|
||||
|
||||
Reference in New Issue
Block a user