Commit 9d4c6830 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Audio record: show track head control when monitoring is activated, and...

Audio record: show track head control when monitoring is activated, and countdown when recording is started
parent 3b5ecdd8
......@@ -77,6 +77,7 @@ void MixerManager::monitorAudio(int tid, bool monitor)
// Another track is monitoring
if (m_mixers.count(m_monitorTrack) > 0) {
m_mixers[m_monitorTrack]->monitorAudio(false);
pCore->monitorAudio(m_monitorTrack, false);
}
m_monitorTrack = -1;
} else {
......@@ -84,6 +85,7 @@ void MixerManager::monitorAudio(int tid, bool monitor)
}
if (m_mixers.count(tid) > 0) {
m_mixers[tid]->monitorAudio(true);
pCore->monitorAudio(tid, true);
} else {
return;
}
......
......@@ -148,6 +148,7 @@ MediaCapture::MediaCapture(QObject *parent)
, m_audioDevice("default:")
, m_path(QUrl())
, m_recordState(0)
, m_tid(-1)
{
m_resetTimer.setInterval(5000);
m_resetTimer.setSingleShot(true);
......@@ -257,6 +258,7 @@ void MediaCapture::resetIfUnused()
void MediaCapture::recordAudio(int tid, bool record)
{
QMutexLocker lk(&m_recMutex);
m_tid = tid;
if (!m_audioRecorder) {
m_audioRecorder = std::make_unique<QAudioRecorder>(this);
connect(m_audioRecorder.get(), &QAudioRecorder::stateChanged, this, [&, tid] (QMediaRecorder::State state) {
......@@ -264,7 +266,6 @@ void MediaCapture::recordAudio(int tid, bool record)
if (m_recordState == QMediaRecorder::StoppedState) {
m_resetTimer.start();
m_recLevels.clear();
m_recTimer.invalidate();
m_lastPos = -1;
emit audioLevels(QVector <qreal>());
emit pCore->finalizeRecording(getCaptureOutputLocation().toLocalFile());
......@@ -274,6 +275,8 @@ void MediaCapture::recordAudio(int tid, bool record)
}
if (record && m_audioRecorder->state() == QMediaRecorder::StoppedState) {
m_recTimer.invalidate();
m_resetTimer.stop();
setAudioCaptureDevice();
m_audioRecorder->setAudioInput(m_audioDevice);
setCaptureOutputLocation();
......@@ -291,20 +294,26 @@ void MediaCapture::recordAudio(int tid, bool record)
audioSettings.setChannelCount(KdenliveSettings::audiocapturechannels());
m_audioRecorder->setEncodingSettings(audioSettings);
m_audioRecorder->setOutputLocation(m_path);
m_lastPos = -1;
m_recLevels.clear();
m_audioRecorder->record();
m_recTimer.start();
} else if (!record) {
m_audioRecorder->stop();
m_recTimer.invalidate();
} else {
m_audioRecorder->record();
qDebug()<<"::: RESTARTING RECORD\n\nBBBBBB";
m_lastPos = -1;
m_recTimer.restart();
m_recTimer.start();
m_audioRecorder->record();
}
}
int MediaCapture::startCapture()
{
m_lastPos = -1;
m_recTimer.start();
m_audioRecorder->record();
return m_tid;
}
void MediaCapture::recordVideo(int tid, bool record)
{
// TO DO - fix video capture
......@@ -445,9 +454,8 @@ void MediaCapture::pauseRecording()
void MediaCapture::resumeRecording()
{
if (m_audioRecorder->state() == QMediaRecorder::PausedState) {
// Pause is not supported on this platform
m_lastPos = -1;
m_recTimer.start();
m_audioRecorder->record();
m_recTimer.restart();
}
}
......@@ -76,6 +76,8 @@ public:
Q_INVOKABLE void switchMonitorState(int tid, bool run);
void pauseRecording();
void resumeRecording();
/** @brief Start the real audio capture **/
int startCapture();
public slots:
void displayErrorMessage();
......@@ -95,6 +97,7 @@ private:
QVector<double> m_recLevels;
int m_recordState;
int m_lastPos;
int m_tid;
QTimer m_resetTimer;
QMutex m_recMutex;
......
......@@ -1009,6 +1009,18 @@ void Core::stopMediaCapture(int tid, bool checkAudio, bool checkVideo)
}
}
void Core::monitorAudio(int tid, bool monitor)
{
m_mainWindow->getCurrentTimeline()->controller()->switchTrackRecord(tid, monitor);
}
void Core::startRecording()
{
int trackId = m_capture->startCapture();
m_mainWindow->getCurrentTimeline()->startAudioRecord(trackId);
pCore->monitorManager()->slotPlay();
}
QStringList Core::getAudioCaptureDevices()
{
return m_capture->getAudioCaptureDevices();
......
......@@ -347,6 +347,10 @@ public slots:
void transcodeFriendlyFile(const QString &binId, bool checkProfile);
/** @brief Reset audio monitoring volume and channels. */
void resetAudioMonitoring();
/** @brief Start audio recording (after countdown). */
void startRecording();
/** @brief Show or hide track head audio rec controls. */
void monitorAudio(int tid, bool monitor);
signals:
void coreIsReady();
......
......@@ -2733,9 +2733,10 @@ void MainWindow::slotSwitchTrackAudioStream()
getCurrentTimeline()->showTargetMenu();
}
void MainWindow::slotShowTrackRec()
void MainWindow::slotShowTrackRec(bool checked)
{
getCurrentTimeline()->controller()->switchTrackRecord();
pCore->mixer()->monitorAudio(getCurrentTimeline()->controller()->activeTrack(), checked);
getCurrentTimeline()->controller()->switchTrackRecord(-1, checked);
}
void MainWindow::slotSelectTrack()
......
......@@ -452,7 +452,7 @@ private slots:
void slotDeleteTrack();
/** @brief Show context menu to switch current track target audio stream. */
void slotSwitchTrackAudioStream();
void slotShowTrackRec();
void slotShowTrackRec(bool checked);
/** @brief Select all clips in active track. */
void slotSelectTrack();
/** @brief Select all clips in timeline. */
......
......@@ -2276,14 +2276,13 @@ void Monitor::loadQmlScene(MonitorSceneType type, const QVariant &sceneData)
break;
case MonitorSceneDefault:
QObject::connect(root, SIGNAL(editCurrentMarker()), this, SLOT(slotEditInlineMarker()), Qt::UniqueConnection);
if (m_id == Kdenlive::ClipMonitor) {
QObject::connect(root, SIGNAL(endDrag()), pCore->bin(), SIGNAL(processDragEnd()), Qt::UniqueConnection);
}
m_qmlManager->setProperty(QStringLiteral("timecode"), m_timePos->displayText());
if (m_id == Kdenlive::ClipMonitor) {
QObject::connect(root, SIGNAL(endDrag()), pCore->bin(), SIGNAL(processDragEnd()), Qt::UniqueConnection);
updateQmlDisplay(KdenliveSettings::displayClipMonitorInfo());
} else if (m_id == Kdenlive::ProjectMonitor) {
updateQmlDisplay(KdenliveSettings::displayProjectMonitorInfo());
QObject::connect(root, SIGNAL(startRecording()), pCore.get(), SLOT(startRecording()), Qt::UniqueConnection);
}
break;
case MonitorSplitTrack:
......@@ -2664,3 +2663,11 @@ void Monitor::seekTimeline(const QString &frameAndTrack)
}
requestSeek(frame);
}
void Monitor::startCountDown()
{
QQuickItem *root = m_glMonitor->rootObject();
if (root) {
QMetaObject::invokeMethod(root, "startCountdown");
}
}
......@@ -143,6 +143,8 @@ public:
void focusTimecode();
/** @brief Ensure the video widget has focus to make keyboard shortcuts work */
void fixFocus();
/** @brief Show a rec countdown over the monitor **/
void startCountDown();
protected:
void mousePressEvent(QMouseEvent *event) override;
......
/*
SPDX-FileCopyrightText: 2022 Jean-Baptiste Mardelle <jb@kdenlive.org>
SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
import QtQuick.Controls 2.4
import QtQuick 2.11
Rectangle {
id: counter
property int countdown: 3
property int subcount: 0
anchors.fill: parent
property int size: Math.min(width, height)
color: Qt.rgba(0, 0, 0, 0.5)
Timer {
id: countdownTimer
interval: 100
running: counter.countdown > 0
repeat: true
onTriggered: {
counter.subcount += 1
if (counter.subcount % 10 == 0) {
counter.subcount = 0
counter.countdown--
if (counter.countdown == 0) {
root.stopCountdown()
}
}
}
}
Rectangle {
width: counter.size * 0.6
height: width
color: "black"
border.color: "white"
border.width: 4
radius: width*0.5
opacity: 0.5
anchors.centerIn: parent
}
Repeater {
model: 4
anchors.fill: parent
delegate: Label {
anchors.centerIn: parent
visible: counter.countdown <= index
opacity: counter.countdown == index ? 1 : 0.4
scale: counter.countdown >= index ? 1.0 : 0.0
text: modelData
color: index < 2 ? 'red' : 'white'
font.pixelSize: counter.size * 0.5
Behavior on opacity { NumberAnimation {} }
//horizontalAlignment: Text.AlignHCenter
}
}
Rectangle {
color: 'white'
height: 5
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
width: parent.width - (counter.subcount * parent.width / 10)
}
}
......@@ -49,6 +49,7 @@ Item {
}
signal editCurrentMarker()
signal startRecording()
onDurationChanged: {
clipMonitorRuler.updateRuler()
......@@ -61,6 +62,14 @@ Item {
clipMonitorRuler.forceRepaint()
}
function startCountdown() {
countDownLoader.source = "Countdown.qml"
}
function stopCountdown() {
root.startRecording()
countDownLoader.source = ""
}
function switchOverlay() {
if (controller.overlayType >= 5) {
controller.overlayType = 0
......@@ -142,6 +151,10 @@ Item {
}
}
}
Loader {
id: countDownLoader
anchors.fill: parent
}
}
Item {
id: monitorOverlay
......
......@@ -758,7 +758,7 @@ void TimelineController::deleteMultipleTracks(int tid)
}
}
void TimelineController::switchTrackRecord(int tid)
void TimelineController::switchTrackRecord(int tid, bool monitor)
{
if (tid == -1) {
tid = m_activeTrack;
......@@ -767,11 +767,19 @@ void TimelineController::switchTrackRecord(int tid)
pCore->displayMessage(i18n("Select an audio track to display record controls"), ErrorMessage, 500);
}
int recDisplayed = m_model->getTrackProperty(tid, QStringLiteral("kdenlive:audio_rec")).toInt();
if (recDisplayed == 1) {
if (monitor == false) {
// Disable rec controls
if (recDisplayed == 0) {
// Already hidden
return;
}
m_model->setTrackProperty(tid, QStringLiteral("kdenlive:audio_rec"), QStringLiteral("0"));
} else {
// Enable rec controls
if (recDisplayed == 1) {
// Already displayed
return;
}
m_model->setTrackProperty(tid, QStringLiteral("kdenlive:audio_rec"), QStringLiteral("1"));
}
QModelIndex ix = m_model->makeTrackIndexFromID(tid);
......@@ -4514,8 +4522,7 @@ void TimelineController::switchRecording(int trackId)
}
pCore->monitorManager()->slotSwitchMonitors(false);
pCore->startMediaCapture(trackId, true, false);
emit startAudioRecord(trackId);
pCore->monitorManager()->slotPlay();
pCore->getMonitor(Kdenlive::ProjectMonitor)->startCountDown();
} else {
pCore->stopMediaCapture(trackId, true, false);
emit stopAudioRecord();
......
......@@ -280,7 +280,7 @@ public:
Q_INVOKABLE void deleteMultipleTracks(int tid);
/** @brief Show / hide audio rec controls in active track
*/
void switchTrackRecord(int tid = -1);
void switchTrackRecord(int tid = -1, bool monitor = false);
/** @brief Group selected items in timeline
*/
Q_INVOKABLE void groupSelection();
......@@ -812,8 +812,5 @@ signals:
Q_INVOKABLE void ungrabHack();
void regainFocus();
void updateAssetPosition(int itemId);
/** @brief An audio recording started, display timeline waveform
*/
void startAudioRecord(int trackId);
void stopAudioRecord();
};
......@@ -54,7 +54,6 @@ TimelineWidget::TimelineWidget(QWidget *parent)
connect(m_proxy, &TimelineController::zoneMoved, this, &TimelineWidget::zoneMoved);
connect(m_proxy, &TimelineController::ungrabHack, this, &TimelineWidget::slotUngrabHack);
connect(m_proxy, &TimelineController::regainFocus, this, &TimelineWidget::regainFocus, Qt::DirectConnection);
connect(m_proxy, &TimelineController::startAudioRecord, this, &TimelineWidget::startAudioRecord, Qt::DirectConnection);
connect(m_proxy, &TimelineController::stopAudioRecord, this, &TimelineWidget::stopAudioRecord, Qt::DirectConnection);
setResizeMode(QQuickWidget::SizeRootObjectToView);
engine()->addImageProvider(QStringLiteral("thumbnail"), new ThumbnailProvider);
......
......@@ -4,6 +4,7 @@
</qresource>
<qresource prefix="/qml">
<file alias="kdenlivemonitor.qml">monitor/view/kdenlivemonitor.qml</file>
<file alias="Countdown.qml">monitor/view/Countdown.qml</file>
<file alias="kdenliveclipmonitor.qml">monitor/view/kdenliveclipmonitor.qml</file>
<file alias="kdenlivemonitoreffectscene.qml">monitor/view/kdenlivemonitoreffectscene.qml</file>
<file alias="kdenlivemonitorcornerscene.qml">monitor/view/kdenlivemonitorcornerscene.qml</file>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment