Feat: Enhance video conversion process on odd pixel dimensions
- Added line break in conversion output before each video for improved readability. - Implemented handling for odd pixel dimensions by adding black pixel padding to ensure even width and height.
This commit is contained in:
parent
5ad78b33f2
commit
c42271b0e4
@ -151,7 +151,8 @@ class Video():
|
|||||||
extension="mkv",
|
extension="mkv",
|
||||||
verbose=False):
|
verbose=False):
|
||||||
'''
|
'''
|
||||||
Converts the original file to the requested format / codec.
|
Converts the original file to the requested format / codec,
|
||||||
|
ensuring even width/height by adding a black pixel gap if necessary.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
vcodec (str): The new video codec, supports av1 or x265.
|
vcodec (str): The new video codec, supports av1 or x265.
|
||||||
@ -164,58 +165,64 @@ class Video():
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
# Setting new filename
|
# Setting new filename
|
||||||
|
base_filename, _ = os.path.splitext(self.filename_origin)
|
||||||
|
|
||||||
if "mp4" in extension:
|
if "mp4" in extension:
|
||||||
newfilename = self.filename_origin[:-4] + ".mp4"
|
newfilename = base_filename + ".mp4"
|
||||||
if os.path.exists(self.path + newfilename):
|
|
||||||
newfilename = findfreename(self.path + newfilename)
|
|
||||||
if os.name == 'nt':
|
|
||||||
newfilename = str(
|
|
||||||
newfilename)[str(newfilename).rindex("\\") + 1:]
|
|
||||||
else:
|
|
||||||
newfilename = str(
|
|
||||||
newfilename)[str(newfilename).rindex("/") + 1:]
|
|
||||||
else:
|
else:
|
||||||
newfilename = self.filename_origin[:-4] + ".mkv"
|
newfilename = base_filename + ".mkv"
|
||||||
if os.path.exists(self.path + newfilename):
|
|
||||||
newfilename = findfreename(self.path + newfilename)
|
if os.path.exists(self.path + newfilename):
|
||||||
if os.name == 'nt':
|
newfilename = findfreename(self.path + newfilename)
|
||||||
newfilename = str(
|
newfilename = os.path.basename(newfilename)
|
||||||
newfilename)[str(newfilename).rindex("\\") + 1:]
|
|
||||||
else:
|
|
||||||
newfilename = str(
|
|
||||||
newfilename)[str(newfilename).rindex("/") + 1:]
|
|
||||||
|
|
||||||
self.filename_tmp = newfilename
|
self.filename_tmp = newfilename
|
||||||
|
|
||||||
# Setting ffmpeg
|
# Setting ffmpeg command
|
||||||
args = [
|
args = [
|
||||||
'ffmpeg', '-i', self.path + self.filename_origin, '-map', '0:v',
|
'ffmpeg', '-i', self.path + self.filename_origin, '-map', '0:v',
|
||||||
'-map', '0:a?', '-map', '0:s?', '-map_metadata', '0'
|
'-map', '0:a?', '-map', '0:s?', '-map_metadata', '0'
|
||||||
]
|
]
|
||||||
|
|
||||||
# Conversion options
|
# Conversion options based on codec
|
||||||
if vcodec == "av1":
|
if vcodec == "av1":
|
||||||
args += ['-c:v', 'libaom-av1']
|
args += ['-c:v', 'libaom-av1']
|
||||||
# Optionally, control quality with a crf value for AV1
|
# Optionally, control quality with a crf value for AV1
|
||||||
args += ['-crf', '30']
|
args += ['-crf', '30']
|
||||||
elif vcodec == "x265" or vcodec == "hevc":
|
elif vcodec == "x265" or vcodec == "hevc":
|
||||||
args += ['-c:v', 'libx265']
|
args += ['-c:v', 'libx265']
|
||||||
# Add max_muxing_queue_size to avoid buffer overflows
|
|
||||||
args += ['-max_muxing_queue_size', '1000']
|
|
||||||
# Control quality with crf for x265
|
# Control quality with crf for x265
|
||||||
args += ['-preset', 'medium', '-crf', '28']
|
args += ['-preset', 'medium', '-crf', '28']
|
||||||
|
# Add max_muxing_queue_size to avoid buffer overflows
|
||||||
|
args += ['-max_muxing_queue_size', '1000']
|
||||||
|
|
||||||
# Add mapping for video, audio, and subtitle streams
|
# Check for odd width/height and adjust with padding
|
||||||
|
width_canvas = self.width
|
||||||
|
height_canvas = self.height
|
||||||
|
if self.width % 2 != 0:
|
||||||
|
width_canvas = self.width + 1
|
||||||
|
|
||||||
|
if self.height % 2 != 0:
|
||||||
|
height_canvas = self.height + 1
|
||||||
|
|
||||||
|
# Only add padding if needed
|
||||||
|
if self.width != width_canvas or self.height != height_canvas:
|
||||||
|
args += [
|
||||||
|
'-vf',
|
||||||
|
f"pad={width_canvas}:{height_canvas}:(ow-iw)/2:(oh-ih)/2:black"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Copy audio and subtitles without re-encoding
|
||||||
args += ['-c:a', 'copy', '-c:s', 'copy']
|
args += ['-c:a', 'copy', '-c:s', 'copy']
|
||||||
|
|
||||||
# Conversion output
|
# Specify output file
|
||||||
args += [self.path + self.filename_tmp]
|
args += [self.path + self.filename_tmp]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if verbose:
|
if verbose:
|
||||||
subprocess.call(args)
|
subprocess.call(args)
|
||||||
else:
|
else:
|
||||||
txt = subprocess.check_output(args, stderr=subprocess.STDOUT)
|
subprocess.check_output(args, stderr=subprocess.STDOUT)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
deletefile(self.path + self.filename_tmp)
|
deletefile(self.path + self.filename_tmp)
|
||||||
self.filename_tmp = ""
|
self.filename_tmp = ""
|
||||||
|
|||||||
@ -149,7 +149,7 @@ def main():
|
|||||||
|
|
||||||
# Verbosing
|
# Verbosing
|
||||||
print(
|
print(
|
||||||
f"{cgreen}****** Starting conversion {counter} of {len(keylist)}: '{ccyan}{medialibrary.videos[filepath].filename_origin}{cgreen}' from {ccyan}{medialibrary.videos[filepath].codec}{cgreen} to {ccyan}{vcodec}{cgreen}...{creset}"
|
f"{cgreen}\n****** Starting conversion {counter} of {len(keylist)}: '{ccyan}{medialibrary.videos[filepath].filename_origin}{cgreen}' from {ccyan}{medialibrary.videos[filepath].codec}{cgreen} to {ccyan}{vcodec}{cgreen}...{creset}"
|
||||||
)
|
)
|
||||||
print(f"{ccyan}Original file:{creset}")
|
print(f"{ccyan}Original file:{creset}")
|
||||||
if "formated" in arguments["printop"] or "verbose" in arguments[
|
if "formated" in arguments["printop"] or "verbose" in arguments[
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user