render music/vocals
This commit is contained in:
parent
afb4454bfc
commit
9dda2f1c34
2 changed files with 101 additions and 0 deletions
24
encode.py
Executable file
24
encode.py
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
from glob import glob
|
||||||
|
|
||||||
|
for xml in glob('output/*.xml'):
|
||||||
|
mp4 = xml.replace('.xml', '.mp4')
|
||||||
|
if not os.path.exists(mp4) or os.path.getmtime(xml) > os.path.getmtime(mp4):
|
||||||
|
subprocess.call([
|
||||||
|
'qmelt', xml, '-consumer', 'avformat:' + mp4 + '.mp4', 'vcodec=libx264'
|
||||||
|
])
|
||||||
|
subprocess.call([
|
||||||
|
'qmelt', xml, '-consumer', 'avformat:' + mp4 + '.wav',
|
||||||
|
])
|
||||||
|
subprocess.call([
|
||||||
|
'ffmpeg', '-y',
|
||||||
|
'-i', mp4 + '.mp4',
|
||||||
|
'-i', mp4 + '.wav',
|
||||||
|
'-c:v', 'copy',
|
||||||
|
'-map', '0:v',
|
||||||
|
'-map', '1:a',
|
||||||
|
'-strict', '-2',
|
||||||
|
mp4
|
||||||
|
])
|
77
render.py
77
render.py
|
@ -3,6 +3,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from collections import defaultdict
|
||||||
import string
|
import string
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
||||||
|
@ -14,6 +15,8 @@ import ox.web.auth
|
||||||
|
|
||||||
base_url = 'https://cdosea.0x2620.org'
|
base_url = 'https://cdosea.0x2620.org'
|
||||||
|
|
||||||
|
FRAME_DURATION = 1/60
|
||||||
|
|
||||||
api = None
|
api = None
|
||||||
|
|
||||||
def get_api():
|
def get_api():
|
||||||
|
@ -32,6 +35,34 @@ if os.path.exists('CLIPS.json'):
|
||||||
else:
|
else:
|
||||||
CLIPS = {}
|
CLIPS = {}
|
||||||
|
|
||||||
|
if not os.path.exists('MUSIC.json'):
|
||||||
|
MUSIC = defaultdict(list)
|
||||||
|
for letter in os.listdir('music'):
|
||||||
|
for d in range(10):
|
||||||
|
path = os.path.join('music', letter, '%d.mp3' % d)
|
||||||
|
MUSIC[letter].append({
|
||||||
|
'path': path,
|
||||||
|
'duration': ox.avinfo(path)['duration']
|
||||||
|
})
|
||||||
|
with open('MUSIC.json', 'w') as fd:
|
||||||
|
json.dump(MUSIC, fd, indent=2)
|
||||||
|
else:
|
||||||
|
MUSIC = json.load(open('MUSIC.json'))
|
||||||
|
|
||||||
|
if not os.path.exists('VOCALS.json'):
|
||||||
|
VOCALS = defaultdict(list)
|
||||||
|
for letter in os.listdir('vocals'):
|
||||||
|
for fn in sorted(os.listdir(os.path.join('vocals', letter))):
|
||||||
|
path = os.path.join('vocals', letter, fn)
|
||||||
|
VOCALS[letter].append({
|
||||||
|
'path': path,
|
||||||
|
'duration': ox.avinfo(path)['duration']
|
||||||
|
})
|
||||||
|
with open('VOCALS.json', 'w') as fd:
|
||||||
|
json.dump(VOCALS, fd, indent=2)
|
||||||
|
else:
|
||||||
|
VOCALS = json.load(open('VOCALS.json'))
|
||||||
|
|
||||||
def get_path(id):
|
def get_path(id):
|
||||||
global PATHS
|
global PATHS
|
||||||
if id not in PATHS:
|
if id not in PATHS:
|
||||||
|
@ -81,6 +112,9 @@ def get_clips(tag):
|
||||||
'range': [0, 10000]})['data']['items']
|
'range': [0, 10000]})['data']['items']
|
||||||
for clip in clips:
|
for clip in clips:
|
||||||
clip['path'] = get_path(clip['id'].split('/')[0])
|
clip['path'] = get_path(clip['id'].split('/')[0])
|
||||||
|
# or use round?
|
||||||
|
clip['in'] = int(clip['in'] / FRAME_DURATION) * FRAME_DURATION
|
||||||
|
clip['out'] = int(clip['out'] / FRAME_DURATION) * FRAME_DURATION
|
||||||
clip['duration'] = clip['out'] - clip['in']
|
clip['duration'] = clip['out'] - clip['in']
|
||||||
clip['tag'] = tag
|
clip['tag'] = tag
|
||||||
CLIPS[tag] = list(sorted(clips, key=lambda c: c['id']))
|
CLIPS[tag] = list(sorted(clips, key=lambda c: c['id']))
|
||||||
|
@ -147,6 +181,8 @@ def sequence(seq, letter):
|
||||||
result = {
|
result = {
|
||||||
'clips': [],
|
'clips': [],
|
||||||
'text': [],
|
'text': [],
|
||||||
|
'vocals': [],
|
||||||
|
'music': [],
|
||||||
}
|
}
|
||||||
duration = 0
|
duration = 0
|
||||||
MAX_DURATION = 65 * 2
|
MAX_DURATION = 65 * 2
|
||||||
|
@ -175,6 +211,8 @@ def sequence(seq, letter):
|
||||||
for clip in result['clips']:
|
for clip in result['clips']:
|
||||||
if seq() == 0:
|
if seq() == 0:
|
||||||
clip['black'] = True
|
clip['black'] = True
|
||||||
|
|
||||||
|
# text overlay
|
||||||
position = last_text = 0
|
position = last_text = 0
|
||||||
tags_text = []
|
tags_text = []
|
||||||
while position < duration:
|
while position < duration:
|
||||||
|
@ -203,6 +241,45 @@ def sequence(seq, letter):
|
||||||
blank = {'blank': True, 'duration': duration - last_text}
|
blank = {'blank': True, 'duration': duration - last_text}
|
||||||
result['text'].append(blank)
|
result['text'].append(blank)
|
||||||
|
|
||||||
|
# music
|
||||||
|
if letter in MUSIC:
|
||||||
|
position = last_music = 0
|
||||||
|
while position < duration:
|
||||||
|
n = seq()
|
||||||
|
if n == 0:
|
||||||
|
blank = {'blank': True, 'duration': position - last_music}
|
||||||
|
result['music'].append(blank)
|
||||||
|
n = seq()
|
||||||
|
|
||||||
|
clip = MUSIC[letter][n]
|
||||||
|
position += clip['duration']
|
||||||
|
if position > duration and result['music'][-1].get('blank'):
|
||||||
|
result['music'][-1]['duration'] -= (position-duration)
|
||||||
|
position = duration
|
||||||
|
result['music'].append(clip)
|
||||||
|
last_music = position
|
||||||
|
else:
|
||||||
|
position += n
|
||||||
|
if last_music < duration:
|
||||||
|
blank = {'blank': True, 'duration': duration - last_music}
|
||||||
|
result['music'].append(blank)
|
||||||
|
# vocals
|
||||||
|
if letter in VOCALS:
|
||||||
|
n = seq()
|
||||||
|
clip = VOCALS[letter][n]
|
||||||
|
|
||||||
|
n = 1.0 / (seq() + 1) # 0.1 - 1
|
||||||
|
|
||||||
|
silence = duration - clip['duration']
|
||||||
|
silence_start = n * silence
|
||||||
|
blank = {'blank': True, 'duration': silence_start}
|
||||||
|
if n != 0:
|
||||||
|
result['vocals'].append(blank)
|
||||||
|
result['vocals'].append(clip)
|
||||||
|
if n != 1:
|
||||||
|
blank = {'blank': True, 'duration': silence - silence_start}
|
||||||
|
result['vocals'].append(blank)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in a new issue