pandora_cdosea/encode.py

198 lines
5.8 KiB
Python
Raw Permalink Normal View History

2017-02-17 21:42:57 +00:00
#!/usr/bin/python3
2017-10-02 12:28:40 +00:00
from argparse import ArgumentParser
2017-02-17 21:42:57 +00:00
from glob import glob
2017-03-02 21:10:14 +00:00
import json
2017-10-02 12:28:40 +00:00
import os
2017-02-17 21:49:32 +00:00
import shutil
import subprocess
2017-03-20 01:28:18 +00:00
import sys
2017-02-17 21:42:57 +00:00
2017-10-09 09:03:17 +00:00
cleanup = True
2017-03-02 21:10:14 +00:00
def get_videoduration(video):
cmd = [
'ffprobe',
'-show_format',
'-show_chapters',
'-show_streams',
'-print_format', 'json',
'-i', video
]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stdin = p.communicate()
data = json.loads(stdout.decode())
duration = float([s for s in data['streams'] if 'width' in s][0]['duration']) - 70/60
2017-03-02 21:10:14 +00:00
return '%0.3f' % duration
2017-03-15 10:15:45 +00:00
def is_new(xml, mp4):
if not os.path.exists(mp4):
return True
2017-05-16 12:59:51 +00:00
vtime = os.path.getmtime(mp4)
xtime = max(
os.path.getmtime(xml),
2017-03-15 10:15:45 +00:00
os.path.getmtime('text.html'),
2017-03-15 12:00:12 +00:00
os.path.getmtime('DRONES.json'),
os.path.getmtime('VOCALS.json'),
2017-10-05 12:29:37 +00:00
os.path.getmtime('encode.py'),
2017-03-15 10:15:45 +00:00
)
return vtime < xtime
2017-10-02 12:28:40 +00:00
def encode(xml, force=False, prefix='.'):
2017-05-18 14:40:28 +00:00
item_json = xml.replace('.xml', '.json')
2017-02-17 22:07:43 +00:00
audio_xml = xml.replace('.xml', '.audio.xml')
2017-05-16 12:59:51 +00:00
vocals_xml = xml.replace('.xml', '.vocals.xml')
2017-02-17 21:42:57 +00:00
mp4 = xml.replace('.xml', '.mp4')
2017-03-06 08:36:39 +00:00
mp4_480p = mp4.replace('.mp4', '.480p.mp4')
2017-05-16 12:59:51 +00:00
video = mp4 + '.v.mov'
amix = mp4 + '.amix.mp4'
2017-02-17 21:49:32 +00:00
audio = mp4 + '.wav'
2017-05-16 12:59:51 +00:00
vocals = mp4 + '.vocals.wav'
silence = 'silence_mono.wav'
left = video + '_left.wav'
right = video + '_right.wav'
2017-10-02 12:28:40 +00:00
public_mp4 = os.path.join(prefix, 'public', mp4.split('/')[-1][0].lower() + mp4.split('/')[-2] + '.1080p.mp4')
2017-05-16 12:59:51 +00:00
public_mp4_480p = public_mp4.replace('.1080p.mp4', '.480p.mp4')
2017-10-09 09:03:17 +00:00
gongs = 'performance' in prefix
gongs_wav = mp4.replace('.mp4', '.gongs.wav')
gongs_left = mp4.replace('.mp4', '.gongs.right.wav')
gongs_right = mp4.replace('.mp4', '.gongs.left.wav')
force = True
2017-10-05 12:29:37 +00:00
2017-05-16 12:59:51 +00:00
if force or is_new(xml, public_mp4):
2017-10-05 12:29:37 +00:00
print(public_mp4)
2017-05-16 12:59:51 +00:00
cmd = [
'qmelt', xml, '-consumer',
'avformat:' + video,
'vcodec=libx264',
'acodec=pcm_s16le'
]
2017-10-09 09:03:17 +00:00
if is_new(xml, video):
subprocess.call(cmd)
2017-03-06 08:36:39 +00:00
duration = get_videoduration(video)
2017-05-16 12:59:51 +00:00
cmd = [
'ffmpeg', '-y', '-i', video,
'-map_channel', '0.1.0', left,
'-map_channel', '0.1.1', right,
]
subprocess.call(cmd)
2017-10-09 09:03:17 +00:00
if gongs:
cmd = [
'ffmpeg', '-y', '-i', gongs_wav,
'-map_channel', '0.0.0', gongs_left,
'-map_channel', '0.0.1', gongs_right,
]
subprocess.call(cmd)
2017-05-16 12:59:51 +00:00
cmd = [
'qmelt', vocals_xml, '-consumer',
'avformat:' + vocals,
'acodec=pcm_s16le',
'ac=1'
]
2017-10-09 09:03:17 +00:00
if is_new(xml, vocals):
subprocess.call(cmd)
2017-05-21 11:55:53 +00:00
#for wav in (left, right, vocals):
# cmd = ['normalize-audio', wav]
# subprocess.call(cmd)
2017-10-09 09:03:17 +00:00
front_left = left
front_right = left
front_center = vocals
lfe = silence
back_left = vocals
back_right = vocals
if gongs:
back_left = gongs_left
back_right = gongs_right
2017-05-16 12:59:51 +00:00
cmd = [
'ffmpeg', '-y',
2017-10-09 09:03:17 +00:00
'-i', front_left, # FL
'-i', front_right, # FR
'-i', front_center, # FC
'-i', lfe, # LFE
'-i', back_left, # BL
'-i', back_right, # BR
2017-05-16 12:59:51 +00:00
'-filter_complex',
'[0:0][1:0][2:0][3:0][4:0][5:0] amerge=inputs=6[aout]',
'-map', "[aout]",
'-strict', '-2',
'-c:a', 'aac',
amix
]
subprocess.call(cmd)
2017-10-09 09:03:17 +00:00
if cleanup:
os.unlink(left)
os.unlink(right)
os.unlink(vocals)
if gongs:
os.unlink(gongs_left)
os.unlink(gongs_right)
2017-05-16 12:59:51 +00:00
2017-02-17 22:27:12 +00:00
cmd = [
2017-02-17 21:42:57 +00:00
'ffmpeg', '-y',
2017-02-17 21:49:32 +00:00
'-i', video,
2017-05-16 12:59:51 +00:00
'-i', amix,
'-t', duration,
2017-03-06 08:36:39 +00:00
'-c:a', 'copy',
2017-02-17 22:27:12 +00:00
'-c:v', 'copy',
2017-05-16 12:59:51 +00:00
'-map', '0:v:0', '-map', '1:a:0',
2017-03-06 08:36:39 +00:00
'-movflags', '+faststart',
2017-05-16 12:59:51 +00:00
mp4
2017-02-17 22:27:12 +00:00
]
subprocess.call(cmd)
2017-10-09 09:03:17 +00:00
if cleanup:
os.unlink(video)
os.unlink(amix)
if is_new(mp4, public_mp4_480p):
cmd = [
'ffmpeg', '-y',
'-i', mp4,
'-c:a', 'copy',
'-vf', 'scale=854:480',
'-c:v', 'libx264',
'-preset', 'medium',
'-b:v', '750k',
'-profile:v', 'high',
'-movflags', '+faststart',
mp4_480p
]
subprocess.call(cmd)
shutil.move(mp4_480p, public_mp4_480p)
2017-05-16 12:59:51 +00:00
shutil.move(mp4, public_mp4)
2017-05-20 15:32:51 +00:00
cmd = [
'./subtitles.py',
2017-10-02 12:42:04 +00:00
'--prefix', prefix,
2017-05-20 15:32:51 +00:00
item_json
2017-05-17 10:15:28 +00:00
]
subprocess.call(cmd)
2017-10-05 12:29:37 +00:00
else:
print('skip', public_mp4)
2017-03-20 01:28:18 +00:00
2017-10-02 12:28:40 +00:00
def encode_all(prefix):
for xml in sorted(glob(os.path.join(prefix, 'output/*/*.xml'))):
2017-05-16 12:59:51 +00:00
parts = xml.split('.')
if len(parts) > 2 and parts[-2] in (
'audio',
'drones',
'music',
'source',
'vocals',
):
2017-03-20 01:28:18 +00:00
continue
2017-10-02 12:28:40 +00:00
encode(xml, prefix=prefix)
2017-03-20 01:28:18 +00:00
if __name__ == '__main__':
2017-10-02 12:28:40 +00:00
usage = "usage: %(prog)s [options] xml"
parser = ArgumentParser(usage=usage)
parser.add_argument('-p', '--prefix', dest='prefix',
help='version prefix', default='.')
parser.add_argument('files', metavar='path', type=str, nargs='*', help='xml files')
opts = parser.parse_args()
if opts.files:
for xml in opts.files:
encode(xml, True, prefix=opts.prefix)
2017-03-20 01:28:18 +00:00
else:
2017-10-02 12:28:40 +00:00
encode_all(prefix=opts.prefix)