Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Kdenlive
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
259
Issues
259
List
Boards
Labels
Service Desk
Milestones
Merge Requests
14
Merge Requests
14
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Multimedia
Kdenlive
Commits
9c9c327b
Commit
9c9c327b
authored
Oct 22, 2020
by
Jean-Baptiste Mardelle
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move audio max level to a job (was causing ui hang on project opening)
Remove audio balance filter in projects with > 2 audio channels
parent
a12ba6df
Pipeline
#38426
canceled with stage
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
96 additions
and
75 deletions
+96
-75
src/audiomixer/mixerwidget.cpp
src/audiomixer/mixerwidget.cpp
+49
-37
src/bin/projectclip.cpp
src/bin/projectclip.cpp
+0
-32
src/core.h
src/core.h
+2
-2
src/jobs/audiothumbjob.cpp
src/jobs/audiothumbjob.cpp
+32
-4
src/mltcontroller/clipcontroller.cpp
src/mltcontroller/clipcontroller.cpp
+11
-0
src/mltcontroller/clipcontroller.h
src/mltcontroller/clipcontroller.h
+2
-0
No files found.
src/audiomixer/mixerwidget.cpp
View file @
9c9c327b
...
...
@@ -107,6 +107,7 @@ MixerWidget::MixerWidget(int tid, std::shared_ptr<Mlt::Tractor> service, const Q
,
m_monitorFilter
(
nullptr
)
,
m_balanceFilter
(
nullptr
)
,
m_channels
(
pCore
->
audioChannels
())
,
m_balanceSlider
(
nullptr
)
,
m_maxLevels
(
qMax
(
30
,
(
int
)(
service
->
get_fps
()
*
1.5
)))
,
m_solo
(
nullptr
)
,
m_record
(
nullptr
)
...
...
@@ -126,6 +127,7 @@ MixerWidget::MixerWidget(int tid, Mlt::Tractor *service, const QString &trackTag
,
m_monitorFilter
(
nullptr
)
,
m_balanceFilter
(
nullptr
)
,
m_channels
(
pCore
->
audioChannels
())
,
m_balanceSlider
(
nullptr
)
,
m_maxLevels
(
qMax
(
30
,
(
int
)(
service
->
get_fps
()
*
1.5
)))
,
m_solo
(
nullptr
)
,
m_record
(
nullptr
)
...
...
@@ -169,23 +171,27 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
m_volumeSlider
->
setValue
(
fromDB
(
val
));
});
m_balanceSlider
=
new
QSlider
(
Qt
::
Horizontal
,
this
);
m_balanceSlider
->
setRange
(
-
50
,
50
);
m_balanceSlider
->
setValue
(
0
);
m_balanceSlider
->
setTickPosition
(
QSlider
::
TicksBelow
);
m_balanceSlider
->
setTickInterval
(
50
);
m_balanceSlider
->
setToolTip
(
i18n
(
"Balance"
));
QLabel
*
labelLeft
=
new
QLabel
(
i18nc
(
"Left"
,
"L"
),
this
);
labelLeft
->
setAlignment
(
Qt
::
AlignHCenter
);
QLabel
*
labelRight
=
new
QLabel
(
i18nc
(
"Right"
,
"R"
),
this
);
labelLeft
->
setAlignment
(
Qt
::
AlignHCenter
);
m_balanceSpin
=
new
QSpinBox
(
this
);
m_balanceSpin
->
setRange
(
-
50
,
50
);
m_balanceSpin
->
setValue
(
0
);
m_balanceSpin
->
setFrame
(
false
);
m_balanceSpin
->
setToolTip
(
i18n
(
"Balance"
));
QLabel
*
labelLeft
=
nullptr
;
QLabel
*
labelRight
=
nullptr
;
if
(
m_channels
==
2
)
{
m_balanceSlider
=
new
QSlider
(
Qt
::
Horizontal
,
this
);
m_balanceSlider
->
setRange
(
-
50
,
50
);
m_balanceSlider
->
setValue
(
0
);
m_balanceSlider
->
setTickPosition
(
QSlider
::
TicksBelow
);
m_balanceSlider
->
setTickInterval
(
50
);
m_balanceSlider
->
setToolTip
(
i18n
(
"Balance"
));
labelLeft
=
new
QLabel
(
i18nc
(
"Left"
,
"L"
),
this
);
labelLeft
->
setAlignment
(
Qt
::
AlignHCenter
);
labelRight
=
new
QLabel
(
i18nc
(
"Right"
,
"R"
),
this
);
labelRight
->
setAlignment
(
Qt
::
AlignHCenter
);
m_balanceSpin
=
new
QSpinBox
(
this
);
m_balanceSpin
->
setRange
(
-
50
,
50
);
m_balanceSpin
->
setValue
(
0
);
m_balanceSpin
->
setFrame
(
false
);
m_balanceSpin
->
setToolTip
(
i18n
(
"Balance"
));
}
// Check if we already have build-in filters for this tractor
int
max
=
service
->
filter_count
();
...
...
@@ -203,7 +209,7 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
double
volume
=
m_levelFilter
->
get_double
(
"level"
);
m_volumeSpin
->
setValue
(
volume
);
m_volumeSlider
->
setValue
(
fromDB
(
volume
));
}
else
if
(
filterService
==
QLatin1String
(
"panner"
))
{
}
else
if
(
m_channels
==
2
&&
filterService
==
QLatin1String
(
"panner"
))
{
m_balanceFilter
=
fl
;
int
val
=
m_balanceFilter
->
get_double
(
"start"
)
*
100
-
50
;
m_balanceSpin
->
setValue
(
val
);
...
...
@@ -219,7 +225,7 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
service
->
attach
(
*
m_levelFilter
.
get
());
}
}
if
(
m_balanceFilter
==
nullptr
)
{
if
(
m_balanceFilter
==
nullptr
&&
m_channels
==
2
)
{
m_balanceFilter
.
reset
(
new
Mlt
::
Filter
(
service
->
get_profile
(),
"panner"
));
if
(
m_balanceFilter
->
is_valid
())
{
m_balanceFilter
->
set
(
"internal_added"
,
237
);
...
...
@@ -245,7 +251,9 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
m_muteAction
->
setActiveIcon
(
QIcon
::
fromTheme
(
QStringLiteral
(
"kdenlive-hide-audio"
)));
m_muteAction
->
setInactiveIcon
(
QIcon
::
fromTheme
(
QStringLiteral
(
"kdenlive-show-audio"
)));
connect
(
m_balanceSlider
,
&
QSlider
::
valueChanged
,
m_balanceSpin
,
&
QSpinBox
::
setValue
);
if
(
m_balanceSlider
)
{
connect
(
m_balanceSlider
,
&
QSlider
::
valueChanged
,
m_balanceSpin
,
&
QSpinBox
::
setValue
);
}
connect
(
m_muteAction
,
&
KDualAction
::
activeChangedByUser
,
this
,
[
&
](
bool
active
)
{
if
(
m_tid
==
-
1
)
{
...
...
@@ -337,17 +345,19 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
pCore
->
setDocumentModified
();
}
});
connect
(
m_balanceSpin
,
static_cast
<
void
(
QSpinBox
::*
)(
int
)
>
(
&
QSpinBox
::
valueChanged
),
this
,
[
&
](
int
value
)
{
QSignalBlocker
bk
(
m_balanceSlider
);
m_balanceSlider
->
setValue
(
value
);
if
(
m_balanceFilter
!=
nullptr
)
{
m_balanceFilter
->
set
(
"start"
,
(
value
+
50
)
/
100.
);
m_balanceFilter
->
set
(
"disable"
,
value
==
0
?
1
:
0
);
m_levels
.
clear
();
emit
m_manager
->
purgeCache
();
pCore
->
setDocumentModified
();
}
});
if
(
m_balanceSlider
)
{
connect
(
m_balanceSpin
,
static_cast
<
void
(
QSpinBox
::*
)(
int
)
>
(
&
QSpinBox
::
valueChanged
),
this
,
[
&
](
int
value
)
{
QSignalBlocker
bk
(
m_balanceSlider
);
m_balanceSlider
->
setValue
(
value
);
if
(
m_balanceFilter
!=
nullptr
)
{
m_balanceFilter
->
set
(
"start"
,
(
value
+
50
)
/
100.
);
m_balanceFilter
->
set
(
"disable"
,
value
==
0
?
1
:
0
);
m_levels
.
clear
();
emit
m_manager
->
purgeCache
();
pCore
->
setDocumentModified
();
}
});
}
QVBoxLayout
*
lay
=
new
QVBoxLayout
;
setContentsMargins
(
0
,
0
,
0
,
0
);
lay
->
setContentsMargins
(
0
,
0
,
0
,
0
);
...
...
@@ -367,12 +377,14 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
}
buttonslay
->
addWidget
(
showEffects
);
lay
->
addLayout
(
buttonslay
);
QGridLayout
*
balancelay
=
new
QGridLayout
;
balancelay
->
addWidget
(
m_balanceSlider
,
0
,
0
,
1
,
3
);
balancelay
->
addWidget
(
labelLeft
,
1
,
0
,
1
,
1
);
balancelay
->
addWidget
(
m_balanceSpin
,
1
,
1
,
1
,
1
);
balancelay
->
addWidget
(
labelRight
,
1
,
2
,
1
,
1
);
lay
->
addLayout
(
balancelay
);
if
(
m_balanceSlider
)
{
QGridLayout
*
balancelay
=
new
QGridLayout
;
balancelay
->
addWidget
(
m_balanceSlider
,
0
,
0
,
1
,
3
);
balancelay
->
addWidget
(
labelLeft
,
1
,
0
,
1
,
1
);
balancelay
->
addWidget
(
m_balanceSpin
,
1
,
1
,
1
,
1
);
balancelay
->
addWidget
(
labelRight
,
1
,
2
,
1
,
1
);
lay
->
addLayout
(
balancelay
);
}
QHBoxLayout
*
hlay
=
new
QHBoxLayout
;
hlay
->
addWidget
(
m_audioMeterWidget
.
get
());
hlay
->
addWidget
(
m_volumeSlider
);
...
...
src/bin/projectclip.cpp
View file @
9c9c327b
...
...
@@ -210,38 +210,6 @@ QString ProjectClip::getXmlProperty(const QDomElement &producer, const QString &
void
ProjectClip
::
updateAudioThumbnail
()
{
if
(
m_hasAudio
&&
m_service
.
startsWith
(
QLatin1String
(
"avformat"
)))
{
int
audioMax
=
getProducerIntProperty
(
QStringLiteral
(
"kdenlive:audio_max"
));
if
(
audioMax
==
0
)
{
// Calculate max audio level with ffmpeg
QProcess
ffmpeg
;
QStringList
args
;
args
<<
QStringLiteral
(
"-i"
)
<<
clipUrl
()
<<
QStringLiteral
(
"-vn"
)
<<
QStringLiteral
(
"-af"
)
<<
QStringLiteral
(
"volumedetect"
)
<<
QStringLiteral
(
"-f"
)
<<
QStringLiteral
(
"null"
);
#ifdef Q_OS_WIN
args
<<
QStringLiteral
(
"-"
);
#else
args
<<
QStringLiteral
(
"/dev/stdout"
);
#endif
QObject
::
connect
(
&
ffmpeg
,
&
QProcess
::
readyReadStandardOutput
,
[
&
ffmpeg
,
this
]()
{
QString
output
=
ffmpeg
.
readAllStandardOutput
();
if
(
output
.
contains
(
QLatin1String
(
"max_volume"
)))
{
output
=
output
.
section
(
QLatin1String
(
"max_volume:"
),
1
).
simplified
();
output
=
output
.
section
(
QLatin1Char
(
' '
),
0
,
0
);
bool
ok
;
double
maxVolume
=
output
.
toDouble
(
&
ok
);
if
(
ok
)
{
int
aMax
=
qMax
(
1
,
qAbs
(
qRound
(
maxVolume
)));
setProducerProperty
(
QStringLiteral
(
"kdenlive:audio_max"
),
aMax
);
}
else
{
setProducerProperty
(
QStringLiteral
(
"kdenlive:audio_max"
),
-
1
);
}
}
});
ffmpeg
.
setProcessChannelMode
(
QProcess
::
MergedChannels
);
ffmpeg
.
start
(
KdenliveSettings
::
ffmpegpath
(),
args
);
ffmpeg
.
waitForFinished
(
-
1
);
}
}
emit
audioThumbReady
();
if
(
m_clipType
==
ClipType
::
Audio
)
{
QImage
thumb
=
ThumbnailCache
::
get
()
->
getThumbnail
(
m_binId
,
0
);
...
...
src/core.h
View file @
9c9c327b
...
...
@@ -101,8 +101,6 @@ public:
KdenliveDoc
*
currentDoc
();
/** @brief Returns project's timecode. */
Timecode
timecode
()
const
;
/** @brief Set current project modified. */
void
setDocumentModified
();
/** @brief Returns a pointer to the monitor manager. */
MonitorManager
*
monitorManager
();
/** @brief Returns a pointer to the view of the project bin. */
...
...
@@ -275,6 +273,8 @@ public slots:
void
displayBinLogMessage
(
const
QString
&
text
,
int
type
,
const
QString
&
logInfo
);
/** @brief Create small thumbnails for luma used in compositions */
void
buildLumaThumbs
(
const
QStringList
&
values
);
/** @brief Set current project modified. */
void
setDocumentModified
();
signals:
void
coreIsReady
();
...
...
src/jobs/audiothumbjob.cpp
View file @
9c9c327b
...
...
@@ -30,6 +30,7 @@
#include "lib/audio/audioStreamInfo.h"
#include "macros.hpp"
#include "utils/thumbnailcache.hpp"
#include <QScopedPointer>
#include <QTemporaryFile>
#include <QProcess>
...
...
@@ -117,13 +118,40 @@ bool AudioThumbJob::computeWithFFMPEG()
// We only wanted the thumb generation
return
m_done
;
}
QString
filePath
=
m_prod
->
get
(
"kdenlive:originalurl"
);
if
(
filePath
.
isEmpty
()
||
!
QFile
::
exists
(
filePath
))
{
filePath
=
m_prod
->
get
(
"resource"
);
}
QString
filePath
=
m_binClip
->
getOriginalUrl
();
if
(
!
QFile
::
exists
(
filePath
))
{
return
false
;
}
int
audioMax
=
m_binClip
->
getProducerIntProperty
(
QStringLiteral
(
"kdenlive:audio_max"
));
if
(
audioMax
==
0
)
{
// Calculate max audio level with ffmpeg
QProcess
ffmpeg
;
QStringList
args
=
{
QStringLiteral
(
"-i"
),
filePath
,
QStringLiteral
(
"-vn"
),
QStringLiteral
(
"-af"
),
QStringLiteral
(
"volumedetect"
),
QStringLiteral
(
"-f"
),
QStringLiteral
(
"null"
)};
#ifdef Q_OS_WIN
args
<<
QStringLiteral
(
"-"
);
#else
args
<<
QStringLiteral
(
"/dev/stdout"
);
#endif
QObject
::
connect
(
&
ffmpeg
,
&
QProcess
::
readyReadStandardOutput
,
[
&
ffmpeg
,
this
]()
{
QString
output
=
ffmpeg
.
readAllStandardOutput
();
if
(
output
.
contains
(
QLatin1String
(
"max_volume"
)))
{
output
=
output
.
section
(
QLatin1String
(
"max_volume:"
),
1
).
simplified
();
output
=
output
.
section
(
QLatin1Char
(
' '
),
0
,
0
);
bool
ok
;
double
maxVolume
=
output
.
toDouble
(
&
ok
);
if
(
ok
)
{
int
aMax
=
qMax
(
1
,
qAbs
(
qRound
(
maxVolume
)));
m_binClip
->
setProducerProperty
(
QStringLiteral
(
"kdenlive:audio_max"
),
aMax
);
QMetaObject
::
invokeMethod
(
pCore
.
get
(),
"setDocumentModified"
,
Qt
::
QueuedConnection
);
}
else
{
m_binClip
->
setProducerProperty
(
QStringLiteral
(
"kdenlive:audio_max"
),
-
1
);
}
}
});
ffmpeg
.
setProcessChannelMode
(
QProcess
::
MergedChannels
);
ffmpeg
.
start
(
KdenliveSettings
::
ffmpegpath
(),
args
);
ffmpeg
.
waitForFinished
(
-
1
);
}
int
audioStreamIndex
=
m_binClip
->
getAudioStreamFfmpegIndex
(
m_audioStream
);
if
(
!
QFile
::
exists
(
m_cachePath
)
&&
!
m_dataInCache
)
{
...
...
src/mltcontroller/clipcontroller.cpp
View file @
9c9c327b
...
...
@@ -1068,3 +1068,14 @@ int ClipController::audioStreamsCount() const
return
0
;
}
const
QString
ClipController
::
getOriginalUrl
()
{
QString
path
=
m_properties
->
get
(
"kdenlive:originalurl"
);
if
(
path
.
isEmpty
())
{
path
=
m_path
;
}
if
(
QFileInfo
(
path
).
isRelative
())
{
path
.
prepend
(
pCore
->
currentDoc
()
->
documentRoot
());
}
return
path
;
}
src/mltcontroller/clipcontroller.h
View file @
9c9c327b
...
...
@@ -224,6 +224,8 @@ public:
QMap
<
int
,
QString
>
activeStreams
()
const
;
/** @brief Returns the count of audio streams for this clip */
int
audioStreamsCount
()
const
;
/** @brief Get the path to the original clip url (in case it is proxied) */
const
QString
getOriginalUrl
();
protected:
virtual
void
emitProducerChanged
(
const
QString
&
/*unused*/
,
const
std
::
shared_ptr
<
Mlt
::
Producer
>
&
/*unused*/
){};
...
...
Jean-Baptiste Mardelle
@mardelle
mentioned in issue
#754
·
Oct 22, 2020
mentioned in issue
#754
mentioned in issue #754
Toggle commit list
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment