Fix AppImage audio recording (switch from wav to flac)

parent 6dd5e215
Pipeline #2509 passed with stage
in 20 minutes and 10 seconds
...@@ -37,6 +37,9 @@ MediaCapture::MediaCapture(QObject *parent) ...@@ -37,6 +37,9 @@ MediaCapture::MediaCapture(QObject *parent)
{ {
m_probe = std::make_unique<QAudioProbe>(this); m_probe = std::make_unique<QAudioProbe>(this);
connect(m_probe.get(), &QAudioProbe::audioBufferProbed, this, &MediaCapture::processBuffer); 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; MediaCapture::~MediaCapture() = default;
...@@ -46,13 +49,29 @@ void MediaCapture::displayErrorMessage() ...@@ -46,13 +49,29 @@ void MediaCapture::displayErrorMessage()
qDebug() << " !!!!!!!!!!!!!!!! ERROR : QMediarecorder - Capture failed"; 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) void MediaCapture::recordAudio(bool record)
{ {
QMutexLocker lk(&m_recMutex);
if (!m_audioRecorder) { if (!m_audioRecorder) {
m_audioRecorder = std::make_unique<QAudioRecorder>(this); m_audioRecorder = std::make_unique<QAudioRecorder>(this);
m_probe->setSource(m_audioRecorder.get()); m_probe->setSource(m_audioRecorder.get());
connect(m_audioRecorder.get(), &QAudioRecorder::stateChanged, [&] (QMediaRecorder::State state) { connect(m_audioRecorder.get(), &QAudioRecorder::stateChanged, [&] (QMediaRecorder::State state) {
m_recordState = state; m_recordState = state;
if (m_recordState == QMediaRecorder::StoppedState) {
m_resetTimer.start();
m_levels.clear();
emit levelsChanged();
pCore->finalizeRecording(getCaptureOutputLocation().toLocalFile());
}
emit recordStateChanged(); emit recordStateChanged();
}); });
} }
...@@ -61,24 +80,21 @@ void MediaCapture::recordAudio(bool record) ...@@ -61,24 +80,21 @@ void MediaCapture::recordAudio(bool record)
setAudioCaptureDevice(); setAudioCaptureDevice();
m_audioRecorder->setAudioInput(m_audioDevice); m_audioRecorder->setAudioInput(m_audioDevice);
setCaptureOutputLocation(); setCaptureOutputLocation();
m_audioRecorder->setOutputLocation(m_path);
setAudioVolume(); setAudioVolume();
m_audioRecorder->setVolume(m_volume); m_audioRecorder->setVolume(m_volume);
//qDebug()<<"START AREC: "<<m_path<<"\n; CODECS: "<<m_audioRecorder->supportedAudioCodecs();
connect(m_audioRecorder.get(), SIGNAL(error(QMediaRecorder::Error)), this, SLOT(displayErrorMessage())); connect(m_audioRecorder.get(), SIGNAL(error(QMediaRecorder::Error)), this, SLOT(displayErrorMessage()));
QAudioEncoderSettings audioSettings; QAudioEncoderSettings audioSettings;
audioSettings.setCodec("audio/x-flac");
audioSettings.setBitRate(48000); // Bit rate is set to 48,0000 audioSettings.setBitRate(48000); // Bit rate is set to 48,0000
QString container = "audio/x-wav"; audioSettings.setChannelCount(2);
m_audioRecorder->setEncodingSettings(audioSettings, QVideoEncoderSettings(), container); m_audioRecorder->setEncodingSettings(audioSettings);
m_audioRecorder->setOutputLocation(m_path);
m_audioRecorder->record(); m_audioRecorder->record();
} else if (m_audioRecorder->state() != QMediaRecorder::PausedState) { } else if (m_audioRecorder->state() != QMediaRecorder::PausedState) {
m_audioRecorder->stop(); m_audioRecorder->stop();
m_audioRecorder.reset();
m_levels.clear();
emit levelsChanged();
m_recordState = QMediaRecorder::StoppedState;
emit recordStateChanged();
} else { } else {
m_audioRecorder->record(); m_audioRecorder->record();
} }
...@@ -127,7 +143,7 @@ void MediaCapture::setCaptureOutputLocation() ...@@ -127,7 +143,7 @@ void MediaCapture::setCaptureOutputLocation()
if (m_videoRecorder.get() != nullptr) { if (m_videoRecorder.get() != nullptr) {
extension = QStringLiteral(".mpeg"); extension = QStringLiteral(".mpeg");
} else if (m_audioRecorder.get() != nullptr) { } else if (m_audioRecorder.get() != nullptr) {
extension = QStringLiteral(".wav"); extension = QStringLiteral(".flac");
} }
QString path = captureFolder.absoluteFilePath("capture0000" + extension); QString path = captureFolder.absoluteFilePath("capture0000" + extension);
......
...@@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QStringList> #include <QStringList>
#include <QUrl> #include <QUrl>
#include <QVideoEncoderSettings> #include <QVideoEncoderSettings>
#include <QTimer>
#include <QMutex>
#include <memory> #include <memory>
class QAudioRecorder; class QAudioRecorder;
...@@ -78,13 +80,17 @@ private: ...@@ -78,13 +80,17 @@ private:
QUrl m_path; QUrl m_path;
QVector<qreal> m_levels; QVector<qreal> m_levels;
int m_recordState; int m_recordState;
QTimer m_resetTimer;
QMutex m_recMutex;
private slots: private slots:
void processBuffer(const QAudioBuffer &buffer); void processBuffer(const QAudioBuffer &buffer);
void resetIfUnused();
signals: signals:
void levelsChanged(); void levelsChanged();
void recordStateChanged(); void recordStateChanged();
void recordDone();
}; };
#endif #endif
...@@ -695,14 +695,13 @@ void Core::startMediaCapture(bool checkAudio, bool checkVideo) ...@@ -695,14 +695,13 @@ void Core::startMediaCapture(bool checkAudio, bool checkVideo)
m_mediaCaptureFile = m_capture->getCaptureOutputLocation(); m_mediaCaptureFile = m_capture->getCaptureOutputLocation();
} }
const QString Core::stopMediaCapture(bool checkAudio, bool checkVideo) void Core::stopMediaCapture(bool checkAudio, bool checkVideo)
{ {
if (checkAudio && checkVideo) { if (checkAudio && checkVideo) {
m_capture->recordVideo(false); m_capture->recordVideo(false);
} else if (checkAudio) { } else if (checkAudio) {
m_capture->recordAudio(false); m_capture->recordAudio(false);
} }
return m_capture->getCaptureOutputLocation().toLocalFile();
} }
QStringList Core::getAudioCaptureDevices() QStringList Core::getAudioCaptureDevices()
......
...@@ -183,7 +183,7 @@ public: ...@@ -183,7 +183,7 @@ public:
int getTimelinePosition() const; int getTimelinePosition() const;
/** @brief Handles audio and video capture **/ /** @brief Handles audio and video capture **/
void startMediaCapture(bool, bool); void startMediaCapture(bool, bool);
const QString stopMediaCapture(bool, bool); void stopMediaCapture(bool, bool);
QStringList getAudioCaptureDevices(); QStringList getAudioCaptureDevices();
int getMediaCaptureState(); int getMediaCaptureState();
bool isMediaCapturing(); bool isMediaCapturing();
...@@ -231,6 +231,7 @@ signals: ...@@ -231,6 +231,7 @@ signals:
void updateLibraryPath(); void updateLibraryPath();
/** @brief Call config dialog on a selected page / tab */ /** @brief Call config dialog on a selected page / tab */
void showConfigDialog(int, int); void showConfigDialog(int, int);
void finalizeRecording(const QString &captureFile);
}; };
#endif #endif
...@@ -8,7 +8,7 @@ Item { ...@@ -8,7 +8,7 @@ Item {
property int recState: audiorec.recordState property int recState: audiorec.recordState
width: parent.width width: parent.width
implicitHeight: root.baseUnit * 1.5 implicitHeight: root.baseUnit * 1.5
onRecStateChanged: { onRecStateChanged: {
if (recState == 1) { if (recState == 1) {
// Recording // Recording
...@@ -19,9 +19,7 @@ Item { ...@@ -19,9 +19,7 @@ Item {
} else { } else {
recbutton.color = 'darkred' recbutton.color = 'darkred'
} }
} }
RowLayout { RowLayout {
spacing: 2 spacing: 2
Layout.fillWidth: true Layout.fillWidth: true
......
...@@ -77,6 +77,7 @@ TimelineController::TimelineController(QObject *parent) ...@@ -77,6 +77,7 @@ TimelineController::TimelineController(QObject *parent)
connect(m_disablePreview, &QAction::triggered, this, &TimelineController::disablePreview); connect(m_disablePreview, &QAction::triggered, this, &TimelineController::disablePreview);
connect(this, &TimelineController::selectionChanged, this, &TimelineController::updateClipActions); connect(this, &TimelineController::selectionChanged, this, &TimelineController::updateClipActions);
m_disablePreview->setEnabled(false); m_disablePreview->setEnabled(false);
connect(pCore.get(), &Core::finalizeRecording, this, &TimelineController::finishRecording);
} }
TimelineController::~TimelineController() TimelineController::~TimelineController()
...@@ -2323,6 +2324,7 @@ void TimelineController::switchRecording(int trackId) ...@@ -2323,6 +2324,7 @@ void TimelineController::switchRecording(int trackId)
return; return;
} }
m_recordStart.first = timelinePosition(); m_recordStart.first = timelinePosition();
m_recordTrack = trackId;
int maximumSpace = m_model->getTrackById_const(trackId)->getBlankEnd(m_recordStart.first); int maximumSpace = m_model->getTrackById_const(trackId)->getBlankEnd(m_recordStart.first);
if (maximumSpace == INT_MAX) { if (maximumSpace == INT_MAX) {
m_recordStart.second = 0; m_recordStart.second = 0;
...@@ -2339,30 +2341,37 @@ void TimelineController::switchRecording(int trackId) ...@@ -2339,30 +2341,37 @@ void TimelineController::switchRecording(int trackId)
pCore->startMediaCapture(true, false); pCore->startMediaCapture(true, false);
pCore->monitorManager()->slotPlay(); pCore->monitorManager()->slotPlay();
} else { } else {
QString recordedFile = pCore->stopMediaCapture(true, false); pCore->stopMediaCapture(true, false);
pCore->monitorManager()->slotPause(); 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<void(const QString &)> callBack = [this](const QString &binId) {
int id = -1;
if (m_recordTrack == -1) {
return; return;
} }
qDebug() << "callback " << binId << " " << m_recordTrack << ", MAXIMUM SPACE: " << m_recordStart.second;
Fun undo = []() { return true; }; bool res = false;
Fun redo = []() { return true; }; if (m_recordStart.second > 0) {
std::function<void(const QString &)> callBack = [this, trackId](const QString &binId) { // Limited space on track
int id = -1; QString binClipId = QString("%1/%2/%3").arg(binId).arg(0).arg(m_recordStart.second - 1);
qDebug() << "callback " << binId << " " << trackId << ", MAXIMUM SPACE: " << m_recordStart.second; res = m_model->requestClipInsertion(binClipId, m_recordTrack, m_recordStart.first, id, true, true, false);
bool res = false; } else {
if (m_recordStart.second > 0) { res = m_model->requestClipInsertion(binId, m_recordTrack, m_recordStart.first, id, true, true, false);
// 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"));
} }
};
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"));
} }
} }
...@@ -116,6 +116,9 @@ public: ...@@ -116,6 +116,9 @@ public:
/* @brief Show/hide audio record controls on a track /* @brief Show/hide audio record controls on a track
*/ */
Q_INVOKABLE void switchRecording(int trackId); 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 /* @brief Open Kdenlive's config diablog on a defined page and tab
*/ */
Q_INVOKABLE void showConfig(int page, int tab); Q_INVOKABLE void showConfig(int page, int tab);
...@@ -482,6 +485,7 @@ private: ...@@ -482,6 +485,7 @@ private:
int m_activeTrack; int m_activeTrack;
int m_audioRef; int m_audioRef;
QPair<int, int> m_recordStart; QPair<int, int> m_recordStart;
int m_recordTrack;
QPoint m_zone; QPoint m_zone;
double m_scale; double m_scale;
static int m_duration; static int m_duration;
......
Markdown is supported
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