cutter: Allow fast or full cuts per location

On full cut, use encoding settings determined by the backend.
pull/103/head
Mike Lang 5 years ago
parent 09887f17ab
commit 1218b694dd

@ -16,7 +16,7 @@ from psycopg2 import sql
import common import common
from common.database import DBManager, query from common.database import DBManager, query
from common.segments import get_best_segments, fast_cut_segments, ContainsHoles from common.segments import get_best_segments, fast_cut_segments, full_cut_segments, ContainsHoles
from .upload_backends import Youtube, Local from .upload_backends import Youtube, Local
@ -267,7 +267,13 @@ class Cutter(object):
upload_backend = self.upload_locations[job.upload_location] upload_backend = self.upload_locations[job.upload_location]
self.logger.info("Cutting and uploading job {} to {}".format(format_job(job), upload_backend)) self.logger.info("Cutting and uploading job {} to {}".format(format_job(job), upload_backend))
cut = fast_cut_segments(job.segments, job.video_start, job.video_end)
if upload_backend.encoding_settings is None:
self.logger.debug("No encoding settings, using fast cut")
cut = fast_cut_segments(job.segments, job.video_start, job.video_end)
else:
self.logger.debug("Using encoding settings for cut: {}".format(upload_backend.encoding_settings))
cut = full_cut_segments(job.segments, job.video_start, job.video_end, upload_backend.encoding_settings)
# This flag tracks whether we've told requests to finalize the upload, # This flag tracks whether we've told requests to finalize the upload,
# and serves to detect whether errors from the request call are recoverable. # and serves to detect whether errors from the request call are recoverable.
@ -550,6 +556,9 @@ def main(
This is useful when multiple upload locations actually refer to the This is useful when multiple upload locations actually refer to the
same place just with different settings, and you only want one of them same place just with different settings, and you only want one of them
to actually do the check. to actually do the check.
cut_type:
One of 'fast' or 'full'. Default 'fast'. This indicates whether to use
fast_cut_segments() or full_cut_segments() for this location.
along with any additional config options defined for that backend type. along with any additional config options defined for that backend type.
creds_file should contain any required credentials for the upload backends, as JSON. creds_file should contain any required credentials for the upload backends, as JSON.
@ -608,6 +617,7 @@ def main(
for location, backend_config in config.items(): for location, backend_config in config.items():
backend_type = backend_config.pop('type') backend_type = backend_config.pop('type')
no_transcode_check = backend_config.pop('no_transcode_check', False) no_transcode_check = backend_config.pop('no_transcode_check', False)
cut_type = backend_config.pop('cut_type', 'fast')
if type == 'youtube': if type == 'youtube':
backend_type = Youtube backend_type = Youtube
elif type == 'local': elif type == 'local':
@ -615,6 +625,11 @@ def main(
else: else:
raise ValueError("Unknown upload backend type: {!r}".format(type)) raise ValueError("Unknown upload backend type: {!r}".format(type))
backend = backend_type(credentials, **backend_config) backend = backend_type(credentials, **backend_config)
if cut_type == 'fast':
# mark for fast cut by clearing encoding settings
backend.encoding_settings = None
elif cut_type != 'full':
raise ValueError("Unknown cut type: {!r}".format(cut_type))
upload_locations[location] = backend upload_locations[location] = backend
if backend.needs_transcode and not no_transcode_check: if backend.needs_transcode and not no_transcode_check:
needs_transcode_check.append(backend) needs_transcode_check.append(backend)

@ -31,12 +31,14 @@ class UploadBackend(object):
The upload backend also determines the encoding settings for the cutting The upload backend also determines the encoding settings for the cutting
process, this is given as a list of ffmpeg args process, this is given as a list of ffmpeg args
under the 'encoding_settings' attribute. under the 'encoding_settings' attribute.
If this is None, instead uses the 'fast cut' strategy where nothing
is transcoded.
""" """
needs_transcode = False needs_transcode = False
# reasonable default if settings don't otherwise matter # reasonable default if settings don't otherwise matter
encoding_settings = [] # TODO encoding_settings = ['-f', 'mp4']
def upload_video(self, title, description, tags, data): def upload_video(self, title, description, tags, data):
raise NotImplementedError raise NotImplementedError
@ -59,7 +61,18 @@ class Youtube(UploadBackend):
""" """
needs_transcode = True needs_transcode = True
encoding_settings = [] # TODO youtube's recommended settings encoding_settings = [
# Youtube's recommended settings:
'-codec:v', 'libx264', # Make the video codec x264
'-crf', '21', # Set the video quality, this produces the bitrate range that YT likes
'-bf', '2', # Have 2 consecutive bframes, as requested
'-flags', '+cgop', # Use closed GOP, as requested
'-pix_fmt', 'yuv420p', # chroma subsampling 4:2:0, as requrested
'-codec:a', 'aac', '-strict', '-2', # audio codec aac, as requested
'-b:a', '384k' # audio bitrate at 348k for 2 channel, use 512k if 5.1 audio
'-r:a', '48000', # set audio sample rate at 48000Hz, as requested
'-movflags', 'faststart', # put MOOV atom at the front of the file, as requested
]
def __init__(self, credentials, hidden=False, category_id=23, language="en"): def __init__(self, credentials, hidden=False, category_id=23, language="en"):
self.logger = logging.getLogger(type(self).__name__) self.logger = logging.getLogger(type(self).__name__)

Loading…
Cancel
Save