[multimedia/kdenlive] /: Add support for MLT autoduck transition (requires latest MLT git)
Jean-Baptiste Mardelle <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 0f02a2f3bbc3f9d04637ddb151d6f708766f1312 by Jean-Baptiste Mardelle.
Committed on 07/08/2026 at 14:32.
Pushed by mardelle into branch 'master'.
Add support for MLT autoduck transition (requires latest MLT git)
M +1 -0 data/transitions/CMakeLists.txt
A +20 -0 data/transitions/autoduck.xml
M +10 -7 src/timeline2/model/timelinemodel.cpp
M +6 -9 src/timeline2/view/qml/Timeline.qml
M +15 -3 src/timeline2/view/timelinecontroller.cpp
M +1 -1 src/transitions/transitionsrepository.cpp
https://invent.kde.org/multimedia/kdenlive/-/commit/0f02a2f3bbc3f9d04637ddb151d6f708766f1312
diff --git a/data/transitions/CMakeLists.txt b/data/transitions/CMakeLists.txt
index 85421692cf..8b1382b54b 100644
--- a/data/transitions/CMakeLists.txt
+++ b/data/transitions/CMakeLists.txt
@@ -3,6 +3,7 @@
INSTALL (FILES
affine.xml
+autoduck.xml
composite.xml
dissolve.xml
luma.xml
diff --git a/data/transitions/autoduck.xml b/data/transitions/autoduck.xml
new file mode 100644
index 0000000000..b7de412212
--- /dev/null
+++ b/data/transitions/autoduck.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!DOCTYPE kpartgui>
+<transition tag="mix" id="autoduck" type="audiotransition">
+ <name>Auto Duck</name>
+ <description>Applies a volume change on the lower track depending on the volume of the upper track.</description>
+ <author>Dan Dennedy</author>
+ <parameter type="constant" name="duck_threshold" max="0" min="-20" default="-15" decimals="1">
+ <name>Ducking Threshold</name>
+ </parameter>
+ <parameter type="constant" name="duck_attenuation" max="0" min="-60" default="-18" decimals="1">
+ <name>Ducking Attenuation</name>
+ </parameter>
+ <parameter type="constant" name="duck_fade_in" max="5000" min="0" default="1500" suffix="ms">
+ <name>Ducking Fade In</name>
+ </parameter>
+ <parameter type="constant" name="duck_fade_out" max="5000" min="0" default="250" suffix="ms">
+ <name>Ducking Fade Out</name>
+ </parameter>
+ <parameter type="fixed" name="sum" max="1" min="1" default="1"/>
+</transition>
diff --git a/src/timeline2/model/timelinemodel.cpp b/src/timeline2/model/timelinemodel.cpp
index 0e3ced23ad..78e4fae2b4 100644
--- a/src/timeline2/model/timelinemodel.cpp
+++ b/src/timeline2/model/timelinemodel.cpp
@@ -1855,7 +1855,7 @@ QVariantList TimelineModel::suggestCompositionMove(int compoId, int trackId, int
Q_ASSERT(isTrack(trackId));
int currentPos = getCompositionPosition(compoId);
int currentTrack = getCompositionTrackId(compoId);
- if (getTrackById_const(trackId)->isAudioTrack()) {
+ if (getTrackById_const(trackId)->isAudioTrack() != getTrackById_const(currentTrack)->isAudioTrack()) {
// Trying move on incompatible track type, stay on same track
trackId = currentTrack;
}
@@ -6528,7 +6528,12 @@ bool TimelineModel::requestCompositionMove(int compoId, int trackId, int composi
Q_ASSERT(isComposition(compoId));
Q_ASSERT(isTrack(trackId));
if (compositionTrack == -1 || (compositionTrack > 0 && trackId == getTrackIndexFromPosition(compositionTrack - 1))) {
- compositionTrack = getPreviousVideoTrackPos(trackId);
+ int previousTrack = getPreviousTrackId(trackId);
+ if (previousTrack == trackId) {
+ compositionTrack = 0;
+ } else {
+ compositionTrack = getTrackMltIndex(previousTrack);
+ }
}
if (compositionTrack == -1) {
// it doesn't make sense to insert a composition on the last track
@@ -6658,11 +6663,9 @@ bool TimelineModel::replantCompositions(int currentCompo, bool updateView)
resource = transition.get("mlt_service");
int internal = transition.get_int("internal_added");
if (internal > 0) {
- if (resource != QLatin1String("mix")) {
- trackCompositions << new Mlt::Transition(transition);
- field->disconnect_service(transition);
- transition.disconnect_all_producers();
- }
+ trackCompositions << new Mlt::Transition(transition);
+ field->disconnect_service(transition);
+ transition.disconnect_all_producers();
}
if (nextservice == nullptr) {
diff --git a/src/timeline2/view/qml/Timeline.qml b/src/timeline2/view/qml/Timeline.qml
index 7ecf022c12..d2b8f6c4cd 100644
--- a/src/timeline2/view/qml/Timeline.qml
+++ b/src/timeline2/view/qml/Timeline.qml
@@ -707,7 +707,7 @@ function getTrackColor(audio, header) {
var track = Logic.getTrackIdFromPos(drag.y + voffset + scrollView.contentY - subtitleTrack.height)
if (track !== -1) {
var frame = Math.floor((drag.x + scrollView.contentX + offset) / root.timeScale)
- if (root.controller.isAudioTrack(track) != isAudioDrag) {
+ if (root.controller.isAudioTrack(track) != compoArea.isAudioDrag) {
// Don't allow moving composition to an audio track
track = root.controller.getCompositionTrackId(root.clipBeingDroppedId)
}
@@ -717,7 +717,7 @@ function getTrackColor(audio, header) {
sameCutPos = root.timeline.isOnCut(root.clipBeingDroppedId)
if (sameCutPos > -1) {
var sourceTrack = Logic.getTrackById(fakeTrack)
- if ((drag.y < sourceTrack.y + sourceTrack.height / 2) || isAudioDrag) {
+ if ((drag.y < sourceTrack.y + sourceTrack.height / 2) || compoArea.isAudioDrag) {
sameTrackIndicator.x = sameCutPos * root.timeScale - sameTrackIndicator.width / 2
sameTrackIndicator.y = sourceTrack.y
sameTrackIndicator.height = sourceTrack.height
@@ -746,8 +746,8 @@ function getTrackColor(audio, header) {
var track = Logic.getTrackIdFromPos(drag.y + scrollView.contentY - yOffset)
var frame = Math.round((drag.x + scrollView.contentX) / root.timeScale)
root.droppedPosition = frame
- isAudioDrag = drag.getDataAsString('type') == "audio"
- if (track >= 0 && root.controller.isAudioTrack(track) == isAudioDrag) {
+ compoArea.isAudioDrag = drag.getDataAsString('type') == "audio"
+ if (track >= 0 && root.controller.isAudioTrack(track) == compoArea.isAudioDrag) {
root.clipBeingDroppedData = drag.getDataAsString('kdenlive/composition')
root.clipBeingDroppedId = root.timeline.insertComposition(track, frame, root.clipBeingDroppedData, false)
root.continuousScrolling(drag.x + scrollView.contentX, drag.y + scrollView.contentY, upMove)
@@ -777,7 +777,7 @@ function getTrackColor(audio, header) {
yOffset = subtitleTrack.height
}
var track = Logic.getTrackIdFromPos(drag.y + scrollView.contentY - yOffset)
- if (track !== -1 && root.controller.isAudioTrack(track) == isAudioDrag) {
+ if (track !== -1 && root.controller.isAudioTrack(track) == compoArea.isAudioDrag) {
frame = root.controller.suggestSnapPoint(frame, root.snapping)
root.clipBeingDroppedData = drag.getDataAsString('kdenlive/composition')
root.clipBeingDroppedId = root.timeline.insertComposition(track, frame, root.clipBeingDroppedData , false)
@@ -808,11 +808,8 @@ function getTrackColor(audio, header) {
if (sameTrackIndicator.visible) {
// We want a same track composition
root.timeline.insertNewMix(track, sameCutPos, root.clipBeingDroppedData)
- } else if (!isAudioDrag) {
- root.timeline.insertNewCompositionAtPos(track, frame, root.clipBeingDroppedData)
} else {
- // Cannot insert an audio mix composition
- // TODO: show warning
+ root.timeline.insertNewCompositionAtPos(track, frame, root.clipBeingDroppedData)
}
}
root.clearDropData()
diff --git a/src/timeline2/view/timelinecontroller.cpp b/src/timeline2/view/timelinecontroller.cpp
index ec70542bcd..f63b1ab072 100644
--- a/src/timeline2/view/timelinecontroller.cpp
+++ b/src/timeline2/view/timelinecontroller.cpp
@@ -552,7 +552,11 @@ int TimelineController::insertNewCompositionAtPos(int tid, int position, const Q
if (topCid > 0) {
return addCompositionToClip(transitionId, topCid, 0);
} else {
- int lowerVideoTrackId = m_model->getPreviousVideoTrackIndex(tid);
+ int previousTrack = m_model->getPreviousTrackId(tid);
+ int lowerVideoTrackId = 0;
+ if (previousTrack != tid) {
+ lowerVideoTrackId = m_model->getTrackMltIndex(previousTrack);
+ }
if (lowerVideoTrackId > 0) {
int lowerCid = m_model->getTrackById_const(lowerVideoTrackId)->getClipByStartPosition(position);
if (lowerCid > 0) {
@@ -594,7 +598,11 @@ int TimelineController::insertNewComposition(int tid, int clipId, int offset, QS
int endPos = minimumPos + clip_duration;
int position = minimumPos;
int duration = qMin(clip_duration, pCore->getDurationFromString(KdenliveSettings::transition_duration()));
- int lowerVideoTrackId = m_model->getPreviousVideoTrackIndex(tid);
+ int previousTrack = m_model->getPreviousTrackId(tid);
+ int lowerVideoTrackId = 0;
+ if (previousTrack != tid) {
+ lowerVideoTrackId = m_model->getTrackMltIndex(previousTrack);
+ }
bool revert = offset > clip_duration / 2;
int bottomId = 0;
if (lowerVideoTrackId > 0) {
@@ -691,7 +699,11 @@ int TimelineController::insertComposition(int tid, int position, QString transit
duration = pCore->getDurationFromString(KdenliveSettings::transition_duration());
}
// Check if composition should be reversed (top clip at beginning, bottom at end)
- int a_track = m_model->getPreviousVideoTrackPos(tid);
+ int previousTrack = m_model->getPreviousTrackId(tid);
+ int a_track = 0;
+ if (previousTrack != tid) {
+ a_track = m_model->getTrackMltIndex(previousTrack);
+ }
int topClip = m_model->getTrackById_const(tid)->getClipByPosition(position);
int bottomClip = -1;
if (a_track > 0) {
diff --git a/src/transitions/transitionsrepository.cpp b/src/transitions/transitionsrepository.cpp
index 28440effb4..0a1f4474ae 100644
--- a/src/transitions/transitionsrepository.cpp
+++ b/src/transitions/transitionsrepository.cpp
@@ -111,7 +111,7 @@ void TransitionsRepository::parseCustomAssetFile(const QString &file_name, std::
if (customAssets.count(result.id) > 0) {
// qDebug() << "duplicate transition" << result.id;
}
- if (m_hiddenList.contains(result.mltId)) {
+ if (m_hiddenList.contains(result.id)) {
result.type = AssetListType::AssetType::Hidden;
}
customAssets[result.id] = result;