From 8519d9f62ed9a03de9caa44998593c045a22ac25 Mon Sep 17 00:00:00 2001 From: Hannes Date: Thu, 12 Feb 2026 01:20:28 +0100 Subject: [PATCH] make ff nicer --- ff | 104 ++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 21 deletions(-) diff --git a/ff b/ff index 78c45cc..a68c5f1 100755 --- a/ff +++ b/ff @@ -72,6 +72,57 @@ def get_interlace_label(fo): return "Progressive" # Default assumption for modern web video +def fixed_width(s, width, align="left", fill=" "): + s = str(s) + if len(s) > width: + return s[:width] + if align == "right": + return s.rjust(width, fill) + if align == "center": + return s.center(width, fill) + return s.ljust(width, fill) + +def short_codec_name(codec): + if not codec: + return "" + + codec = codec.lower() + + match codec: + # ---- Audio ---- + case "pcm_s16le": + new_codec = "PCM16" + case "pcm_s24le": + new_codec = "PCM24" + case "pcm_s32le": + new_codec = "PCM32" + case "pcm_f32le": + new_codec = "PCMF" + case "truehd": + new_codec = "THD" + + # ---- Video ---- + case "mpeg2video": + new_codec = "MPG2" + case "prores": + new_codec = "PRRS" + case "prores_ks": + new_codec = "PRRSK" + + # ---- Subtitles ---- + case "subrip": + new_codec = "SRT" + case "webvtt": + new_codec = "VTT" + case "hdmv_pgs_subtitle": + new_codec = "PGS" + case "dvb_subtitle": + new_codec = "DVB" + + case _: + new_codec = codec + return fixed_width(new_codec.upper(), 5) + class video_lines: def __init__(self, stream): if stream.get("index"): @@ -135,16 +186,16 @@ class video_lines: self.field_order = "" def __str__(self): - string = "Video" + string = fixed_width("Video", 6) if self.id != None: string += f" {self.id:02d}: " else: string += f": " - string += f"{self.codec}" + string += f"{short_codec_name(self.codec)}" if self.duration: string += f" {self.duration}s" if self.resolution != "x": - string += f"({self.resolution}" + string += f" ({self.resolution}" if self.framerate != "x": string += f"@{self.framerate})" if self.aspect_ratio: @@ -194,13 +245,13 @@ class audio_lines: self.bitrate = f"{int(br) // 1000} kbps" if br else "" def __str__(self): - string = "Audio" + string = "dub" if self.id is not None: - string += f" {self.id}: " + string += f" {self.id:02d}: " else: string += ": " - string += f"{self.codec}" + string += f"{short_codec_name(self.codec)}" if self.language: string += f" [{self.language}]" @@ -250,10 +301,10 @@ class subtitles: self.is_default = dispo.get("default") == 1 def __str__(self): - parts = [f"Subtitle {self.id:02d}:" if self.id is not None else "Subtitle:"] + parts = [f"sub {self.id:02d}:" if self.id is not None else "Subtitle:"] if self.codec: - parts.append(self.codec.upper()) + parts.append(short_codec_name(self.codec)) if self.language: parts.append(f"[{self.language}]") @@ -335,25 +386,36 @@ class video_file: self.name = os.path.basename(path) # 25.mkv self.size = os.path.getsize(path) - self.videos = [] - self.audios = [] - self.subtitles = [] - self.duration, videos, audios, subtitles = get_media_info(path) + self.duration, videos, audios, subs = get_media_info(path) - for vl in videos: - video_line = video_lines(vl) - self.videos.append(video_line) - for al in audios: - audio_line = audio_lines(al) - self.videos.append(audio_line) - for st in subtitles: - subtitle = subtitles(st) - self.videos.append(subtitle) + self.sort_video_info(videos) + self.sort_audio_info(audios) + self.sort_subs_info(subs) self.bitrate = get_stream_bitrate(self.size, self.duration) self.size = human_readable_size(self.size) # 198MB self.duration = seconds_to_hms(self.duration) + def sort_video_info(self, videos): + self.videos = [] + if videos: + for vl in videos: + video_line = video_lines(vl) + self.videos.append(video_line) + + def sort_audio_info(self, audios): + self.audios = [] + if audios: + for al in audios: + self.audios.append(audio_lines(al)) + + def sort_subs_info(self, subs): + self.subtitles = [] + if subs: + for st in subs: + subtitle = subtitles(st) + self.subtitles.append(subtitle) + def print(self): if self.base_tab == "\t": np(f"{self.base_tab}{self.name} ({self.size}, {self.duration}, {self.bitrate} MB/s):", NORMAL_STYLE)