fix: corrections post-review (escapes, find_crf, color_args, chemins /tmp/)
- Supprime les séquences d'échappement invalides \( \) dans les f-strings HDR10 (SyntaxWarning → SyntaxError en Python 3.14) - find_crf : prend la dernière ligne "crf X VMAF Y" au lieu de la première (évite de retourner un CRF intermédiaire d'ab-av1 crf-search) - color_args : garde contre les valeurs None pour color_primaries/transfer/space - Chemins /tmp/ : utilise os.path.basename() pour éviter les chemins malformés si le fichier source est spécifié avec un chemin absolu ou relatif Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -71,10 +71,11 @@ def get_infos(file):
|
|||||||
hdr10_v_cmd = f'ffmpeg -loglevel panic -i {file} -c:v copy {bsf} -f hevc - | hdr10plus_parser --verify -'
|
hdr10_v_cmd = f'ffmpeg -loglevel panic -i {file} -c:v copy {bsf} -f hevc - | hdr10plus_parser --verify -'
|
||||||
hdr10_v_raw = subprocess.getoutput(hdr10_v_cmd)
|
hdr10_v_raw = subprocess.getoutput(hdr10_v_cmd)
|
||||||
if 'metadata detected' in hdr10_v_raw:
|
if 'metadata detected' in hdr10_v_raw:
|
||||||
hdr10_cmd = f'ffmpeg -loglevel panic -i {file} -c:v copy {bsf} -f hevc - | hdr10plus_parser -o /tmp/{file}_hdr10_metadata.json -'
|
hdr10_meta = f'/tmp/{os.path.basename(file)}_hdr10_metadata.json'
|
||||||
|
hdr10_cmd = f'ffmpeg -loglevel panic -i {file} -c:v copy {bsf} -f hevc - | hdr10plus_parser -o {hdr10_meta} -'
|
||||||
hdr10_cmd_res = subprocess.getoutput(hdr10_cmd)
|
hdr10_cmd_res = subprocess.getoutput(hdr10_cmd)
|
||||||
logging.debug(hdr10_cmd_res)
|
logging.debug(hdr10_cmd_res)
|
||||||
v_infos.update({'hdr10plus': True, 'hdr10plus_metadata': f'/tmp/{file}_hdr10_metadata.json'})
|
v_infos.update({'hdr10plus': True, 'hdr10plus_metadata': hdr10_meta})
|
||||||
try:
|
try:
|
||||||
for side_data in full_v_infos['frames'][0].get('side_data_list', []):
|
for side_data in full_v_infos['frames'][0].get('side_data_list', []):
|
||||||
if side_data.get('side_data_type') == 'DOVI configuration record':
|
if side_data.get('side_data_type') == 'DOVI configuration record':
|
||||||
@@ -146,15 +147,17 @@ def find_crf(file, enc_options, hdr=False):
|
|||||||
logging.debug(cmd)
|
logging.debug(cmd)
|
||||||
result = subprocess.getoutput(cmd)
|
result = subprocess.getoutput(cmd)
|
||||||
logging.debug(result)
|
logging.debug(result)
|
||||||
|
found_crf = None
|
||||||
for line in result.splitlines():
|
for line in result.splitlines():
|
||||||
# ab-av1 émet une ligne du type : "crf 32 VMAF 96.21 ..."
|
# ab-av1 émet des lignes intermédiaires puis une ligne finale "crf 32 VMAF 96.21 ..."
|
||||||
if 'crf' in line and 'VMAF' in line:
|
if 'crf' in line and 'VMAF' in line:
|
||||||
try:
|
try:
|
||||||
crf = int(line.split('crf')[1].split()[0])
|
found_crf = int(line.split('crf')[1].split()[0])
|
||||||
logging.info(f"CRF optimal trouvé : {crf}")
|
|
||||||
return crf
|
|
||||||
except (IndexError, ValueError):
|
except (IndexError, ValueError):
|
||||||
pass
|
pass
|
||||||
|
if found_crf is not None:
|
||||||
|
logging.info(f"CRF optimal trouvé : {found_crf}")
|
||||||
|
return found_crf
|
||||||
logging.warning("ab-av1 crf-search a échoué, utilisation du CRF par défaut (32)")
|
logging.warning("ab-av1 crf-search a échoué, utilisation du CRF par défaut (32)")
|
||||||
return 32
|
return 32
|
||||||
|
|
||||||
@@ -212,32 +215,33 @@ def convert_video(file, infos, crf, crop, enc_options, interlaced, vhs):
|
|||||||
color_primaries = infos['video']['color_primaries']
|
color_primaries = infos['video']['color_primaries']
|
||||||
color_transfer = infos['video']['color_transfer']
|
color_transfer = infos['video']['color_transfer']
|
||||||
color_space = infos['video']['color_space']
|
color_space = infos['video']['color_space']
|
||||||
|
if all([color_primaries, color_transfer, color_space]):
|
||||||
color_args = f'-color_primaries {color_primaries} -color_trc {color_transfer} -colorspace {color_space}'
|
color_args = f'-color_primaries {color_primaries} -color_trc {color_transfer} -colorspace {color_space}'
|
||||||
green_x = infos['video']['side_data_list'][0]['green_x'].split('/')
|
green_x = infos['video']['side_data_list'][0]['green_x'].split('/')
|
||||||
green_x = int(int(green_x[0])*(int(green_x[1])/50000))
|
green_x = int(int(green_x[0])*(int(green_x[1])/50000))
|
||||||
green_y = infos['video']['side_data_list'][0]['green_y'].split('/')
|
green_y = infos['video']['side_data_list'][0]['green_y'].split('/')
|
||||||
green_y = int(int(green_y[0])*(int(green_y[1])/50000))
|
green_y = int(int(green_y[0])*(int(green_y[1])/50000))
|
||||||
green = f'G\({green_x},{green_y}\)'
|
green = f'G({green_x},{green_y})'
|
||||||
blue_x = infos['video']['side_data_list'][0]['blue_x'].split('/')
|
blue_x = infos['video']['side_data_list'][0]['blue_x'].split('/')
|
||||||
blue_x = int(int(blue_x[0])*(int(blue_x[1])/50000))
|
blue_x = int(int(blue_x[0])*(int(blue_x[1])/50000))
|
||||||
blue_y = infos['video']['side_data_list'][0]['blue_y'].split('/')
|
blue_y = infos['video']['side_data_list'][0]['blue_y'].split('/')
|
||||||
blue_y = int(int(blue_y[0])*(int(blue_y[1])/50000))
|
blue_y = int(int(blue_y[0])*(int(blue_y[1])/50000))
|
||||||
blue = f'B\({blue_x},{blue_y}\)'
|
blue = f'B({blue_x},{blue_y})'
|
||||||
red_x = infos['video']['side_data_list'][0]['red_x'].split('/')
|
red_x = infos['video']['side_data_list'][0]['red_x'].split('/')
|
||||||
red_x = int(int(red_x[0])*(int(red_x[1])/50000))
|
red_x = int(int(red_x[0])*(int(red_x[1])/50000))
|
||||||
red_y = infos['video']['side_data_list'][0]['red_y'].split('/')
|
red_y = infos['video']['side_data_list'][0]['red_y'].split('/')
|
||||||
red_y = int(int(red_y[0])*(int(red_y[1])/50000))
|
red_y = int(int(red_y[0])*(int(red_y[1])/50000))
|
||||||
red = f'R\({red_x},{red_y}\)'
|
red = f'R({red_x},{red_y})'
|
||||||
white_point_x = infos['video']['side_data_list'][0]['white_point_x'].split('/')
|
white_point_x = infos['video']['side_data_list'][0]['white_point_x'].split('/')
|
||||||
white_point_x = int(int(white_point_x[0])*(int(white_point_x[1])/50000))
|
white_point_x = int(int(white_point_x[0])*(int(white_point_x[1])/50000))
|
||||||
white_point_y = infos['video']['side_data_list'][0]['white_point_y'].split('/')
|
white_point_y = infos['video']['side_data_list'][0]['white_point_y'].split('/')
|
||||||
white_point_y = int(int(white_point_y[0])*(int(white_point_y[1])/50000))
|
white_point_y = int(int(white_point_y[0])*(int(white_point_y[1])/50000))
|
||||||
white_point = f'WP\({white_point_x},{white_point_y}\)'
|
white_point = f'WP({white_point_x},{white_point_y})'
|
||||||
min_luminance = infos['video']['side_data_list'][0]['min_luminance'].split('/')
|
min_luminance = infos['video']['side_data_list'][0]['min_luminance'].split('/')
|
||||||
min_luminance = int(int(min_luminance[0])*(int(min_luminance[1])/10000))
|
min_luminance = int(int(min_luminance[0])*(int(min_luminance[1])/10000))
|
||||||
max_luminance = infos['video']['side_data_list'][0]['max_luminance'].split('/')
|
max_luminance = infos['video']['side_data_list'][0]['max_luminance'].split('/')
|
||||||
max_luminance = int(int(max_luminance[0])*(int(max_luminance[1])/10000))
|
max_luminance = int(int(max_luminance[0])*(int(max_luminance[1])/10000))
|
||||||
luminance = f'L\({max_luminance},{min_luminance}\)'
|
luminance = f'L({max_luminance},{min_luminance})'
|
||||||
master_display = green + blue + red + white_point + luminance
|
master_display = green + blue + red + white_point + luminance
|
||||||
hdr = f'mastering-display={master_display}:content-light={light_level}'
|
hdr = f'mastering-display={master_display}:content-light={light_level}'
|
||||||
if svtav1_params:
|
if svtav1_params:
|
||||||
@@ -280,13 +284,14 @@ def create_mkv(filename):
|
|||||||
json_data += ["--no-track-tags", "--no-global-tags", "--no-chapters",
|
json_data += ["--no-track-tags", "--no-global-tags", "--no-chapters",
|
||||||
"--language", f"0:{lang}",
|
"--language", f"0:{lang}",
|
||||||
"(", file, ")"]
|
"(", file, ")"]
|
||||||
with open(f"/tmp/{filename}.json", "w") as mkvmerge_options:
|
json_path = f"/tmp/{os.path.basename(filename)}.json"
|
||||||
|
with open(json_path, "w") as mkvmerge_options:
|
||||||
mkvmerge_options.write(json.dumps(json_data))
|
mkvmerge_options.write(json.dumps(json_data))
|
||||||
command = f"mkvmerge -v @/tmp/{filename}.json"
|
command = f"mkvmerge -v @{json_path}"
|
||||||
logging.debug(command)
|
logging.debug(command)
|
||||||
result = subprocess.getoutput(command)
|
result = subprocess.getoutput(command)
|
||||||
logging.info(result)
|
logging.info(result)
|
||||||
remove(f"/tmp/{filename}.json")
|
remove(json_path)
|
||||||
for file in listdir():
|
for file in listdir():
|
||||||
if file == video_file:
|
if file == video_file:
|
||||||
remove(file)
|
remove(file)
|
||||||
|
|||||||
Reference in New Issue
Block a user