diff --git a/src/capture/mediacapture.cpp b/src/capture/mediacapture.cpp index b801bff62cdc47bd4a0714c1f197c852a80bb10e..cc82dba21642b2d1a4ef5aa6e8cfc761028ec841 100644 --- a/src/capture/mediacapture.cpp +++ b/src/capture/mediacapture.cpp @@ -37,6 +37,9 @@ MediaCapture::MediaCapture(QObject *parent) { m_probe = std::make_unique(this); connect(m_probe.get(), &QAudioProbe::audioBufferProbed, this, &MediaCapture::processBuffer); + m_resetTimer.setInterval(5000); + m_resetTimer.setSingleShot(true); + connect(&m_resetTimer, &QTimer::timeout, this, &MediaCapture::resetIfUnused); } MediaCapture::~MediaCapture() = default; @@ -46,13 +49,29 @@ void MediaCapture::displayErrorMessage() qDebug() << " !!!!!!!!!!!!!!!! ERROR : QMediarecorder - Capture failed"; } +void MediaCapture::resetIfUnused() +{ + QMutexLocker lk(&m_recMutex); + qDebug()<<"// CLEARING REC MANAGER"; + if (m_audioRecorder && m_audioRecorder->state() == QMediaRecorder::StoppedState) { + m_audioRecorder.reset(); + } +} + void MediaCapture::recordAudio(bool record) { + QMutexLocker lk(&m_recMutex); if (!m_audioRecorder) { m_audioRecorder = std::make_unique(this); m_probe->setSource(m_audioRecorder.get()); connect(m_audioRecorder.get(), &QAudioRecorder::stateChanged, [&] (QMediaRecorder::State state) { m_recordState = state; + if (m_recordState == QMediaRecorder::StoppedState) { + m_resetTimer.start(); + m_levels.clear(); + emit levelsChanged(); + pCore->finalizeRecording(getCaptureOutputLocation().toLocalFile()); + } emit recordStateChanged(); }); } @@ -61,24 +80,21 @@ void MediaCapture::recordAudio(bool record) setAudioCaptureDevice(); m_audioRecorder->setAudioInput(m_audioDevice); setCaptureOutputLocation(); - m_audioRecorder->setOutputLocation(m_path); setAudioVolume(); m_audioRecorder->setVolume(m_volume); + //qDebug()<<"START AREC: "<supportedAudioCodecs(); connect(m_audioRecorder.get(), SIGNAL(error(QMediaRecorder::Error)), this, SLOT(displayErrorMessage())); QAudioEncoderSettings audioSettings; + audioSettings.setCodec("audio/x-flac"); audioSettings.setBitRate(48000); // Bit rate is set to 48,0000 - QString container = "audio/x-wav"; - m_audioRecorder->setEncodingSettings(audioSettings, QVideoEncoderSettings(), container); + audioSettings.setChannelCount(2); + m_audioRecorder->setEncodingSettings(audioSettings); + m_audioRecorder->setOutputLocation(m_path); m_audioRecorder->record(); } else if (m_audioRecorder->state() != QMediaRecorder::PausedState) { m_audioRecorder->stop(); - m_audioRecorder.reset(); - m_levels.clear(); - emit levelsChanged(); - m_recordState = QMediaRecorder::StoppedState; - emit recordStateChanged(); } else { m_audioRecorder->record(); } @@ -127,7 +143,7 @@ void MediaCapture::setCaptureOutputLocation() if (m_videoRecorder.get() != nullptr) { extension = QStringLiteral(".mpeg"); } else if (m_audioRecorder.get() != nullptr) { - extension = QStringLiteral(".wav"); + extension = QStringLiteral(".flac"); } QString path = captureFolder.absoluteFilePath("capture0000" + extension); diff --git a/src/capture/mediacapture.h b/src/capture/mediacapture.h index b742c7b7a7527f4cfcc59d80cfb2216be4949e69..b5be2bee28402d7e2dd5c2c45848f8778b8ce571 100644 --- a/src/capture/mediacapture.h +++ b/src/capture/mediacapture.h @@ -31,6 +31,8 @@ along with this program. If not, see . #include #include #include +#include +#include #include class QAudioRecorder; @@ -78,13 +80,17 @@ private: QUrl m_path; QVector m_levels; int m_recordState; + QTimer m_resetTimer; + QMutex m_recMutex; private slots: void processBuffer(const QAudioBuffer &buffer); + void resetIfUnused(); signals: void levelsChanged(); void recordStateChanged(); + void recordDone(); }; #endif diff --git a/src/core.cpp b/src/core.cpp index 878198f252e2854e9903f2908c58b3ece69ac798..6a9dbfeda84eea051d140959a753606b8bacd70b 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -695,14 +695,13 @@ void Core::startMediaCapture(bool checkAudio, bool checkVideo) m_mediaCaptureFile = m_capture->getCaptureOutputLocation(); } -const QString Core::stopMediaCapture(bool checkAudio, bool checkVideo) +void Core::stopMediaCapture(bool checkAudio, bool checkVideo) { if (checkAudio && checkVideo) { m_capture->recordVideo(false); } else if (checkAudio) { m_capture->recordAudio(false); } - return m_capture->getCaptureOutputLocation().toLocalFile(); } QStringList Core::getAudioCaptureDevices() diff --git a/src/core.h b/src/core.h index f7a956093d9caac88e62d231bd945a7720100f13..d18bc5f18c286e11792b52d8a762af3f38dae21d 100644 --- a/src/core.h +++ b/src/core.h @@ -183,7 +183,7 @@ public: int getTimelinePosition() const; /** @brief Handles audio and video capture **/ void startMediaCapture(bool, bool); - const QString stopMediaCapture(bool, bool); + void stopMediaCapture(bool, bool); QStringList getAudioCaptureDevices(); int getMediaCaptureState(); bool isMediaCapturing(); @@ -231,6 +231,7 @@ signals: void updateLibraryPath(); /** @brief Call config dialog on a selected page / tab */ void showConfigDialog(int, int); + void finalizeRecording(const QString &captureFile); }; #endif diff --git a/src/timeline2/view/qml/AudioLevels.qml b/src/timeline2/view/qml/AudioLevels.qml index e7c03f369fdc3cfa6bb6dafa1cbb57e3917c5ded..f87e11458d67fb163c476cc298f0992af51ff6f6 100644 --- a/src/timeline2/view/qml/AudioLevels.qml +++ b/src/timeline2/view/qml/AudioLevels.qml @@ -8,7 +8,7 @@ Item { property int recState: audiorec.recordState width: parent.width implicitHeight: root.baseUnit * 1.5 - + onRecStateChanged: { if (recState == 1) { // Recording @@ -19,9 +19,7 @@ Item { } else { recbutton.color = 'darkred' } - } - RowLayout { spacing: 2 Layout.fillWidth: true diff --git a/src/timeline2/view/timelinecontroller.cpp b/src/timeline2/view/timelinecontroller.cpp index d24ec4e3e5ec7ecb09eee9eaab62398228a0e359..944f334147e7053fdc2a8fa3da461f762108f188 100644 --- a/src/timeline2/view/timelinecontroller.cpp +++ b/src/timeline2/view/timelinecontroller.cpp @@ -77,6 +77,7 @@ TimelineController::TimelineController(QObject *parent) connect(m_disablePreview, &QAction::triggered, this, &TimelineController::disablePreview); connect(this, &TimelineController::selectionChanged, this, &TimelineController::updateClipActions); m_disablePreview->setEnabled(false); + connect(pCore.get(), &Core::finalizeRecording, this, &TimelineController::finishRecording); } TimelineController::~TimelineController() @@ -2323,6 +2324,7 @@ void TimelineController::switchRecording(int trackId) return; } m_recordStart.first = timelinePosition(); + m_recordTrack = trackId; int maximumSpace = m_model->getTrackById_const(trackId)->getBlankEnd(m_recordStart.first); if (maximumSpace == INT_MAX) { m_recordStart.second = 0; @@ -2339,30 +2341,37 @@ void TimelineController::switchRecording(int trackId) pCore->startMediaCapture(true, false); pCore->monitorManager()->slotPlay(); } else { - QString recordedFile = pCore->stopMediaCapture(true, false); + pCore->stopMediaCapture(true, false); pCore->monitorManager()->slotPause(); - if (recordedFile.isEmpty()) { + } +} + +void TimelineController::finishRecording(const QString &recordedFile) +{ + if (recordedFile.isEmpty()) { + return; + } + + Fun undo = []() { return true; }; + Fun redo = []() { return true; }; + std::function callBack = [this](const QString &binId) { + int id = -1; + if (m_recordTrack == -1) { return; } - - Fun undo = []() { return true; }; - Fun redo = []() { return true; }; - std::function callBack = [this, trackId](const QString &binId) { - int id = -1; - qDebug() << "callback " << binId << " " << trackId << ", MAXIMUM SPACE: " << m_recordStart.second; - bool res = false; - if (m_recordStart.second > 0) { - // Limited space on track - QString binClipId = QString("%1/%2/%3").arg(binId).arg(0).arg(m_recordStart.second - 1); - res = m_model->requestClipInsertion(binClipId, trackId, m_recordStart.first, id, true, true, false); - } else { - res = m_model->requestClipInsertion(binId, trackId, m_recordStart.first, id, true, true, false); - } - }; - QString binId = ClipCreator::createClipFromFile(recordedFile, pCore->projectItemModel()->getRootFolder()->clipId(), pCore->projectItemModel(), undo, - redo, callBack); - if (binId != QStringLiteral("-1")) { - pCore->pushUndo(undo, redo, i18n("Record audio")); + qDebug() << "callback " << binId << " " << m_recordTrack << ", MAXIMUM SPACE: " << m_recordStart.second; + bool res = false; + if (m_recordStart.second > 0) { + // Limited space on track + QString binClipId = QString("%1/%2/%3").arg(binId).arg(0).arg(m_recordStart.second - 1); + res = m_model->requestClipInsertion(binClipId, m_recordTrack, m_recordStart.first, id, true, true, false); + } else { + res = m_model->requestClipInsertion(binId, m_recordTrack, m_recordStart.first, id, true, true, false); } + }; + QString binId = ClipCreator::createClipFromFile(recordedFile, pCore->projectItemModel()->getRootFolder()->clipId(), pCore->projectItemModel(), undo, + redo, callBack); + if (binId != QStringLiteral("-1")) { + pCore->pushUndo(undo, redo, i18n("Record audio")); } } diff --git a/src/timeline2/view/timelinecontroller.h b/src/timeline2/view/timelinecontroller.h index af3cc064cf2ce8e3e11b565f5bc9e5e67e16b0a2..b838fbc7ca6c50802e588024dc901d2f4e7d9e06 100644 --- a/src/timeline2/view/timelinecontroller.h +++ b/src/timeline2/view/timelinecontroller.h @@ -116,6 +116,9 @@ public: /* @brief Show/hide audio record controls on a track */ Q_INVOKABLE void switchRecording(int trackId); + /* @brief Add recorded file to timeline + */ + void finishRecording(const QString &recordedFile); /* @brief Open Kdenlive's config diablog on a defined page and tab */ Q_INVOKABLE void showConfig(int page, int tab); @@ -482,6 +485,7 @@ private: int m_activeTrack; int m_audioRef; QPair m_recordStart; + int m_recordTrack; QPoint m_zone; double m_scale; static int m_duration;