40 gst_init(
nullptr,
nullptr);
55 return media::Player::PlaybackStatus::playing;
56 else if (state.
new_state == GST_STATE_PAUSED)
57 return media::Player::PlaybackStatus::paused;
58 else if (state.
new_state == GST_STATE_READY)
59 return media::Player::PlaybackStatus::ready;
60 else if (state.
new_state == GST_STATE_NULL)
61 return media::Player::PlaybackStatus::null;
63 return media::Player::PlaybackStatus::stopped;
68 if (p.second ==
"playbin")
70 std::cout <<
"State changed on playbin: " 71 << gst_element_state_get_name(p.first.new_state) << std::endl;
72 const auto status = gst_state_to_player_status(p.first);
77 if (status == media::Player::PlaybackStatus::paused &&
78 !playbin.can_play_streams()) {
79 std::cerr <<
"** Cannot play: some codecs are missing" << std::endl;
84 playback_status_changed(status);
94 if (g_strcmp0(g_quark_to_string(ewi.
error->domain),
"gst-core-error-quark") == 0)
96 switch (ewi.
error->code)
98 case GST_CORE_ERROR_FAILED:
99 std::cerr <<
"** Encountered a GST_CORE_ERROR_FAILED" << std::endl;
100 ret_error = media::Player::Error::resource_error;
102 case GST_CORE_ERROR_NEGOTIATION:
103 std::cerr <<
"** Encountered a GST_CORE_ERROR_NEGOTIATION" << std::endl;
104 ret_error = media::Player::Error::resource_error;
106 case GST_CORE_ERROR_MISSING_PLUGIN:
107 std::cerr <<
"** Encountered a GST_CORE_ERROR_MISSING_PLUGIN" << std::endl;
108 ret_error = media::Player::Error::format_error;
111 std::cerr <<
"** Encountered an unhandled core error: '" 112 << ewi.
debug <<
"' (code: " << ewi.
error->code <<
")" << std::endl;
113 ret_error = media::Player::Error::no_error;
117 else if (g_strcmp0(g_quark_to_string(ewi.
error->domain),
"gst-resource-error-quark") == 0)
119 switch (ewi.
error->code)
121 case GST_RESOURCE_ERROR_FAILED:
122 std::cerr <<
"** Encountered a GST_RESOURCE_ERROR_FAILED" << std::endl;
123 ret_error = media::Player::Error::resource_error;
125 case GST_RESOURCE_ERROR_NOT_FOUND:
126 std::cerr <<
"** Encountered a GST_RESOURCE_ERROR_NOT_FOUND" << std::endl;
127 ret_error = media::Player::Error::resource_error;
129 case GST_RESOURCE_ERROR_OPEN_READ:
130 std::cerr <<
"** Encountered a GST_RESOURCE_ERROR_OPEN_READ" << std::endl;
131 ret_error = media::Player::Error::resource_error;
133 case GST_RESOURCE_ERROR_OPEN_WRITE:
134 std::cerr <<
"** Encountered a GST_RESOURCE_ERROR_OPEN_WRITE" << std::endl;
135 ret_error = media::Player::Error::resource_error;
137 case GST_RESOURCE_ERROR_READ:
138 std::cerr <<
"** Encountered a GST_RESOURCE_ERROR_READ" << std::endl;
139 ret_error = media::Player::Error::resource_error;
141 case GST_RESOURCE_ERROR_WRITE:
142 std::cerr <<
"** Encountered a GST_RESOURCE_ERROR_WRITE" << std::endl;
143 ret_error = media::Player::Error::resource_error;
145 case GST_RESOURCE_ERROR_NOT_AUTHORIZED:
146 std::cerr <<
"** Encountered a GST_RESOURCE_ERROR_NOT_AUTHORIZED" << std::endl;
147 ret_error = media::Player::Error::access_denied_error;
150 std::cerr <<
"** Encountered an unhandled resource error: '" 151 << ewi.
debug <<
"' (code: " << ewi.
error->code <<
")" << std::endl;
152 ret_error = media::Player::Error::no_error;
156 else if (g_strcmp0(g_quark_to_string(ewi.
error->domain),
"gst-stream-error-quark") == 0)
158 switch (ewi.
error->code)
160 case GST_STREAM_ERROR_FAILED:
161 std::cerr <<
"** Encountered a GST_STREAM_ERROR_FAILED" << std::endl;
162 ret_error = media::Player::Error::resource_error;
164 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
165 std::cerr <<
"** Encountered a GST_STREAM_ERROR_CODEC_NOT_FOUND" << std::endl;
167 ret_error = media::Player::Error::no_error;
169 case GST_STREAM_ERROR_DECODE:
170 std::cerr <<
"** Encountered a GST_STREAM_ERROR_DECODE" << std::endl;
171 ret_error = media::Player::Error::format_error;
174 std::cerr <<
"** Encountered an unhandled stream error: '" 175 << ewi.
debug <<
"' (code: " << ewi.
error->code <<
")" << std::endl;
176 ret_error = media::Player::Error::no_error;
181 if (ret_error != media::Player::Error::no_error) {
182 std::cerr <<
"Resetting playbin pipeline after unrecoverable error" << std::endl;
191 if (e != media::Player::Error::no_error)
198 if (e != media::Player::Error::no_error)
204 std::cerr <<
"Got a playbin info message (no action taken): " << ewi.
debug << std::endl;
209 media::Track::MetaData md;
211 track_meta_data.set(std::make_tuple(playbin.uri(), md));
216 playbin.set_volume(new_volume.value);
221 playbin.set_audio_stream_role(new_audio_role);
233 playbin.set_lifetime(lifetime);
238 state = Engine::State::ready;
249 client_disconnected();
259 video_dimension_changed(dimensions);
265 orientation(
media::Player::Orientation::rotate0),
266 is_video_source(false),
267 is_audio_source(false),
268 about_to_finish_connection(
269 playbin.signals.about_to_finish.connect(
273 on_state_changed_connection(
274 playbin.signals.on_state_changed.connect(
276 &
Private::on_playbin_state_changed,
278 std::placeholders::_1))),
280 playbin.signals.on_error.connect(
284 std::placeholders::_1))),
285 on_warning_connection(
286 playbin.signals.on_warning.connect(
290 std::placeholders::_1))),
292 playbin.signals.on_info.connect(
296 std::placeholders::_1))),
297 on_tag_available_connection(
298 playbin.signals.on_tag_available.connect(
302 std::placeholders::_1))),
303 on_volume_changed_connection(
304 volume.changed().connect(
308 std::placeholders::_1))),
309 on_audio_stream_role_changed_connection(
310 audio_role.changed().connect(
312 &
Private::on_audio_stream_role_changed,
314 std::placeholders::_1))),
315 on_orientation_changed_connection(
316 playbin.signals.on_orientation_changed.connect(
318 &
Private::on_orientation_changed,
320 std::placeholders::_1))),
321 on_lifetime_changed_connection(
322 lifetime.changed().connect(
326 std::placeholders::_1))),
327 on_seeked_to_connection(
328 playbin.signals.on_seeked_to.connect(
332 std::placeholders::_1))),
333 client_disconnected_connection(
334 playbin.signals.client_disconnected.connect(
336 &
Private::on_client_disconnected,
338 on_end_of_stream_connection(
339 playbin.signals.on_end_of_stream.connect(
343 on_video_dimension_changed_connection(
344 playbin.signals.on_video_dimensions_changed.connect(
346 &
Private::on_video_dimension_changed,
348 std::placeholders::_1)))
357 core::Property<Engine::State>
state;
358 core::Property<std::tuple<media::Track::UriType, media::Track::MetaData>>
track_meta_data;
361 core::Property<media::Engine::Volume>
volume;
389 core::Signal<media::Player::Error>
error;
394 d->state = media::Engine::State::no_media;
400 d->state = media::Engine::State::no_media;
403 const std::shared_ptr<media::Engine::MetaDataExtractor>&
406 return d->meta_data_extractor;
415 bool do_pipeline_reset)
424 d->playbin.set_uri(uri, headers);
430 d->playbin.create_video_sink(texture_id);
435 const auto result = d->playbin.set_state_and_wait(GST_STATE_PLAYING);
439 d->state = media::Engine::State::playing;
440 cout << __PRETTY_FUNCTION__ << endl;
441 cout <<
"Engine: playing uri: " << d->playbin.uri() << endl;
442 d->playback_status_changed(media::Player::PlaybackStatus::playing);
451 if (d->state == media::Engine::State::stopped)
453 std::cerr <<
"Current player state is already stopped - no need to change state to stopped" << std::endl;
457 const auto result = d->playbin.set_state_and_wait(GST_STATE_NULL);
460 d->state = media::Engine::State::stopped;
461 cout << __PRETTY_FUNCTION__ << endl;
462 d->playback_status_changed(media::Player::PlaybackStatus::stopped);
470 const auto result = d->playbin.set_state_and_wait(GST_STATE_PAUSED);
474 d->state = media::Engine::State::paused;
475 cout << __PRETTY_FUNCTION__ << endl;
476 d->playback_status_changed(media::Player::PlaybackStatus::paused);
484 return d->playbin.seek(ts);
490 if (type == gstreamer::Playbin::MediaFileType::MEDIA_FILE_TYPE_VIDEO)
491 d->is_video_source.set(
true);
493 d->is_video_source.set(
false);
495 return d->is_video_source;
501 if (type == gstreamer::Playbin::MediaFileType::MEDIA_FILE_TYPE_AUDIO)
502 d->is_audio_source.set(
true);
504 d->is_audio_source.set(
false);
506 return d->is_audio_source;
511 d->position.set(d->playbin.position());
517 d->duration.set(d->playbin.duration());
533 return d->audio_role;
543 return d->audio_role;
548 return d->orientation;
556 const core::Property<std::tuple<media::Track::UriType, media::Track::MetaData>>&
559 return d->track_meta_data;
564 return d->about_to_finish;
574 return d->client_disconnected;
579 return d->end_of_stream;
584 return d->playback_status_changed;
589 return d->video_dimension_changed;
void on_tag_available(const gstreamer::Bus::Message::Detail::Tag &tag)
core::ScopedConnection on_state_changed_connection
core::ScopedConnection on_video_dimension_changed_connection
core::Signal< core::ubuntu::media::video::Dimensions > video_dimension_changed
const core::Property< core::ubuntu::media::Engine::Volume > & volume() const
core::Property< bool > is_video_source
const core::Signal< core::ubuntu::media::Player::PlaybackStatus > & playback_status_changed_signal() const
const core::Property< core::ubuntu::media::Player::AudioStreamRole > & audio_stream_role() const
const core::Property< bool > & is_video_source() const
const core::Signal< void > & client_disconnected_signal() const
core::ScopedConnection on_info_connection
core::Signal< void > end_of_stream
core::ScopedConnection on_lifetime_changed_connection
void on_seeked_to(uint64_t value)
void on_playbin_warning(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
void on_about_to_finish()
const core::Property< State > & state() const
const core::Property< core::ubuntu::media::Player::Lifetime > & lifetime() const
core::ScopedConnection on_seeked_to_connection
core::ScopedConnection on_end_of_stream_connection
void on_orientation_changed(const media::Player::Orientation &o)
core::Signal< media::Player::Error > error
gstreamer::Playbin playbin
bool seek_to(const std::chrono::microseconds &ts)
core::ScopedConnection on_warning_connection
bool open_resource_for_uri(const core::ubuntu::media::Track::UriType &uri, bool do_pipeline_reset)
const core::Signal< uint64_t > & seeked_to_signal() const
struct gstreamer::Init init
void create_video_sink(uint32_t texture_id)
const core::Property< std::tuple< core::ubuntu::media::Track::UriType, core::ubuntu::media::Track::MetaData > > & track_meta_data() const
core::ScopedConnection client_disconnected_connection
void on_playbin_error(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
media::Player::Error from_gst_errorwarning(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
const core::Property< bool > & is_audio_source() const
void on_volume_changed(const media::Engine::Volume &new_volume)
const core::Signal< core::ubuntu::media::Player::Error > & error_signal() const
const core::Property< uint64_t > & duration() const
core::ScopedConnection on_volume_changed_connection
const core::Signal< void > & about_to_finish_signal() const
core::Property< media::Player::Orientation > orientation
core::Property< media::Player::AudioStreamRole > audio_role
const core::Signal< void > & end_of_stream_signal() const
const core::Signal< core::ubuntu::media::video::Dimensions > & video_dimension_changed_signal() const
core::Signal< void > client_disconnected
core::Signal< uint64_t > seeked_to
void on_playbin_info(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
core::ScopedConnection on_error_connection
core::Property< media::Player::Lifetime > lifetime
std::shared_ptr< Engine::MetaDataExtractor > meta_data_extractor
core::ScopedConnection on_tag_available_connection
const std::shared_ptr< MetaDataExtractor > & meta_data_extractor() const
core::Property< media::Engine::Volume > volume
void on_playbin_state_changed(const std::pair< gstreamer::Bus::Message::Detail::StateChanged, std::string > &p)
media::Player::PlaybackStatus gst_state_to_player_status(const gstreamer::Bus::Message::Detail::StateChanged &state)
core::ScopedConnection about_to_finish_connection
core::Property< Engine::State > state
const core::Property< core::ubuntu::media::Player::Orientation > & orientation() const
core::Property< uint64_t > position
core::Property< std::tuple< media::Track::UriType, media::Track::MetaData > > track_meta_data
core::Signal< void > about_to_finish
core::Signal< media::Player::PlaybackStatus > playback_status_changed
const core::Property< uint64_t > & position() const
core::ScopedConnection on_orientation_changed_connection
void on_client_disconnected()
void on_audio_stream_role_changed(const media::Player::AudioStreamRole &new_audio_role)
void on_video_dimension_changed(const media::video::Dimensions &dimensions)
void on_lifetime_changed(const media::Player::Lifetime &lifetime)
core::Property< bool > is_audio_source
core::Property< uint64_t > duration
core::ScopedConnection on_audio_stream_role_changed_connection