update subtitles

This commit is contained in:
j 2023-11-16 09:08:03 +01:00
parent 798efa43a8
commit 5103e8f81b
2 changed files with 83 additions and 7 deletions

View file

@ -0,0 +1,20 @@
import json
import os
import subprocess
from django.core.management.base import BaseCommand
from django.conf import settings
from ...render import update_subtitles
class Command(BaseCommand):
help = 'genrate kdenlive porject and render'
def add_arguments(self, parser):
parser.add_argument('--prefix', action='store', dest='prefix', default="/srv/t_for_time", help='prefix to build clips in')
parser.add_argument('--duration', action='store', dest='duration', default="3600", help='target duration of all fragments in seconds')
parser.add_argument('--offset', action='store', dest='offset', default="1024", help='inital offset in pi')
def handle(self, **options):
update_subtitles(options)

View file

@ -2,10 +2,11 @@
from collections import defaultdict from collections import defaultdict
import json import json
import os import os
import re
import shutil
import subprocess import subprocess
import sys import sys
import time import time
import shutil
from pathlib import Path from pathlib import Path
import ox import ox
@ -46,6 +47,23 @@ def get_clip_by_seqid(clips, seqid):
return clips.pop(i) return clips.pop(i)
return None return None
def write_if_new(path, data, mode=''):
read_mode = 'r' + mode
write_mode = 'w' + mode
if os.path.exists(path):
with open(path, read_mode) as fd:
old = fd.read()
else:
old = ""
is_new = data != old
if path.endswith(".kdenlive"):
is_new = re.sub('\{.{36}\}', '', data) != re.sub('\{.{36}\}', '', old)
if is_new:
with open(path, write_mode) as fd:
fd.write(data)
def compose(clips, target=150, base=1024, voice_over=None): def compose(clips, target=150, base=1024, voice_over=None):
length = 0 length = 0
scene = { scene = {
@ -282,8 +300,9 @@ def render(root, scene, prefix=''):
scene_duration = int(get_scene_duration(scene) * 24) scene_duration = int(get_scene_duration(scene) * 24)
for timeline, data in scene.items(): for timeline, data in scene.items():
if timeline == "subtitles": if timeline == "subtitles":
with open(os.path.join(root, prefix + "front.srt"), "wb") as fd: path = os.path.join(root, prefix + "front.srt")
fd.write(ox.srt.encode(data)) srt = ox.srt.encode(data)
write_if_new(path, srt, 'b')
continue continue
#print(timeline) #print(timeline)
project = KDEnliveProject(root) project = KDEnliveProject(root)
@ -304,8 +323,8 @@ def render(root, scene, prefix=''):
project.append_clip(track, {'blank': True, "duration": delta/24}) project.append_clip(track, {'blank': True, "duration": delta/24})
break break
path = os.path.join(root, prefix + "%s.kdenlive" % timeline) path = os.path.join(root, prefix + "%s.kdenlive" % timeline)
with open(path, 'w') as fd: project_xml = project.to_xml()
fd.write(project.to_xml()) write_if_new(path, project_xml)
files.append(path) files.append(path)
return files return files
@ -410,8 +429,8 @@ def render_all(options):
timelines = render(prefix, scene, fragment_prefix[len(prefix) + 1:] + '/') timelines = render(prefix, scene, fragment_prefix[len(prefix) + 1:] + '/')
with open(os.path.join(fragment_prefix, 'scene.json'), 'w') as fd: scene_json = json.dumps(scene, indent=2, ensure_ascii=False)
json.dump(scene, fd, indent=2, ensure_ascii=False) write_if_new(os.path.join(fragment_prefix, 'scene.json'), scene_json)
if not options['no_video']: if not options['no_video']:
for timeline in timelines: for timeline in timelines:
@ -517,3 +536,40 @@ def render_all(options):
print(json.dumps(dict(stats), sort_keys=True, indent=2)) print(json.dumps(dict(stats), sort_keys=True, indent=2))
with open(_cache, "w") as fd: with open(_cache, "w") as fd:
json.dump(_CACHE, fd) json.dump(_CACHE, fd)
def update_subtitles(options):
import item.models
prefix = Path(options['prefix'])
duration = int(options['duration'])
base = int(options['offset'])
_cache = os.path.join(prefix, "cache.json")
if os.path.exists(_cache):
with open(_cache) as fd:
_CACHE.update(json.load(fd))
base_prefix = prefix / 'render' / str(base)
for folder in os.listdir(base_prefix):
folder = base_prefix / folder
with open(folder / "scene.json") as fd:
scene = json.load(fd)
offset = 0
subs = []
for clip in scene['audio-center']['A1']:
if not clip.get("blank"):
batch, fragment_id = clip['src'].replace('.wav', '').split('/')[-2:]
vo = item.models.Item.objects.filter(data__icontains='2-Whispered', data__title__startswith=fragment_id + '_').first()
if vo:
for sub in vo.annotations.filter(layer="subtitles").exclude(value="").order_by("start"):
sdata = sub.json(keys=['in', 'out', 'value'])
sdata['value'] = sdata['value'].replace('<br/>', '<br>').replace('<br>\n', '\n').replace('<br>', '\n')
sdata["in"] += offset
sdata["out"] += offset
subs.append(sdata)
offset += clip['duration']
path = folder / "front.srt"
srt = ox.srt.encode(subs)
write_if_new(str(path), srt, 'b')