Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qffmpegmediarecorder.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include "qaudiodevice.h"
6#include <private/qmediastoragelocation_p.h>
7#include <private/qplatformcamera_p.h>
8#include <private/qplatformsurfacecapture_p.h>
9#include "qaudiosource.h"
10#include "qffmpegaudioinput_p.h"
11#include "qaudiobuffer.h"
12#include "qffmpegencoder_p.h"
14
15#include <qdebug.h>
16#include <qeventloop.h>
17#include <qstandardpaths.h>
18#include <qmimetype.h>
19#include <qloggingcategory.h>
20
21static Q_LOGGING_CATEGORY(qLcMediaEncoder, "qt.multimedia.encoder")
22
24
27{
28}
29
31{
32 if (encoder)
33 encoder->finalize();
34}
35
37{
38 return true;
39}
40
41void QFFmpegMediaRecorder::handleSessionError(QMediaRecorder::Error code, const QString &description)
42{
43 error(code, description);
44 stop();
45}
46
48{
49 if (!m_session || state() != QMediaRecorder::StoppedState)
50 return;
51
52 auto videoSources = m_session->activeVideoSources();
53 const auto hasVideo = !videoSources.empty();
54 const auto hasAudio = m_session->audioInput() != nullptr;
55
56 if (!hasVideo && !hasAudio) {
57 error(QMediaRecorder::ResourceError, QMediaRecorder::tr("No video or audio input"));
58 return;
59 }
60
61 const auto audioOnly = settings.videoCodec() == QMediaFormat::VideoCodec::Unspecified;
62
63 auto primaryLocation = audioOnly ? QStandardPaths::MusicLocation : QStandardPaths::MoviesLocation;
64 auto container = settings.mimeType().preferredSuffix();
65 auto location = QMediaStorageLocation::generateFileName(outputLocation().toLocalFile(), primaryLocation, container);
66
68 qCDebug(qLcMediaEncoder) << "recording new video to" << actualSink;
69 qCDebug(qLcMediaEncoder) << "requested format:" << settings.fileFormat() << settings.audioCodec();
70
71 Q_ASSERT(!actualSink.isEmpty());
72
73 encoder = new QFFmpeg::Encoder(settings, actualSink);
74 encoder->setMetaData(m_metaData);
75 connect(encoder, &QFFmpeg::Encoder::durationChanged, this, &QFFmpegMediaRecorder::newDuration);
76 connect(encoder, &QFFmpeg::Encoder::finalizationDone, this, &QFFmpegMediaRecorder::finalizationDone);
77 connect(encoder, &QFFmpeg::Encoder::error, this, &QFFmpegMediaRecorder::handleSessionError);
78
79 auto *audioInput = m_session->audioInput();
80 if (audioInput) {
81 if (audioInput->device.isNull())
82 qWarning() << "Audio input device is null; cannot encode audio";
83 else
84 encoder->addAudioInput(static_cast<QFFmpegAudioInput *>(audioInput));
85 }
86
87 for (auto source : videoSources)
88 encoder->addVideoSource(source);
89
93
94 encoder->start();
95}
96
98{
99 if (!m_session || state() != QMediaRecorder::RecordingState)
100 return;
101
102 Q_ASSERT(encoder);
103 encoder->setPaused(true);
104
106}
107
109{
110 if (!m_session || state() != QMediaRecorder::PausedState)
111 return;
112
113 Q_ASSERT(encoder);
114 encoder->setPaused(false);
115
117}
118
120{
121 if (!m_session || state() == QMediaRecorder::StoppedState)
122 return;
123 auto * input = m_session ? m_session->audioInput() : nullptr;
124 if (input)
125 static_cast<QFFmpegAudioInput *>(input)->setRunning(false);
126 qCDebug(qLcMediaEncoder) << "stop";
127 // ### all of the below should be done asynchronous. finalize() should do it's work in a thread
128 // to avoid blocking the UI in case of slow codecs
129 if (encoder) {
130 encoder->finalize();
131 encoder = nullptr;
132 }
133}
134
135void QFFmpegMediaRecorder::finalizationDone()
136{
138}
139
141{
142 if (!m_session)
143 return;
144 m_metaData = metaData;
145}
146
148{
149 return m_metaData;
150}
151
153{
154 auto *captureSession = static_cast<QFFmpegMediaCaptureSession *>(session);
155 if (m_session == captureSession)
156 return;
157
158 if (m_session)
159 stop();
160
161 m_session = captureSession;
162 if (!m_session)
163 return;
164}
165
167
168#include "moc_qffmpegmediarecorder_p.cpp"
static QString currentPath()
Returns the absolute path of the application's current directory.
Definition qdir.cpp:2051
void record(QMediaEncoderSettings &settings) override
bool isLocationWritable(const QUrl &sink) const override
QMediaMetaData metaData() const override
void setMetaData(const QMediaMetaData &) override
void setCaptureSession(QPlatformMediaCaptureSession *session)
void durationChanged(qint64 duration)
void addAudioInput(QFFmpegAudioInput *input)
void setPaused(bool p)
void error(QMediaRecorder::Error code, const QString &description)
void setMetaData(const QMediaMetaData &metaData)
void addVideoSource(QPlatformVideoSource *source)
void finalizationDone()
\inmodule QtMultimedia
\inmodule QtMultimedia
Error
\qmlproperty enumeration QtMultimedia::MediaRecorder::error
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
std::vector< QPlatformVideoSource * > activeVideoSources()
void actualLocationChanged(const QUrl &location)
void stateChanged(QMediaRecorder::RecorderState state)
QMediaRecorder::Error error() const
void durationChanged(qint64 position)
virtual QMediaRecorder::RecorderState state() const
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qurl.h:94
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition qurl.cpp:3354
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
Definition qurl.cpp:2722
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
Definition qurl.cpp:1888
Q_MULTIMEDIA_EXPORT QString generateFileName(const QString &requestedName, QStandardPaths::StandardLocation type, const QString &extension)
Combined button and popup list for selecting options.
#define qWarning
Definition qlogging.h:162
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLint location
GLsizei GLsizei GLchar * source
GLenum GLenum GLenum input
static QString toLocalFile(const QString &url)
Definition qqmlfile.cpp:611
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QSettings settings("MySoft", "Star Runner")
[0]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent