From a2958360bdfa527c2ce4cce3c354adee34833034 Mon Sep 17 00:00:00 2001 From: Ghost <62809003+Ghost6446@users.noreply.github.com> Date: Wed, 10 Apr 2024 08:46:49 +0200 Subject: [PATCH] try fix stuttering 2 --- Src/Lib/FFmpeg/my_m3u8.py | 7 +-- Src/Lib/FFmpeg/util/helper.py | 11 +++-- Src/Lib/FFmpeg/util/parser.py | 92 ++++++++++++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 8 deletions(-) diff --git a/Src/Lib/FFmpeg/my_m3u8.py b/Src/Lib/FFmpeg/my_m3u8.py index 2e4f731..4078ff4 100644 --- a/Src/Lib/FFmpeg/my_m3u8.py +++ b/Src/Lib/FFmpeg/my_m3u8.py @@ -587,7 +587,8 @@ class Downloader(): # Get obj codec self.codec: M3U8_Codec = parse_class_m3u8.codec - logging.info(f"Get coded: {self.codec}") + logging.info(f"Get codeds: {self.codec}") + console.log(f"[cyan]Use codecs: [red]({self.codec.video_codec_name};{self.codec.audio_codec_name})") def manage_subtitle(self): """ @@ -735,8 +736,8 @@ class Downloader(): return concatenate_and_save( file_list_path=file_list_path, output_filename=out_file_name, - v_codec=self.codec.video_codec, - a_codec=self.codec.audio_codec, + v_codec=self.codec.video_codec_name, + a_codec=self.codec.audio_codec_name, bandwidth=self.codec.bandwidth ) diff --git a/Src/Lib/FFmpeg/util/helper.py b/Src/Lib/FFmpeg/util/helper.py index 367b0f3..c638f86 100644 --- a/Src/Lib/FFmpeg/util/helper.py +++ b/Src/Lib/FFmpeg/util/helper.py @@ -20,6 +20,7 @@ from Src.Util.config import config_manager # Variable DEBUG_MODE = config_manager.get_bool("DEFAULT", "debug") DEBUG_FFMPEG = "debug" if DEBUG_MODE else "error" +USE_CODECS = False @@ -210,6 +211,7 @@ def concatenate_and_save(file_list_path: str, output_filename: str, v_codec: str output_args = { 'c': 'copy', + 'preset': 'ultrafast', 'loglevel': DEBUG_FFMPEG, 'y': None, } @@ -217,10 +219,11 @@ def concatenate_and_save(file_list_path: str, output_filename: str, v_codec: str # Add BANDWIDTH and CODECS if provided if bandwidth is not None: output_args['b:v'] = str(bandwidth) - """if v_codec is not None: - output_args['vcodec'] = v_codec - if a_codec is not None: - output_args['acodec'] = a_codec""" + if USE_CODECS: + if v_codec is not None: + output_args['vcodec'] = v_codec + if a_codec is not None: + output_args['acodec'] = a_codec # Set up the output file name by modifying the video file name output_file_name = os.path.splitext(output_filename)[0] + f"_{prefix}.mp4" diff --git a/Src/Lib/FFmpeg/util/parser.py b/Src/Lib/FFmpeg/util/parser.py index 3b2912e..2ac8323 100644 --- a/Src/Lib/FFmpeg/util/parser.py +++ b/Src/Lib/FFmpeg/util/parser.py @@ -12,6 +12,32 @@ import requests from m3u8 import M3U8 +# Costant +CODEC_MAPPINGS = { + "video": { + "avc1": "libx264", + "avc2": "libx264", + "avc3": "libx264", + "avc4": "libx264", + "hev1": "libx265", + "hev2": "libx265", + "hvc1": "libx265", + "hvc2": "libx265", + "vp8": "libvpx", + "vp9": "libvpx-vp9", + "vp10": "libvpx-vp9" + }, + "audio": { + "mp4a": "aac", + "mp3": "libmp3lame", + "ac-3": "ac3", + "ec-3": "eac3", + "opus": "libopus", + "vorbis": "libvorbis" + } +} + + class M3U8_Codec(): """ @@ -39,9 +65,10 @@ class M3U8_Codec(): self.codecs = codecs self.audio_codec = None self.video_codec = None + self.extract_codecs() self.parse_codecs() - def parse_codecs(self): + def extract_codecs(self): """ Parses the codecs information to extract audio and video codecs. @@ -57,6 +84,69 @@ class M3U8_Codec(): elif codec.startswith('mp4a'): self.audio_codec = codec + def convert_video_codec(self, video_codec_identifier) -> str: + + """ + Convert video codec identifier to codec name. + + Parameters: + - video_codec_identifier (str): Identifier of the video codec. + + Returns: + - str: Codec name corresponding to the identifier. + """ + + # Extract codec type from the identifier + codec_type = video_codec_identifier.split('.')[0] + + # Retrieve codec mapping from the provided mappings or fallback to static mappings + video_codec_mapping = CODEC_MAPPINGS.get('video', {}) + codec_name = video_codec_mapping.get(codec_type) + + if codec_name: + return codec_name + + else: + logging.warning(f"No corresponding video codec found for {video_codec_identifier}. Using default codec libx264.") + return "libx264" # Default + + def convert_audio_codec(self, audio_codec_identifier) -> str: + + """ + Convert audio codec identifier to codec name. + + Parameters: + - audio_codec_identifier (str): Identifier of the audio codec. + + Returns: + - str: Codec name corresponding to the identifier. + """ + + # Extract codec type from the identifier + codec_type = audio_codec_identifier.split('.')[0] + + # Retrieve codec mapping from the provided mappings or fallback to static mappings + audio_codec_mapping = CODEC_MAPPINGS.get('audio', {}) + codec_name = audio_codec_mapping.get(codec_type) + + if codec_name: + return codec_name + + else: + logging.warning(f"No corresponding audio codec found for {audio_codec_identifier}. Using default codec aac.") + return "aac" # Default + + def parse_codecs(self): + """ + Parse video and audio codecs. + + This method updates `video_codec_name` and `audio_codec_name` attributes. + """ + + self.video_codec_name = self.convert_video_codec(self.video_codec) + self.audio_codec_name = self.convert_audio_codec(self.audio_codec) + logging.info(f"CODECS={self.video_codec_name},{self.audio_codec_name}") + def __str__(self): """ Returns a string representation of the M3U8Codec object.