inc multifile handling

click
Maveno 1 year ago
parent e7426398ee
commit ad7562f387

@ -15,8 +15,7 @@ DEFAULT_QUALITY = 23
DEFAULT_AV1_PRESET = 5
DEFAULT_LABEL='output'
DEFAULT_FILE_SUFFIX = 'webm'
DEFAULT_FILE_EXTENSION = 'webm'
DEFAULT_STEREO_BANDWIDTH = "128"
DEFAULT_AC3_BANDWIDTH = "256"
@ -50,9 +49,8 @@ STREAM_LAYOUT_5_1 = '5.1(side)'
STREAM_LAYOUT_STEREO = 'stereo'
STREAM_LAYOUT_6CH = '6ch'
SEASON_EPISODE_INDICATOR_MATCH = '([sS][0-9]+)([eE][0-9]+)'
SEASON_INDICATOR_MATCH = '([sS][0-9]+)'
EPISODE_INDICATOR_MATCH = '([eE][0-9]+)'
SEASON_EPISODE_INDICATOR_MATCH = '[sS]([0-9]+)[eE]([0-9]+)'
EPISODE_INDICATOR_MATCH = '[eE]([0-9]+)'
class DashboardScreen(Screen):
@ -129,7 +127,7 @@ def executeProcess(commandSequence):
output, error = process.communicate()
return output
return output.decode('utf-8'), error.decode('utf-8')
@ -142,11 +140,14 @@ def executeProcess(commandSequence):
def getStreamDescriptor(filename):
ffprobeOutput = executeProcess(["ffprobe",
ffprobeOutput, ffprobeError = executeProcess(["ffprobe",
"-show_streams",
"-of", "json",
filename])
if 'Invalid data found when processing input' in ffprobeError:
return None
streamData = json.loads(ffprobeOutput)['streams']
descriptor = []
@ -249,16 +250,16 @@ def generateOutputTokens(f, suffix, q=None):
# if presetTokens:
# preset = int(presetTokens[0].split('=')[1])
# cropStart = ''
# cropLength = ''
# ctx.obj['crop_start'] = ''
# ctx.obj['crop_length'] = ''
# cropTokens = [c for c in sys.argv if c.startswith('crop')]
# if cropTokens:
# if '=' in cropTokens[0]:
# cropString = cropTokens[0].split('=')[1]
# cropStart, cropLength = cropString.split(',')
# ctx.obj['crop_start'], ctx.obj['crop_length'] = cropString.split(',')
# else:
# cropStart = 60
# cropLength = 180
# ctx.obj['crop_start'] = 60
# ctx.obj['crop_length'] = 180
#
# denoiseTokens = [d for d in sys.argv if d.startswith('denoise')]
#
@ -336,7 +337,10 @@ def help():
@click.argument('filename', nargs=1)
@ffx.command()
def streams(filename):
for d in getStreamDescriptor(filename):
sd = getStreamDescriptor(filename)
if sd is None:
raise click.ClickException('This file does not contain any audiovisual data')
for d in sd:
click.echo(f"{d['codec']}{' (' + str(d['channels']) + ')' if d['type'] == 'audio' else ''}")
@ -345,7 +349,7 @@ def streams(filename):
@click.pass_context
@click.argument('paths', nargs=-1)
@click.option('-l', '--label', type=str, default=DEFAULT_LABEL, help='Label to be used as filename prefix')
@click.option('-l', '--label', type=str, default='', help='Label to be used as filename prefix')
@click.option('-v', '--video-encoder', type=str, default=DEFAULT_VIDEO_ENCODER, help='Target video encoder (vp9 or av1) default: vp9')
@ -418,9 +422,9 @@ def convert(ctx, paths, label, video_encoder, quality, preset, stereo_bitrate, a
click.echo(f"\nRunning {len(paths) * len(q_list)} jobs")
job_index = 0
se_match = re.compile(SEASON_EPISODE_INDICATOR_MATCH)
s_match = re.compile(SEASON_INDICATOR_MATCH)
e_match = re.compile(EPISODE_INDICATOR_MATCH)
@ -442,97 +446,146 @@ def convert(ctx, paths, label, video_encoder, quality, preset, stereo_bitrate, a
sourceFileBasename = sourceFilename
sourceFilenameExtension = ''
#click.echo(f"dir={sourceDirectory} base={sourceFileBasename} ext={sourceFilenameExtension}")
click.echo(f"\nProcessing file {sourcePath}")
season_digits = 2
episode_digits = 2
index_digits = 3
se_result = se_match.search(sourceFilename)
s_result = s_match.search(sourceFilename)
e_result = e_match.search(sourceFilename)
season = -1
episode = -1
file_index = 0
if se_result is not None:
season = int(se_result.group(1))
episode = int(se_result.group(2))
elif e_result is not None:
episode = int(e_result.group(1))
else:
file_index += 1
print(f"season={season} episode={episode} file={file_index}")
targetFilenameTokens = []
#streamDescriptor = getStreamDescriptor(sourcePath)
#commandTokens = COMMAND_TOKENS + [sourcePath]
targetFilenameExtension = DEFAULT_FILE_EXTENSION
#for q in q_list:
if label:
targetFilenameTokens = [label]
#click.echo(f"\nRunning job q={q}")
if season > -1 and episode > -1:
targetFilenameTokens += [f"S{season:0{season_digits}d}E{episode:0{episode_digits}d}"]
elif episode > -1:
targetFilenameTokens += [f"E{episode:0{episode_digits}d}"]
else:
targetFilenameTokens += [f"{file_index:0{index_digits}d}"]
else:
targetFilenameTokens = [sourceFileBasename]
#mappingVideoTokens = ['-map', 'v:0']
#mappingTokens = mappingVideoTokens.copy()
#audioTokens = []
# In case source and target filenames are the same add an extension to distinct output from input
if sourceFilenameExtension == targetFilenameExtension:
targetFilenameTokens += ['ffx']
#audioIndex = 0
#for audioStreamDescriptor in streamDescriptor:
#if audioStreamDescriptor['type'] == STREAM_TYPE_AUDIO:
targetFilename = '_'.join(targetFilenameTokens) + '.' + targetFilenameExtension
#mappingTokens += ['-map', f"a:{audioIndex}"]
#audioTokens += generateAudioTokens(ctx.obj, audioIndex, audioStreamDescriptor['layout'])
#audioIndex += 1
click.echo(f"target filename: {targetFilename}")
streamDescriptor = getStreamDescriptor(sourcePath)
#for s in range(len([d for d in streamDescriptor if d['type'] == STREAM_TYPE_SUBTITLE])):
#mappingTokens += ['-map', f"s:{s}"]
if streamDescriptor is None:
click.echo(f"File with path {sourcePath} does not contain any audiovisual data, skipping ...")
continue
commandTokens = COMMAND_TOKENS + [sourcePath]
#if video_encoder == 'av1':
for q in q_list:
#commandSequence = commandTokens + mappingTokens + audioTokens + generateAV1Tokens(q, preset) + audioTokens
click.echo(f"\nRunning job {job_index} file={sourcePath} q={q}")
job_index += 1
#if clear_metadata:
#commandSequence += generateClearTokens(streamDescriptor)
mappingVideoTokens = ['-map', 'v:0']
mappingTokens = mappingVideoTokens.copy()
audioTokens = []
#if performCrop:
#commandSequence += generateCropTokens(cropStart, cropLength)
audioIndex = 0
for audioStreamDescriptor in streamDescriptor:
#commandSequence += generateOutputTokens(targetFilename, DEFAULT_FILE_SUFFIX, q)
if audioStreamDescriptor['type'] == STREAM_TYPE_AUDIO:
#click.echo(f"Command: {' '.join(commandSequence)}")
mappingTokens += ['-map', f"a:{audioIndex}"]
audioTokens += generateAudioTokens(ctx.obj, audioIndex, audioStreamDescriptor['layout'])
audioIndex += 1
#executeProcess(commandSequence)
for s in range(len([d for d in streamDescriptor if d['type'] == STREAM_TYPE_SUBTITLE])):
mappingTokens += ['-map', f"s:{s}"]
#if video_encoder == 'vp9':
#commandSequence1 = commandTokens + mappingVideoTokens + generateVP9Pass1Tokens(q)
#if performCrop:
# commandSequence1 += generateCropTokens(cropStart, cropLength)
if video_encoder == 'av1':
#commandSequence1 += NULL_TOKENS
commandSequence = commandTokens + mappingTokens + audioTokens + generateAV1Tokens(q, preset) + audioTokens
#click.echo(f"Command 1: {' '.join(commandSequence1)}")
if clear_metadata:
commandSequence += generateClearTokens(streamDescriptor)
#if os.path.exists(TEMP_FILE_NAME):
# os.remove(TEMP_FILE_NAME)
if ctx.obj['perform_crop']:
commandSequence += generateCropTokens(ctx.obj['crop_start'], ctx.obj['crop_length'])
#executeProcess(commandSequence1)
commandSequence += generateOutputTokens(targetFilename, DEFAULT_FILE_EXTENSION, q)
click.echo(f"Command: {' '.join(commandSequence)}")
#commandSequence2 = commandTokens + mappingTokens
# executeProcess(commandSequence)
#if denoise:
# commandSequence2 += generateDenoiseTokens()
#commandSequence2 += generateVP9Pass2Tokens(q) + audioTokens
if video_encoder == 'vp9':
#if clear_metadata:
# commandSequence2 += generateClearTokens(streamDescriptor)
commandSequence1 = commandTokens + mappingVideoTokens + generateVP9Pass1Tokens(q)
#if performCrop:
# commandSequence2 += generateCropTokens(cropStart, cropLength)
if ctx.obj['perform_crop']:
commandSequence1 += generateCropTokens(ctx.obj['crop_start'], ctx.obj['crop_length'])
commandSequence1 += NULL_TOKENS
click.echo(f"Command 1: {' '.join(commandSequence1)}")
if os.path.exists(TEMP_FILE_NAME):
os.remove(TEMP_FILE_NAME)
# executeProcess(commandSequence1)
commandSequence2 = commandTokens + mappingTokens
if denoise:
commandSequence2 += generateDenoiseTokens()
commandSequence2 += generateVP9Pass2Tokens(q) + audioTokens
if clear_metadata:
commandSequence2 += generateClearTokens(streamDescriptor)
if ctx.obj['perform_crop']:
commandSequence2 += generateCropTokens(ctx.obj['crop_start'], ctx.obj['crop_length'])
#commandSequence2 += generateOutputTokens(targetFilename, DEFAULT_FILE_SUFFIX, q)
commandSequence2 += generateOutputTokens(targetFilename, DEFAULT_FILE_EXTENSION, q)
#click.echo(f"Command 2: {' '.join(commandSequence2)}")
click.echo(f"Command 2: {' '.join(commandSequence2)}")
#executeProcess(commandSequence2)
# executeProcess(commandSequence2)
#app = ModesApp(ctx.obj)

Loading…
Cancel
Save