added poster for 6th Kyu
This commit is contained in:
@@ -9,6 +9,29 @@ import sys
|
||||
import argparse
|
||||
import os
|
||||
|
||||
# bitrate recommendations as from https://developers.google.com/media/vp9/settings/vod
|
||||
bitrateProfiles = {
|
||||
"240": {"heigth": 240, "bitrate": "150k", "minrate": "75k", "maxrate": "218k"},
|
||||
"360": {"heigth": 360, "bitrate": "276k", "minrate": "138k", "maxrate": "400k"},
|
||||
"480LQ": {"heigth": 480, "bitrate": "512k", "minrate": "256k", "maxrate": "742k"},
|
||||
"480MQ": {"heigth": 480, "bitrate": "750k", "minrate": "375k", "maxrate": "1088k"},
|
||||
"720@30": {"heigth": 720, "bitrate": "1024k", "minrate": "512k", "maxrate": "1485k"},
|
||||
"720@60": {"heigth": 720, "bitrate": "1800k", "minrate": "900k", "maxrate": "2610k"},
|
||||
"1080@30": {"heigth": 1080, "bitrate": "1800k", "minrate": "900k", "maxrate": "2610k"},
|
||||
"1080@60": {"heigth": 1080, "bitrate": "3000k", "minrate": "1500k", "maxrate": "4350k"},
|
||||
"1440@30": {"heigth": 1440, "bitrate": "6000k", "minrate": "3000k", "maxrate": "8700k"},
|
||||
"1440@60": {"heigth": 1440, "bitrate": "9000k", "minrate": "4500k", "maxrate": "13050k"},
|
||||
"2160@30": {"heigth": 2160, "bitrate": "12000k", "minrate": "6000k", "maxrate": "17400k"},
|
||||
"2160@60": {"heigth": 2160, "bitrate": "18000k", "minrate": "9000k", "maxrate": "26100k"},
|
||||
}
|
||||
|
||||
config = {
|
||||
'vcodec': "vp9",
|
||||
'acodec': "libopus",
|
||||
'bitrateProfile': "480LQ",
|
||||
'quality': "best",
|
||||
}
|
||||
|
||||
def generate_thumbnail(in_filename, out_filename, time, height):
|
||||
try:
|
||||
(
|
||||
@@ -24,22 +47,99 @@ def generate_thumbnail(in_filename, out_filename, time, height):
|
||||
sys.exit(1)
|
||||
|
||||
# setting width and height from hardcoded defaults -> configured defaults -> clip
|
||||
def getDimensions(config, clip):
|
||||
h = config['height'] if 'height' in config else 480
|
||||
w = config['width'] if 'width' in config else -2
|
||||
def getDimensions(config, clip, bitrateProfiles):
|
||||
# set width and height to a default
|
||||
w, h = -2, 480
|
||||
# set the height by the bitrateProfile
|
||||
try:
|
||||
h = bitrateProfiles[config['bitrateProfile']]
|
||||
except:
|
||||
pass
|
||||
# overwrite it with the scaling
|
||||
if 'scale' in clip:
|
||||
h = clip['scale']['h'] if 'h' in clip['scale'] else h
|
||||
w = clip['scale']['w'] if 'w' in clip['scale'] else w
|
||||
|
||||
return h, w
|
||||
return w, h
|
||||
|
||||
def twoPassEncode(inputFilename, clip):
|
||||
# cutting
|
||||
kwArgs = {}
|
||||
if 'from' in clip:
|
||||
kwArgs['ss'] = clip['from']
|
||||
if 'to' in clip:
|
||||
kwArgs['to'] = clip['to']
|
||||
|
||||
stream = ffmpeg.input( inputFilename, **kwArgs)
|
||||
|
||||
video, audio = stream.video, stream.audio
|
||||
|
||||
if 'crop' in clip:
|
||||
stream = ffmpeg.filter(stream,
|
||||
"crop",
|
||||
x=clip['crop']['x'],
|
||||
y=clip['crop']['y'],
|
||||
w=clip['crop']['w'],
|
||||
h=clip['crop']['h']
|
||||
)
|
||||
|
||||
stream = ffmpeg.output(stream,
|
||||
clip['target'],
|
||||
vcodec=config['vcodec'],
|
||||
**{
|
||||
# "an":None,
|
||||
"y": None,
|
||||
"pass": "1",
|
||||
"b:v": bitrateProfile[config['bitrateProfile']['bitrate']],
|
||||
"minrate": bitrateProfile[config['bitrateProfile']['minrate']],
|
||||
"maxrate": bitrateProfile[config['bitrateProfile']['maxrate']],
|
||||
"quality": config['quality'] if 'quality' in config else "best",
|
||||
}
|
||||
)
|
||||
try:
|
||||
ffmpeg.run(stream)
|
||||
except:
|
||||
print(infoDict)
|
||||
|
||||
|
||||
config = {
|
||||
'vcodec': "vp9",
|
||||
'acodec': "libopus",
|
||||
'height': 480,
|
||||
'quality': "best",
|
||||
}
|
||||
if 'from' in clip and 'to' in clip:
|
||||
stream = ffmpeg.input(
|
||||
glob.glob(infoDict['id']+"*")[0],
|
||||
ss=clip['from'],
|
||||
to=clip['to'],
|
||||
)
|
||||
else:
|
||||
stream = ffmpeg.input(
|
||||
glob.glob(infoDict['id']+"*")[0]
|
||||
)
|
||||
if 'crop' in clip:
|
||||
stream = ffmpeg.filter(stream,
|
||||
"crop",
|
||||
x=clip['crop']['x'],
|
||||
y=clip['crop']['y'],
|
||||
w=clip['crop']['w'],
|
||||
h=clip['crop']['h']
|
||||
)
|
||||
|
||||
h, w = getDimensions(config, clip)
|
||||
|
||||
stream = ffmpeg.output(stream, audio,
|
||||
clip['target'],
|
||||
vcodec=config['vcodec'],
|
||||
**{
|
||||
"y": None,
|
||||
"pass": "2",
|
||||
"b:v": bitrateProfile[config['bitrateProfile']['bitrate']],
|
||||
"minrate": bitrateProfile[config['bitrateProfile']['minrate']],
|
||||
"maxrate": bitrateProfile[config['bitrateProfile']['maxrate']],
|
||||
"quality": config['quality'] if 'quality' in config else "best",
|
||||
"acodec": config['acodec'],
|
||||
}
|
||||
)
|
||||
try:
|
||||
ffmpeg.run(stream)
|
||||
except:
|
||||
print(infoDict)
|
||||
|
||||
|
||||
argParser = argparse.ArgumentParser()
|
||||
@@ -69,88 +169,10 @@ for clip in clipDict:
|
||||
# @todo This is a very bad hack because the outtmpl options doesn't seem to be working if the file gets reencoded
|
||||
inputFilename = glob.glob(infoDict['id']+"*")[0]
|
||||
|
||||
h, w = getDimensions(config, clip)
|
||||
w, h = getDimensions(config, clip)
|
||||
|
||||
# generate preview image for the video
|
||||
if 'poster' in clip:
|
||||
generate_thumbnail(inputFilename, os.path.splitext(clip['target'])[0]+".jpg", clip['poster']['timeIndex'], h )
|
||||
|
||||
kwArgs = {}
|
||||
if 'from' in clip:
|
||||
kwArgs['ss'] = clip['from']
|
||||
if 'to' in clip:
|
||||
kwArgs['to'] = clip['to']
|
||||
|
||||
stream = ffmpeg.input( inputFilename, **kwArgs)
|
||||
|
||||
video, audio = stream.video, stream.audio
|
||||
|
||||
if 'crop' in clip:
|
||||
stream = ffmpeg.filter(stream,
|
||||
"crop",
|
||||
x=clip['crop']['x'],
|
||||
y=clip['crop']['y'],
|
||||
w=clip['crop']['w'],
|
||||
h=clip['crop']['h']
|
||||
)
|
||||
|
||||
stream = ffmpeg.output(stream,
|
||||
clip['target'],
|
||||
vcodec=config['vcodec'],
|
||||
**{
|
||||
# "an":None,
|
||||
"y":None,
|
||||
"pass":"1",
|
||||
# "b:v":"276k", "minrate":"138k", "maxrate":"400k", # x360
|
||||
"b:v":"512k", "minrate":"256k", "maxrate":"742k", # x480 LQ
|
||||
# "b:v":"750k", "minrate":"375k", "maxrate":"1088k", # x480 MQ
|
||||
"quality": config['quality'] if 'quality' in config else "best",
|
||||
}
|
||||
)
|
||||
try:
|
||||
ffmpeg.run(stream)
|
||||
except:
|
||||
print(infoDict)
|
||||
|
||||
|
||||
if 'from' in clip and 'to' in clip:
|
||||
stream = ffmpeg.input(
|
||||
glob.glob(infoDict['id']+"*")[0],
|
||||
ss=clip['from'],
|
||||
to=clip['to'],
|
||||
)
|
||||
else:
|
||||
stream = ffmpeg.input(
|
||||
glob.glob(infoDict['id']+"*")[0]
|
||||
)
|
||||
if 'crop' in clip:
|
||||
stream = ffmpeg.filter(stream,
|
||||
"crop",
|
||||
x=clip['crop']['x'],
|
||||
y=clip['crop']['y'],
|
||||
w=clip['crop']['w'],
|
||||
h=clip['crop']['h']
|
||||
)
|
||||
|
||||
h, w = getDimensions(config, clip)
|
||||
|
||||
stream = ffmpeg.output(stream, audio,
|
||||
clip['target'],
|
||||
vcodec=config['vcodec'],
|
||||
**{
|
||||
# "an":None,
|
||||
"y":None,
|
||||
"pass":"2",
|
||||
# "b:v":"276k", "minrate":"138k", "maxrate":"400k", # x360
|
||||
"b:v":"512k", "minrate":"256k", "maxrate":"742k", # x480 LQ
|
||||
# "b:v":"750k", "minrate":"375k", "maxrate":"1088k", # x480 MQ
|
||||
"quality": config['quality'] if 'quality' in config else "best",
|
||||
"acodec": config['acodec'],
|
||||
}
|
||||
)
|
||||
try:
|
||||
ffmpeg.run(stream)
|
||||
except:
|
||||
print(infoDict)
|
||||
|
||||
exit(-1)
|
||||
twoPassEncode(inputFilename, clip)
|
||||
Reference in New Issue
Block a user