diff --git a/edit.py b/edit.py
index ae643a6..f659a6d 100755
--- a/edit.py
+++ b/edit.py
@@ -1,6 +1,7 @@
#!/usr/bin/python3
import os
import json
+import math
import ox
import ox.web.auth
@@ -46,7 +47,7 @@ def sort_clips(edit, sort):
'id', 'index', 'in', 'out', 'duration',
'title', 'director', 'year', 'videoRatio'
]:
- s = sorted(clips, key=lambda c: (str(c.get(sort, last)), c['in'], c['out']))
+ s = sorted(clips, key=lambda c: (str(c.get(sort, last)), c['title'], c['in'], c['out']))
if reverse:
s = reversed(s)
else:
@@ -77,6 +78,15 @@ if __name__ == '__main__':
position = 0
for clip in sort_clips(edit, sort_by):
+ clip_subtitles = []
+ for sub in clip['layers']['subtitles']:
+ subtitles.append({
+ 'in': position,
+ 'out': position + (sub['out'] - sub['in']),
+ 'value': sub['value'].replace('
', '\n').replace('
', '\n').replace('\n\n', '\n'),
+ })
+ clip_subtitles.append(sub['value'].replace('
', '\n').replace('
', '\n').replace('\n\n', '\n'))
+
part_pos = 0
for i, duration in enumerate(clip['durations']):
if part_pos + duration < clip['in']:
@@ -84,6 +94,10 @@ if __name__ == '__main__':
elif part_pos <= clip['in']:
stream_in = clip['in'] - part_pos
stream_out = min(clip['out'] - part_pos, duration)
+
+ stream_in = math.ceil(stream_in / (1/25)) * 1/25
+ stream_out = math.ceil(stream_out / (1/25)) * 1/25
+
part_pos += duration
info = get_info(api, clip['streams'][i])
videos.append({
@@ -91,11 +105,14 @@ if __name__ == '__main__':
'path': os.path.join(prefix, info['path']),
'resolution': info['resolution'],
'in': stream_in,
- 'out': stream_out
+ 'out': stream_out,
+ 'subtitles': '\n'.join(clip_subtitles)
})
elif clip['out'] > part_pos:
stream_in = part_pos
stream_out = min(clip['out'] - part_pos, duration)
+ stream_in = math.ceil(stream_in / (1/25)) * 1/25
+ stream_out = math.ceil(stream_out / (1/25)) * 1/25
part_pos += duration
info = get_info(api, clip['streams'][i])
videos.append({
@@ -103,17 +120,13 @@ if __name__ == '__main__':
'path': info['path'],
'resolution': info['resolution'],
'in': stream_in,
- 'out': stream_out
+ 'out': stream_out,
+ 'subtitles': '\n'.join(clip_subtitles)
})
- for sub in clip['layers']['subtitles']:
- subtitles.append({
- 'in': position,
- 'out': position + (sub['out'] - sub['in']),
- 'value': sub['value'].replace('
', '\n').replace('
', '\n').replace('\n\n', '\n'),
- })
position += clip['duration']
+ position = math.ceil(position / (1/25)) * 1/25
name = normalize(edit_id)
if sort_by != 'year':
diff --git a/ffmpeg.py b/ffmpeg.py
index 2eed9a0..31dae70 100755
--- a/ffmpeg.py
+++ b/ffmpeg.py
@@ -3,6 +3,7 @@ import json
import os
import subprocess
import sys
+import ox
def run(cmd):
#print(' '.join('"%s"' % c for c in cmd))
@@ -12,7 +13,7 @@ def run(cmd):
edit_json = sys.argv[1]
edit = json.load(open(edit_json))
-render = '/tmp/out'
+render = './cache'
output = os.path.splitext(edit_json)[0] + '.mp4'
height = 480
aspect = 16/9
@@ -23,10 +24,23 @@ if not os.path.exists(render):
os.makedirs(render)
files = []
+edit_duration = 0
+subtitles = []
+position = 0
for clip in edit:
out = render + '/%s_%0.3f-%0.3f.ts' % (clip['oshash'], clip['in'], clip['out'])
+ edit_duration += (clip['out']-clip['in'])
files.append(out)
if os.path.exists(out):
+ duration = ox.avinfo(out)['duration']
+ if clip['subtitles']:
+ subtitles.append({
+ 'in': position,
+ 'out': position+duration,
+ 'value': clip['subtitles']
+ })
+ position += duration
+ print(out, duration, (clip['out'] - clip['in']))
continue
clip_aspect = clip['resolution'][0] / clip['resolution'][1]
if clip_aspect < aspect:
@@ -44,12 +58,14 @@ for clip in edit:
offset = int(((y - height) / 3))
vf += ',crop=w=%s:h=%s:x=0:y=%s' % (width, height, offset)
options = [
+ '-map_metadata', '-1',
'-vf', vf,
'-aspect', str(aspect),
'-c:v', 'libx264',
'-b:v', '2M',
'-preset:v', 'medium', '-profile:v', 'high', '-level:v', '4.0',
- '-r:v', '25',
+ '-map', '0:0,0:0', '-map', '0:1,0:1',
+ '-r', '25',
'-c:a', 'aac',
'-ar', '48000',
'-ac', '2',
@@ -65,6 +81,15 @@ for clip in edit:
out
]
run(cmd)
+ duration = ox.avinfo(out)['duration']
+ if clip['subtitles']:
+ subtitles.append({
+ 'in': position,
+ 'out': position+duration,
+ 'value': clip['subtitles']
+ })
+ position += duration
+ print(out, duration, (clip['out'] - clip['in']))
txt = output + '.txt'
with open(txt, 'w') as fd:
@@ -72,3 +97,12 @@ with open(txt, 'w') as fd:
cmd = ['ffmpeg', '-y', '-f', 'concat', '-safe', '0', '-i', txt, '-c', 'copy', output]
run(cmd)
os.unlink(txt)
+
+srt = output.replace('.mp4', '.srt')
+
+with open(srt, 'wb') as fd:
+ fd.write(ox.srt.encode(subtitles))
+
+duration = ox.avinfo(output)['duration']
+print('file is %d, edit should be %d' % (duration, edit_duration))
+