45 gst_init(
nullptr,
nullptr);
62 return media::Player::PlaybackStatus::playing;
63 else if (state.
new_state == GST_STATE_PAUSED)
64 return media::Player::PlaybackStatus::paused;
65 else if (state.
new_state == GST_STATE_READY)
66 return media::Player::PlaybackStatus::ready;
67 else if (state.
new_state == GST_STATE_NULL)
68 return media::Player::PlaybackStatus::null;
70 return media::Player::PlaybackStatus::stopped;
74 const QByteArray &source)
78 if (source ==
"playbin")
80 MH_INFO(
"State changed on playbin: %s",
81 gst_element_state_get_name(state.
new_state));
82 const auto status = gst_state_to_player_status(state);
87 if (status == media::Player::PlaybackStatus::paused &&
88 !playbin.can_play_streams()) {
89 MH_ERROR(
"** Cannot play: some codecs are missing");
92 Q_EMIT q->errorOccurred(e);
93 }
else if (status == media::Player::PlaybackStatus::paused &&
94 (q->state() == Engine::State::ready ||
95 q->state() == Engine::State::playing)) {
99 q->setPlaybackStatus(status);
109 if (g_strcmp0(g_quark_to_string(ewi.
error->domain),
"gst-core-error-quark") == 0)
111 switch (ewi.
error->code)
113 case GST_CORE_ERROR_FAILED:
114 MH_ERROR(
"** Encountered a GST_CORE_ERROR_FAILED");
115 ret_error = media::Player::Error::resource_error;
117 case GST_CORE_ERROR_NEGOTIATION:
118 MH_ERROR(
"** Encountered a GST_CORE_ERROR_NEGOTIATION");
119 ret_error = media::Player::Error::resource_error;
121 case GST_CORE_ERROR_MISSING_PLUGIN:
122 MH_ERROR(
"** Encountered a GST_CORE_ERROR_MISSING_PLUGIN");
123 ret_error = media::Player::Error::format_error;
126 MH_ERROR(
"** Encountered an unhandled core error: '%s' (code: %d)",
128 ret_error = media::Player::Error::no_error;
132 else if (g_strcmp0(g_quark_to_string(ewi.
error->domain),
"gst-resource-error-quark") == 0)
134 switch (ewi.
error->code)
136 case GST_RESOURCE_ERROR_FAILED:
137 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_FAILED");
138 ret_error = media::Player::Error::resource_error;
140 case GST_RESOURCE_ERROR_NOT_FOUND:
141 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_NOT_FOUND");
142 ret_error = media::Player::Error::resource_error;
144 case GST_RESOURCE_ERROR_OPEN_READ:
145 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_OPEN_READ");
146 ret_error = media::Player::Error::resource_error;
148 case GST_RESOURCE_ERROR_OPEN_WRITE:
149 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_OPEN_WRITE");
150 ret_error = media::Player::Error::resource_error;
152 case GST_RESOURCE_ERROR_READ:
153 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_READ");
154 ret_error = media::Player::Error::resource_error;
156 case GST_RESOURCE_ERROR_WRITE:
157 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_WRITE");
158 ret_error = media::Player::Error::resource_error;
160 case GST_RESOURCE_ERROR_NOT_AUTHORIZED:
161 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_NOT_AUTHORIZED");
162 ret_error = media::Player::Error::access_denied_error;
165 MH_ERROR(
"** Encountered an unhandled resource error: '%s' (code: %d)",
167 ret_error = media::Player::Error::no_error;
171 else if (g_strcmp0(g_quark_to_string(ewi.
error->domain),
"gst-stream-error-quark") == 0)
173 switch (ewi.
error->code)
175 case GST_STREAM_ERROR_FAILED:
176 MH_ERROR(
"** Encountered a GST_STREAM_ERROR_FAILED");
177 ret_error = media::Player::Error::resource_error;
179 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
180 MH_ERROR(
"** Encountered a GST_STREAM_ERROR_CODEC_NOT_FOUND");
182 ret_error = media::Player::Error::no_error;
184 case GST_STREAM_ERROR_DECODE:
185 MH_ERROR(
"** Encountered a GST_STREAM_ERROR_DECODE");
186 ret_error = media::Player::Error::format_error;
189 MH_ERROR(
"** Encountered an unhandled stream error: '%s' code(%d)",
191 ret_error = media::Player::Error::no_error;
196 if (ret_error != media::Player::Error::no_error) {
197 MH_ERROR(
"Resetting playbin pipeline after unrecoverable error: %s", ewi.
debug);
207 if (e != media::Player::Error::no_error)
208 Q_EMIT q->errorOccurred(e);
215 if (e != media::Player::Error::no_error)
216 Q_EMIT q->errorOccurred(e);
221 MH_DEBUG(
"Got a playbin info message (no action taken): %s", ewi.
debug);
227 media::Track::MetaData md;
230 auto pair = q->trackMetadata();
231 if (playbin.uri() == pair.first)
235 q->setTrackMetadata(qMakePair(playbin.uri(), md));
243 QObject::connect(&playbin, &Playbin::errorOccurred,
245 on_playbin_error(ewi);
247 QObject::connect(&playbin, &Playbin::warningOccurred,
249 on_playbin_warning(ewi);
251 QObject::connect(&playbin, &Playbin::infoOccurred,
253 on_playbin_info(ewi);
256 QObject::connect(&playbin, &Playbin::aboutToFinish,
261 QObject::connect(&playbin, &Playbin::seekedTo,
262 q, &Engine::seekedTo);
263 QObject::connect(&playbin, &Playbin::bufferingChanged,
264 q, &Engine::bufferingChanged);
265 QObject::connect(&playbin, &Playbin::clientDisconnected,
266 q, &Engine::clientDisconnected);
267 QObject::connect(&playbin, &Playbin::endOfStream,
268 q, &Engine::endOfStream);
270 QObject::connect(&playbin, &Playbin::stateChanged,
272 const QByteArray &source) {
273 on_playbin_state_changed(state, source);
276 QObject::connect(&playbin, &Playbin::tagAvailable,
278 on_tag_available(tag);
280 QObject::connect(&playbin, &Playbin::orientationChanged,
284 QObject::connect(&playbin, &Playbin::videoDimensionChanged,
285 q, [q](
const QSize &size) {
308 const auto fileType = d->playbin.mediaFileType();
309 using ft = Playbin::MediaFileType;
310 setIsVideoSource(fileType == ft::MEDIA_FILE_TYPE_VIDEO);
311 setIsAudioSource(fileType == ft::MEDIA_FILE_TYPE_AUDIO);
318 setState(media::Engine::State::no_media);
322 bool do_pipeline_reset)
333 d->playbin.set_uri(uri, headers);
340 d->playbin.create_video_sink(texture_id);
346 const auto result = d->playbin.set_state(GST_STATE_PLAYING);
350 setState(media::Engine::State::playing);
351 MH_INFO(
"Engine: playing uri: %s", qUtf8Printable(d->playbin.uri().toString()));
361 if (state() == media::Engine::State::stopped)
363 MH_DEBUG(
"Current player state is already stopped - no need to change state to stopped");
367 const auto result = d->playbin.set_state(GST_STATE_NULL);
370 setState(media::Engine::State::stopped);
381 const auto result = d->playbin.set_state(GST_STATE_PAUSED);
385 setState(media::Engine::State::paused);
395 return d->playbin.seek(ts);
401 return d->playbin.position();
407 return d->playbin.duration();
419 d->playbin.set_audio_stream_role(role);
425 d->playbin.set_lifetime(lifetime);
431 d->playbin.set_volume(volume);