#!/usr/bin/python3 import os import json import subprocess import string from pi import random from keywords import KEYWORDS import ox import ox.web.auth base_url = 'https://cdosea.0x2620.org' api = None def get_api(): global api if not api: api = ox.API(base_url + '/api/') api.signin(**ox.web.auth.get('cdosea')) if os.path.exists('PATHS.json'): PATHS = json.load(open('PATHS.json')) else: PATHS = {} if os.path.exists('CLIPS.json'): CLIPS = json.load(open('CLIPS.json')) else: CLIPS = {} def get_path(id): global PATHS if id not in PATHS: get_api() info = api.findMedia({ 'query': { 'conditions': [ {'key': 'id', 'operator': '==', 'value': id} ] }, 'keys': ['id', 'extension'], 'range': [0, 1] })['data']['items'][0] path = os.path.join('cache', '%s.%s' % (info['id'], info['extension'])) if not os.path.exists(path): url = '%s/%s/download/source/' % (base_url, id) print('get video', url) PATHS[id] = path with open('PATHS.json', 'w') as fd: json.dump(PATHS, fd, indent=4, sort_keys=True) return PATHS[id] def get_clips(tag): global CLIPS if tag not in CLIPS: get_api() clips = api.findAnnotations({ 'query': { 'conditions': [ {'key': 'layer', 'operator': '==', 'value': 'keywords'}, {'key': 'value', 'operator': '==', 'value': tag} ], 'operator': '&' }, 'keys': ['id', 'in', 'out'], 'range': [0, 10000]})['data']['items'] for clip in clips: clip['path'] = get_path(clip['id'].split('/')[0]) clip['duration'] = clip['out'] - clip['in'] clip['tag'] = tag CLIPS[tag] = list(sorted(clips, key=lambda c: c['id'])) with open('CLIPS.json', 'w') as fd: json.dump(CLIPS, fd, indent=4, sort_keys=True) return CLIPS[tag] def random_choice(seq, items): n = n_ = len(items) - 1 print('len', n) if n == 0: return items[0] r = seq() base = 10 while n > 10: n /= 10 print(r) r += seq() base += 10 r = int(n_ * r / base) print('result', r, items) return items[r] def splitint(number, by): div = int(number/by) mod = number % by return [div + 1 if i > (by - 1 - mod) else div for i in range(by)] def filter_clips(clips, duration, max_duration=0): # 1 minute blur = 0.5 low = 1 high = 10 # 2 minute blur = 1 low = 2 high = 20 buckets = {} clips_ = [] for tag in clips: for clip in clips[tag]: clip['tag'] = tag clips_.append(clip) clips_.sort(key=lambda c: c['duration']) print(clips_) size = splitint(len(clips_), 10) p = 0 for i in range(10): buckets[i+1] = clips_[p:+p+size[i]] p += size[i] clips_ = {} print(buckets[duration]) for clip in buckets[duration]: if clip['tag'] not in clips_: clips_[clip['tag']] = [] clips_[clip['tag']].append(clip) return clips_ def sequence(seq, letter): tags = KEYWORDS[letter] clips = {tag: get_clips(tag) for tag in tags} result = { 'clips': [], 'text': [], } duration = 0 MAX_DURATION = 65 * 2 MIN_DURATION = 56 * 2 while duration < MAX_DURATION and not duration >= MIN_DURATION: # clip duration: 1-10 n = seq() if n == 0: n = 10 max_duration = MAX_DURATION - duration clips_n = filter_clips(clips, n, max_duration) tags_n = list(sorted(clips_n.keys())) if not tags_n: print('NO tags for', letter, n) tag = random_choice(seq, tags_n) #if 'tiger' in tags_n: # tag = 'tiger' clip = random_choice(seq, clips_n[tag]) duration += clip['duration'] result['clips'].append(clip.copy()) for clip in result['clips']: if seq() == 0: clip['black'] = True position = last_text = 0 while position < duration: n = seq() if n == 0: blank = {'blank': True, 'duration': position - last_text} result['text'].append(blank) n = seq() if n == 0: n = 10 n = min(n, duration-position) text = { 'text': random_choice(seq, tags_n), 'duration': n } result['text'].append(text) position += n last_text = position else: position += n if last_text < duration: blank = {'blank': True, 'duration': duration - last_text} result['text'].append(blank) return result if __name__ == '__main__': for n in range(10): seq = random(n) #for letter in string.ascii_uppercase: for letter in ('T', 'W'): r = sequence(seq, letter) tjson = 'output/%s%d.json' % (letter, n) with open(tjson, 'w') as fd: json.dump(r, fd, indent=4, sort_keys=True) print(json.dumps(r, indent=4, sort_keys=True)) #print(sum([c['duration'] for c in r['clips']])) subprocess.call(['./render_mlt.py', tjson])