inc
This commit is contained in:
103
bin/ffx.py
103
bin/ffx.py
@@ -1,6 +1,6 @@
|
|||||||
#! /usr/bin/python3
|
#! /usr/bin/python3
|
||||||
|
|
||||||
import os, sys, subprocess, json, click, time
|
import os, sys, subprocess, json, click, time, re
|
||||||
|
|
||||||
from textual.app import App, ComposeResult
|
from textual.app import App, ComposeResult
|
||||||
from textual.screen import Screen
|
from textual.screen import Screen
|
||||||
@@ -50,6 +50,9 @@ STREAM_LAYOUT_5_1 = '5.1(side)'
|
|||||||
STREAM_LAYOUT_STEREO = 'stereo'
|
STREAM_LAYOUT_STEREO = 'stereo'
|
||||||
STREAM_LAYOUT_6CH = '6ch'
|
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]+)'
|
||||||
|
|
||||||
|
|
||||||
class DashboardScreen(Screen):
|
class DashboardScreen(Screen):
|
||||||
@@ -364,8 +367,10 @@ def streams(filename):
|
|||||||
@click.option("-c", "--clear-metadata", is_flag=True, default=False)
|
@click.option("-c", "--clear-metadata", is_flag=True, default=False)
|
||||||
@click.option("-d", "--denoise", is_flag=True, default=False)
|
@click.option("-d", "--denoise", is_flag=True, default=False)
|
||||||
|
|
||||||
|
@click.option("-o", "--output-directory", type=str, default='')
|
||||||
|
|
||||||
def convert(ctx, paths, label, video_encoder, quality, preset, stereo_bitrate, ac3_bitrate, dts_bitrate, crop, clear_metadata, default_subtitle, forced_audio, default_audio, denoise):
|
|
||||||
|
def convert(ctx, paths, label, video_encoder, quality, preset, stereo_bitrate, ac3_bitrate, dts_bitrate, crop, clear_metadata, default_subtitle, forced_audio, default_audio, denoise, output_directory):
|
||||||
"""Batch conversion of audiovideo files in format suitable for web playback, e.g. jellyfin
|
"""Batch conversion of audiovideo files in format suitable for web playback, e.g. jellyfin
|
||||||
|
|
||||||
Files found under PATHS will be converted according to parameters.
|
Files found under PATHS will be converted according to parameters.
|
||||||
@@ -377,11 +382,54 @@ def convert(ctx, paths, label, video_encoder, quality, preset, stereo_bitrate, a
|
|||||||
|
|
||||||
context = ctx.obj
|
context = ctx.obj
|
||||||
|
|
||||||
|
|
||||||
|
click.echo(f"\nVideo encoder: {video_encoder}")
|
||||||
|
|
||||||
|
qualityTokens = quality.split(',')
|
||||||
|
q_list = [q for q in qualityTokens if q.isnumeric()]
|
||||||
|
|
||||||
|
click.echo(f"Qualities: {q_list}")
|
||||||
|
|
||||||
|
|
||||||
|
ctx.obj['bitrates'] = {}
|
||||||
|
ctx.obj['bitrates']['stereo'] = str(stereo_bitrate) if str(stereo_bitrate).endswith('k') else f"{stereo_bitrate}k"
|
||||||
|
ctx.obj['bitrates']['ac3'] = str(ac3_bitrate) if str(ac3_bitrate).endswith('k') else f"{ac3_bitrate}k"
|
||||||
|
ctx.obj['bitrates']['dts'] = str(dts_bitrate) if str(dts_bitrate).endswith('k') else f"{dts_bitrate}k"
|
||||||
|
|
||||||
|
click.echo(f"Stereo bitrate: {ctx.obj['bitrates']['stereo']}")
|
||||||
|
click.echo(f"AC3 bitrate: {ctx.obj['bitrates']['ac3']}")
|
||||||
|
click.echo(f"DTS bitrate: {ctx.obj['bitrates']['dts']}")
|
||||||
|
|
||||||
|
ctx.obj['perform_crop'] = (crop != 'none')
|
||||||
|
|
||||||
|
if ctx.obj['perform_crop']:
|
||||||
|
|
||||||
|
cropTokens = crop.split(',')
|
||||||
|
|
||||||
|
if cropTokens and len(cropTokens) == 2:
|
||||||
|
|
||||||
|
ctx.obj['crop_start'], ctx.obj['crop_length'] = crop.split(',')
|
||||||
|
else:
|
||||||
|
ctx.obj['crop_start'] = DEFAULT_CROP_START
|
||||||
|
ctx.obj['crop_length'] = DEFAULT_CROP_LENGTH
|
||||||
|
|
||||||
|
click.echo(f"crop start={ctx.obj['crop_start']} length={ctx.obj['crop_length']}")
|
||||||
|
|
||||||
|
|
||||||
|
click.echo(f"\nRunning {len(paths) * len(q_list)} jobs")
|
||||||
|
|
||||||
|
|
||||||
|
se_match = re.compile(SEASON_EPISODE_INDICATOR_MATCH)
|
||||||
|
s_match = re.compile(SEASON_INDICATOR_MATCH)
|
||||||
|
e_match = re.compile(EPISODE_INDICATOR_MATCH)
|
||||||
|
|
||||||
|
|
||||||
for sourcePath in paths:
|
for sourcePath in paths:
|
||||||
|
|
||||||
|
|
||||||
if not os.path.isfile(sourcePath):
|
if not os.path.isfile(sourcePath):
|
||||||
click.echo(f"There is no file with path {sourcePath}, skipping ...")
|
click.echo(f"There is no file with path {sourcePath}, skipping ...")
|
||||||
|
continue
|
||||||
|
|
||||||
sourceDirectory = os.path.dirname(sourcePath)
|
sourceDirectory = os.path.dirname(sourcePath)
|
||||||
sourceFilename = os.path.basename(sourcePath)
|
sourceFilename = os.path.basename(sourcePath)
|
||||||
@@ -394,51 +442,16 @@ def convert(ctx, paths, label, video_encoder, quality, preset, stereo_bitrate, a
|
|||||||
sourceFileBasename = sourceFilename
|
sourceFileBasename = sourceFilename
|
||||||
sourceFilenameExtension = ''
|
sourceFilenameExtension = ''
|
||||||
|
|
||||||
click.echo(f"dir={sourceDirectory} base={sourceFileBasename} ext={sourceFilenameExtension}")
|
#click.echo(f"dir={sourceDirectory} base={sourceFileBasename} ext={sourceFilenameExtension}")
|
||||||
|
|
||||||
#click.echo(f"src: {sourcePath} tgt: {targetFilename}")
|
click.echo(f"\nProcessing file {sourcePath}")
|
||||||
|
|
||||||
|
|
||||||
#click.echo(f"ve={video_encoder}")
|
se_result = se_match.search(sourceFilename)
|
||||||
|
s_result = s_match.search(sourceFilename)
|
||||||
|
e_result = e_match.search(sourceFilename)
|
||||||
|
|
||||||
|
|
||||||
#qualityTokens = quality.split(',')
|
|
||||||
|
|
||||||
#q_list = [q for q in qualityTokens if q.isnumeric()]
|
|
||||||
|
|
||||||
#click.echo(q_list)
|
|
||||||
|
|
||||||
#ctx.obj['bitrates'] = {}
|
|
||||||
#ctx.obj['bitrates']['stereo'] = str(stereo_bitrate) if str(stereo_bitrate).endswith('k') else f"{stereo_bitrate}k"
|
|
||||||
#ctx.obj['bitrates']['ac3'] = str(ac3_bitrate) if str(ac3_bitrate).endswith('k') else f"{ac3_bitrate}k"
|
|
||||||
#ctx.obj['bitrates']['dts'] = str(dts_bitrate) if str(dts_bitrate).endswith('k') else f"{dts_bitrate}k"
|
|
||||||
|
|
||||||
|
|
||||||
#click.echo(f"a={ctx.obj['bitrates']['stereo']}")
|
|
||||||
#click.echo(f"ac3={ctx.obj['bitrates']['ac3']}")
|
|
||||||
#click.echo(f"dts={ctx.obj['bitrates']['dts']}")
|
|
||||||
|
|
||||||
|
|
||||||
#performCrop = (crop != 'none')
|
|
||||||
|
|
||||||
|
|
||||||
#if performCrop:
|
|
||||||
|
|
||||||
#cropTokens = crop.split(',')
|
|
||||||
|
|
||||||
#if cropTokens and len(cropTokens) == 2:
|
|
||||||
|
|
||||||
#cropStart, cropLength = crop.split(',')
|
|
||||||
#else:
|
|
||||||
#cropStart = DEFAULT_CROP_START
|
|
||||||
#cropLength = DEFAULT_CROP_LENGTH
|
|
||||||
|
|
||||||
#click.echo(f"crop start={cropStart} length={cropLength}")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#click.echo(f"\nRunning {len(q_list)} jobs")
|
|
||||||
|
|
||||||
|
|
||||||
#streamDescriptor = getStreamDescriptor(sourcePath)
|
#streamDescriptor = getStreamDescriptor(sourcePath)
|
||||||
|
|
||||||
@@ -522,8 +535,10 @@ def convert(ctx, paths, label, video_encoder, quality, preset, stereo_bitrate, a
|
|||||||
#executeProcess(commandSequence2)
|
#executeProcess(commandSequence2)
|
||||||
|
|
||||||
|
|
||||||
app = ModesApp(ctx.obj)
|
#app = ModesApp(ctx.obj)
|
||||||
app.run()
|
#app.run()
|
||||||
|
|
||||||
|
#click.confirm('Warning! This file is not compliant to the defined source schema! Do you want to continue?', abort=True)
|
||||||
|
|
||||||
click.echo('\nDONE\n')
|
click.echo('\nDONE\n')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user