Compare commits
No commits in common. "959d1f5408590ef9c1aa32cf17c01e012c533948" and "eb1ea250eb7492e0f14764507d345e9bdf9656a3" have entirely different histories.
959d1f5408
...
eb1ea250eb
2 changed files with 23 additions and 66 deletions
51
edit.py
51
edit.py
|
@ -1,15 +1,13 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from glob import glob
|
|
||||||
import getpass
|
import getpass
|
||||||
import hashlib
|
|
||||||
import json
|
import json
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
from glob import glob
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
import ox.web.auth
|
import ox.web.auth
|
||||||
|
@ -22,6 +20,7 @@ pandora_client_config = {}
|
||||||
use_local = False
|
use_local = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if os.path.exists('files.json'):
|
if os.path.exists('files.json'):
|
||||||
files = json.load(open('files.json'))
|
files = json.load(open('files.json'))
|
||||||
else:
|
else:
|
||||||
|
@ -105,8 +104,6 @@ def get_pandora_media_path(oshash):
|
||||||
|
|
||||||
def cache_clips(api, videos, use_source=False, use_pandora=False):
|
def cache_clips(api, videos, use_source=False, use_pandora=False):
|
||||||
for clip in videos:
|
for clip in videos:
|
||||||
if clip.get("title"):
|
|
||||||
continue
|
|
||||||
out = '%s/%s.mp4' % (render, clip['oshash'])
|
out = '%s/%s.mp4' % (render, clip['oshash'])
|
||||||
if 'path' in clip:
|
if 'path' in clip:
|
||||||
clip['src'] = clip['path']
|
clip['src'] = clip['path']
|
||||||
|
@ -127,38 +124,6 @@ def cache_clips(api, videos, use_source=False, use_pandora=False):
|
||||||
print(url, out)
|
print(url, out)
|
||||||
api.save_url(url, out)
|
api.save_url(url, out)
|
||||||
|
|
||||||
def make_title(title):
|
|
||||||
from PIL import Image, ImageFont, ImageDraw
|
|
||||||
title_mp4 = "cache/title_%s.mp4" % hashlib.sha1(title.encode()).hexdigest()
|
|
||||||
title_png = title_mp4.replace('.mp4', '.png')
|
|
||||||
if not os.path.exists(title_mp4):
|
|
||||||
width = 852
|
|
||||||
height = 480
|
|
||||||
image = Image.new("RGB", (width, height), "black")
|
|
||||||
font = ImageFont.truetype("/usr/share/fonts/truetype/roboto/unhinted/RobotoTTF/Roboto-Regular.ttf", size=30)
|
|
||||||
draw = ImageDraw.Draw(image)
|
|
||||||
_, _, font_width, font_height = font.getbbox(title)
|
|
||||||
new_width = (width - font_width) / 2
|
|
||||||
new_height = (height - font_height) / 2
|
|
||||||
draw.text((new_width, new_height), title, font=font)
|
|
||||||
image.save(title_png)
|
|
||||||
cmd = [
|
|
||||||
'ffmpeg', '-r', '25',
|
|
||||||
'-i', title_png, '-t', '5',
|
|
||||||
'-pix_fmt', 'yuv420p',
|
|
||||||
title_mp4
|
|
||||||
]
|
|
||||||
subprocess.call(cmd)
|
|
||||||
clip = {
|
|
||||||
"title": title,
|
|
||||||
"in": 0,
|
|
||||||
"out": 5,
|
|
||||||
"duration": 5,
|
|
||||||
"volume": 1.0,
|
|
||||||
"path": title_mp4
|
|
||||||
}
|
|
||||||
return clip
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
usage = "usage: %(prog)s [options] edit-url"
|
usage = "usage: %(prog)s [options] edit-url"
|
||||||
|
@ -169,8 +134,6 @@ if __name__ == '__main__':
|
||||||
help="source, local or site", default='site')
|
help="source, local or site", default='site')
|
||||||
parser.add_argument('-r', '--resolution', dest='stream_resolution', type=int,
|
parser.add_argument('-r', '--resolution', dest='stream_resolution', type=int,
|
||||||
help="resolution of streams to download i.e. 480, 240, 96 default 480", default=480)
|
help="resolution of streams to download i.e. 480, 240, 96 default 480", default=480)
|
||||||
parser.add_argument('-t', '--title', dest='title', type=str,
|
|
||||||
help="title", default="")
|
|
||||||
parser.add_argument('-c', '--config', dest='config',
|
parser.add_argument('-c', '--config', dest='config',
|
||||||
help='config.json containing config',
|
help='config.json containing config',
|
||||||
default='~/.ox/client.json')
|
default='~/.ox/client.json')
|
||||||
|
@ -236,15 +199,7 @@ if __name__ == '__main__':
|
||||||
videos = []
|
videos = []
|
||||||
subtitles = []
|
subtitles = []
|
||||||
position = 0
|
position = 0
|
||||||
clips = sort_clips(edit, sort_by)
|
for clip in sort_clips(edit, sort_by):
|
||||||
if opts.title:
|
|
||||||
clips.insert(0, make_title(opts.title))
|
|
||||||
for clip in clips:
|
|
||||||
if clip.get("title"):
|
|
||||||
videos.append(clip)
|
|
||||||
position += clip['duration']
|
|
||||||
position = math.ceil(position / (1/25)) * 1/25
|
|
||||||
continue
|
|
||||||
clip_out = position + clip['duration']
|
clip_out = position + clip['duration']
|
||||||
clip_subtitles = []
|
clip_subtitles = []
|
||||||
for sub in clip['layers'].get('subtitles', []):
|
for sub in clip['layers'].get('subtitles', []):
|
||||||
|
|
38
ffmpeg.py
38
ffmpeg.py
|
@ -11,22 +11,6 @@ def run(cmd):
|
||||||
#print(' '.join('"%s"' % c for c in cmd))
|
#print(' '.join('"%s"' % c for c in cmd))
|
||||||
subprocess.call(cmd)
|
subprocess.call(cmd)
|
||||||
|
|
||||||
def add_subtitles(subtitles, clip, position, duration):
|
|
||||||
if clip.get('subtitles'):
|
|
||||||
if isinstance(clip['subtitles'], list):
|
|
||||||
for sub in clip['subtitles']:
|
|
||||||
subtitles.append({
|
|
||||||
'in': position + sub['in'],
|
|
||||||
'out': position + sub['out'],
|
|
||||||
'value': sub['value']
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
subtitles.append({
|
|
||||||
'in': position,
|
|
||||||
'out': position + duration,
|
|
||||||
'value': clip['subtitles']
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
usage = "usage: %(prog)s [options] edit.json"
|
usage = "usage: %(prog)s [options] edit.json"
|
||||||
parser = ArgumentParser(usage=usage)
|
parser = ArgumentParser(usage=usage)
|
||||||
|
@ -78,7 +62,12 @@ for clip in edit:
|
||||||
src_duration = clip['out']-clip['in']
|
src_duration = clip['out']-clip['in']
|
||||||
if abs(src_duration-duration) > 1:
|
if abs(src_duration-duration) > 1:
|
||||||
print(clip.get('annotation', clip['item']), 'expected', src_duration, 'got', duration, out)
|
print(clip.get('annotation', clip['item']), 'expected', src_duration, 'got', duration, out)
|
||||||
add_subtitles(subtitles, clip, position, duration)
|
if clip.get('subtitles'):
|
||||||
|
subtitles.append({
|
||||||
|
'in': position,
|
||||||
|
'out': position+duration,
|
||||||
|
'value': clip['subtitles']
|
||||||
|
})
|
||||||
position += duration
|
position += duration
|
||||||
continue
|
continue
|
||||||
src_info = ox.avinfo(clip['path'])
|
src_info = ox.avinfo(clip['path'])
|
||||||
|
@ -153,7 +142,20 @@ for clip in edit:
|
||||||
src_duration = clip['out']-clip['in']
|
src_duration = clip['out']-clip['in']
|
||||||
if abs(src_duration-duration) > 1:
|
if abs(src_duration-duration) > 1:
|
||||||
print(clip.get('annotation', clip['item']), 'expected', src_duration, 'got', duration, out)
|
print(clip.get('annotation', clip['item']), 'expected', src_duration, 'got', duration, out)
|
||||||
add_subtitles(subtitles, clip, position, duration)
|
if clip.get('subtitles'):
|
||||||
|
if isinstance(clip['subtitles'], list):
|
||||||
|
for sub in clip['subtitles']:
|
||||||
|
subtitles.append({
|
||||||
|
'in': position + sub['in'],
|
||||||
|
'out': position + sub['out'],
|
||||||
|
'value': sub['value']
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
subtitles.append({
|
||||||
|
'in': position,
|
||||||
|
'out': position + duration,
|
||||||
|
'value': clip['subtitles']
|
||||||
|
})
|
||||||
position += duration
|
position += duration
|
||||||
|
|
||||||
txt = output + '.txt'
|
txt = output + '.txt'
|
||||||
|
|
Loading…
Reference in a new issue