add voice over, output 6 channels, add 5.1 mix

This commit is contained in:
j 2023-10-16 23:26:09 +01:00
commit 9c778bb7de
3 changed files with 263 additions and 37 deletions

View file

@ -18,7 +18,7 @@ class KDEnliveProject:
def to_xml(self):
track = self._main_tractor.xpath(".//track")[0]
duration = max(self._duration.values())
duration = self.get_duration()
values = {
"in": "0",
"out": str(duration - 1)
@ -85,13 +85,85 @@ class KDEnliveProject:
["mlt_image_format", "rgba"],
["set.test_audio", "0"],
]),
a4 := self.get_element("playlist", children=[
["kdenlive:audio_track", "1"],
]),
a4e := self.get_element("playlist", children=[
["kdenlive:audio_track", "1"],
]),
t_a4 := self.get_element("tractor", children=[
["kdenlive:audio_track", "1"],
["kdenlive:trackheight", "69"],
["kdenlive:timeline_active", "1"],
["kdenlive:collapsed", "0"],
["kdenlive:thumbs_format", None],
["kdenlive:audio_rec", None],
self.get_element("track", attrib={"hide": "video", "producer": a4.attrib["id"]}),
self.get_element("track", attrib={"hide": "video", "producer": a4e.attrib["id"]}),
self.get_element("filter", [
["window", "75"],
["max_gain", "20dB"],
["mlt_service", "volume"],
["internal_added", "237"],
["disable", "1"],
]),
self.get_element("filter", [
["channel", "-1"],
["mlt_service", "panner"],
["internal_added", "237"],
["start", "0.5"],
["disable", "1"],
]),
self.get_element("filter", [
["iec_scale", "0"],
["mlt_service", "audiolevel"],
["dbpeak", "1"],
["disable", "1"],
]),
]),
a3 := self.get_element("playlist", children=[
["kdenlive:audio_track", "1"],
]),
a3e := self.get_element("playlist", children=[
["kdenlive:audio_track", "1"],
]),
t_a3 := self.get_element("tractor", children=[
["kdenlive:audio_track", "1"],
["kdenlive:trackheight", "69"],
["kdenlive:timeline_active", "1"],
["kdenlive:collapsed", "0"],
["kdenlive:thumbs_format", None],
["kdenlive:audio_rec", None],
self.get_element("track", attrib={"hide": "video", "producer": a3.attrib["id"]}),
self.get_element("track", attrib={"hide": "video", "producer": a3e.attrib["id"]}),
self.get_element("filter", [
["window", "75"],
["max_gain", "20dB"],
["mlt_service", "volume"],
["internal_added", "237"],
["disable", "1"],
]),
self.get_element("filter", [
["channel", "-1"],
["mlt_service", "panner"],
["internal_added", "237"],
["start", "0.5"],
["disable", "1"],
]),
self.get_element("filter", [
["iec_scale", "0"],
["mlt_service", "audiolevel"],
["dbpeak", "1"],
["disable", "1"],
]),
]),
a2 := self.get_element("playlist", children=[
["kdenlive:audio_track", "1"],
]),
a2e := self.get_element("playlist", children=[
["kdenlive:audio_track", "1"],
]),
t0 := self.get_element("tractor", children=[
t_a2 := self.get_element("tractor", children=[
["kdenlive:audio_track", "1"],
["kdenlive:trackheight", "69"],
["kdenlive:timeline_active", "1"],
@ -127,7 +199,7 @@ class KDEnliveProject:
a1e := self.get_element("playlist", children=[
["kdenlive:audio_track", "1"],
]),
t1 := self.get_element("tractor", children=[
t_a1 := self.get_element("tractor", children=[
["kdenlive:audio_track", "1"],
["kdenlive:trackheight", "69"],
["kdenlive:timeline_active", "1"],
@ -219,8 +291,10 @@ class KDEnliveProject:
["kdenlive:sequenceproperties.disablepreview", "0"],
self.get_element("track", attrib={"producer": p0.attrib["id"]}),
self.get_element("track", attrib={"producer": t0.attrib["id"]}),
self.get_element("track", attrib={"producer": t1.attrib["id"]}),
self.get_element("track", attrib={"producer": t_a4.attrib["id"]}),
self.get_element("track", attrib={"producer": t_a3.attrib["id"]}),
self.get_element("track", attrib={"producer": t_a2.attrib["id"]}),
self.get_element("track", attrib={"producer": t_a1.attrib["id"]}),
self.get_element("track", attrib={"producer": t2.attrib["id"]}),
self.get_element("track", attrib={"producer": t3.attrib["id"]}),
self.get_element("transition", [
@ -246,6 +320,26 @@ class KDEnliveProject:
self.get_element("transition", [
["a_track", "0"],
["b_track", "3"],
["mlt_service", "mix"],
["kdenlive_id", "mix"],
["internal_added", "237"],
["always_active", "1"],
["accepts_blanks", "1"],
["sum", "1"],
]),
self.get_element("transition", [
["a_track", "0"],
["b_track", "4"],
["mlt_service", "mix"],
["kdenlive_id", "mix"],
["internal_added", "237"],
["always_active", "1"],
["accepts_blanks", "1"],
["sum", "1"],
]),
self.get_element("transition", [
["a_track", "0"],
["b_track", "5"],
["compositing", "0"],
["distort", "0"],
["rotate_center", "0"],
@ -258,7 +352,7 @@ class KDEnliveProject:
]),
self.get_element("transition", [
["a_track", "0"],
["b_track", "4"],
["b_track", "6"],
["compositing", "0"],
["distort", "0"],
["rotate_center", "0"],
@ -313,11 +407,13 @@ class KDEnliveProject:
self._sequence = sequence
self._main_bin = main_bin
self._main_tractor = t4
self._audio_tractor = t1
self._audio_tractor = t_a1
self._v1 = v1
self._v2 = v2
self._a1 = a1
self._a2 = a2
self._a3 = a3
self._a4 = a4
def get_counter(self, prefix):
self._counters[prefix] += 1
@ -330,7 +426,7 @@ class KDEnliveProject:
if file in _CACHE:
out = _CACHE[file]
else:
out = _CACHE[file] = subprocess.check_output(['melt', file, '-consumer', 'xml'])
out = _CACHE[file] = subprocess.check_output(['melt', file, '-consumer', 'xml']).decode()
chain = lxml.etree.fromstring(out).xpath('producer')[0]
chain.tag = 'chain'
chain.attrib['id'] = self.get_id('chain')
@ -358,6 +454,11 @@ class KDEnliveProject:
mlt_service.text = "avformat-novalidate"
return chain
def get_duration(self):
if not self._duration:
return 0
return max(self._duration.values())
def get_element(self, tag, children=[], attrib={}, text=None):
element = lxml.etree.Element(tag)
if tag not in (
@ -445,13 +546,6 @@ class KDEnliveProject:
def append_clip(self, track_id, clip):
path = clip['src']
filters = clip.get("filter", {})
frames = int(self._fps * clip['duration'])
self._duration[track_id] += frames
#print(path, filters)
chain = self.get_chain(path)
id = get_propery(chain, "kdenlive:id")
if track_id == "V1":
track = self._v1
elif track_id == "V2":
@ -460,9 +554,30 @@ class KDEnliveProject:
track = self._a1
elif track_id == "A2":
track = self._a2
elif track_id == "A3":
track = self._a3
elif track_id == "A4":
track = self._a4
else:
print('!!', track_id)
frames = int(self._fps * clip['duration'])
self._duration[track_id] += frames
if clip.get("blank"):
track.append(
self.get_element("blank", attrib={
"length": str(frames),
})
)
return
path = clip['src']
filters = clip.get("filter", {})
#print(path, filters)
chain = self.get_chain(path)
id = get_propery(chain, "kdenlive:id")
if track_id[0] == 'A':
has_audio = False
for prop in chain.xpath('property'):
@ -504,14 +619,14 @@ class KDEnliveProject:
["kdenlive:id", id],
] + filters_),
)
chain = self.get_chain(path, id)
self._tree.append(chain)
self._main_bin.append(
self.get_element("entry", attrib={
"producer": chain.attrib["id"],
"in": chain.attrib["in"],
"out": chain.attrib["out"],
}),
)
chain = self.get_chain(path, id)
self._tree.append(chain)
self._main_bin.append(
self.get_element("entry", attrib={
"producer": chain.attrib["id"],
"in": chain.attrib["in"],
"out": chain.attrib["out"],
}),
)