diff --git a/edit.py b/edit.py index bb75505..76ed945 100755 --- a/edit.py +++ b/edit.py @@ -1,13 +1,15 @@ #!/usr/bin/env python3 from argparse import ArgumentParser +from glob import glob import getpass +import hashlib import json import math import os +import subprocess import sys import urllib.parse import urllib.request -from glob import glob import ox import ox.web.auth @@ -20,7 +22,6 @@ pandora_client_config = {} use_local = False - if os.path.exists('files.json'): files = json.load(open('files.json')) else: @@ -104,6 +105,8 @@ def get_pandora_media_path(oshash): def cache_clips(api, videos, use_source=False, use_pandora=False): for clip in videos: + if clip.get("title"): + continue out = '%s/%s.mp4' % (render, clip['oshash']) if 'path' in clip: clip['src'] = clip['path'] @@ -124,6 +127,38 @@ def cache_clips(api, videos, use_source=False, use_pandora=False): print(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__': usage = "usage: %(prog)s [options] edit-url" @@ -134,6 +169,8 @@ if __name__ == '__main__': help="source, local or site", default='site') 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) + parser.add_argument('-t', '--title', dest='title', type=str, + help="title", default="") parser.add_argument('-c', '--config', dest='config', help='config.json containing config', default='~/.ox/client.json') @@ -199,7 +236,15 @@ if __name__ == '__main__': videos = [] subtitles = [] position = 0 - for clip in sort_clips(edit, sort_by): + clips = 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_subtitles = [] for sub in clip['layers'].get('subtitles', []): diff --git a/ffmpeg.py b/ffmpeg.py index 4946fb3..1f19a9a 100755 --- a/ffmpeg.py +++ b/ffmpeg.py @@ -11,6 +11,22 @@ def run(cmd): #print(' '.join('"%s"' % c for c in 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" parser = ArgumentParser(usage=usage) @@ -62,12 +78,7 @@ for clip in edit: src_duration = clip['out']-clip['in'] if abs(src_duration-duration) > 1: print(clip.get('annotation', clip['item']), 'expected', src_duration, 'got', duration, out) - if clip.get('subtitles'): - subtitles.append({ - 'in': position, - 'out': position+duration, - 'value': clip['subtitles'] - }) + add_subtitles(subtitles, clip, position, duration) position += duration continue src_info = ox.avinfo(clip['path']) @@ -142,20 +153,7 @@ for clip in edit: src_duration = clip['out']-clip['in'] if abs(src_duration-duration) > 1: print(clip.get('annotation', clip['item']), 'expected', src_duration, 'got', duration, out) - 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'] - }) + add_subtitles(subtitles, clip, position, duration) position += duration txt = output + '.txt'