43 if (!m_session || state() != QMediaRecorder::StoppedState)
46 auto videoSources = m_session->activeVideoSources();
47 auto audioInputs = m_session->activeAudioInputs();
48 const auto hasVideo = !videoSources.empty();
49 const auto hasAudio = !audioInputs.empty();
51 if (!hasVideo && !hasAudio) {
52 updateError(QMediaRecorder::ResourceError, QMediaRecorder::tr(
"No video or audio input"));
56 if (outputDevice() && !outputLocation().isEmpty())
57 qCWarning(qLcMediaEncoder)
58 <<
"Both outputDevice and outputLocation has been set to QMediaRecorder";
60 if (outputDevice() && !outputDevice()->isWritable())
61 qCWarning(qLcMediaEncoder) <<
"Output device has been set but not it's not writable";
63 QString actualLocation;
64 auto formatContext = std::make_unique<QFFmpeg::EncodingFormatContext>(settings.fileFormat());
66 if (outputDevice() && outputDevice()->isWritable()) {
67 formatContext->openAVIO(outputDevice());
69 actualLocation = findActualLocation(settings);
70 formatContext->openAVIO(actualLocation);
73 qCInfo(qLcMediaEncoder).nospace()
74 <<
"Recording new media with muxer "
75 << formatContext->avFormatContext()->oformat->long_name <<
" to "
76 << (actualLocation.isNull() ? u"IO device"_s : actualLocation)
77 <<
" with format: " << settings.fileFormat() <<
", " << settings.audioCodec() <<
", "
78 << settings.videoCodec();
80 if (!formatContext->isAVIOOpen()) {
81 updateError(QMediaRecorder::LocationNotWritable,
82 QMediaRecorder::tr(
"Cannot open the output location for writing"));
86 m_recordingEngine.reset(
new RecordingEngine(settings, std::move(formatContext)));
87 m_recordingEngine->setMetaData(m_metaData);
89 connect(m_recordingEngine.get(), &QFFmpeg::RecordingEngine::durationChanged,
this,
90 &QFFmpegMediaRecorder::newDuration);
91 connect(m_recordingEngine.get(), &QFFmpeg::RecordingEngine::finalizationDone,
this,
92 &QFFmpegMediaRecorder::finalizationDone);
93 connect(m_recordingEngine.get(), &QFFmpeg::RecordingEngine::sessionError,
this,
94 &QFFmpegMediaRecorder::handleSessionError);
98 auto handleStreamInitializationError = [
this](QMediaRecorder::Error code,
99 const QString &description) {
100 qCWarning(qLcMediaEncoder) <<
"Stream initialization error:" << description;
101 updateError(code, description);
104 connect(m_recordingEngine.get(), &QFFmpeg::RecordingEngine::streamInitializationError,
this,
105 handleStreamInitializationError);
108 actualLocationChanged(QUrl::fromLocalFile(actualLocation));
110 qCDebug(qLcMediaEncoder) <<
"Starting recording engine";
111 if (m_recordingEngine->initialize(audioInputs, videoSources)) {
112 stateChanged(QMediaRecorder::RecordingState);
113 qCDebug(qLcMediaEncoder) <<
"Recording engine started";
116 qCWarning(qLcMediaEncoder) <<
"Failed to start recording engine";
185 const bool autoStop = mediaRecorder()->autoStop();
186 if (!m_recordingEngine || m_recordingEngine->autoStop() == autoStop)
190 connect(m_recordingEngine.get(), &QFFmpeg::RecordingEngine::autoStopped,
this,
191 &QFFmpegMediaRecorder::stop);
193 disconnect(m_recordingEngine.get(), &QFFmpeg::RecordingEngine::autoStopped,
this,
194 &QFFmpegMediaRecorder::stop);
196 m_recordingEngine->setAutoStop(autoStop);