static gboolean impl_play (RBPlayer *player, RBPlayerPlayType play_type, gint64 crossfade, GError **error) { RBPlayerGst *mp = RB_PLAYER_GST (player); g_return_val_if_fail (mp->priv->playbin != NULL, FALSE); mp->priv->track_change = TRUE; if (mp->priv->stream_change_pending == FALSE) { rb_debug ("no stream change pending, just restarting playback"); mp->priv->track_change = FALSE; start_state_change (mp, GST_STATE_PLAYING, FINISH_TRACK_CHANGE); } else if (mp->priv->current_track_finishing) { switch (play_type) { case RB_PLAYER_PLAY_AFTER_EOS: rb_debug ("current track finishing -> just setting URI on playbin"); g_object_set (mp->priv->playbin, "uri", mp->priv->uri, NULL); mp->priv->playbin_stream_changing = TRUE; track_change_done (mp, NULL); break; case RB_PLAYER_PLAY_REPLACE: case RB_PLAYER_PLAY_CROSSFADE: rb_debug ("current track finishing, waiting for EOS to start next"); break; default: g_assert_not_reached (); } } else { gboolean reused = FALSE; /* try to reuse the stream */ if (mp->priv->prev_uri != NULL) { g_signal_emit (mp, signals[CAN_REUSE_STREAM], 0, mp->priv->uri, mp->priv->prev_uri, mp->priv->playbin, &reused); if (reused) { rb_debug ("reusing stream to switch from %s to %s", mp->priv->prev_uri, mp->priv->uri); g_signal_emit (player, signals[REUSE_STREAM], 0, mp->priv->uri, mp->priv->prev_uri, mp->priv->playbin); track_change_done (mp, *error); } } /* no stream reuse, so stop, set the new URI, then start */ if (reused == FALSE) { rb_debug ("not in transition, stopping current track to start the new one"); start_state_change (mp, GST_STATE_READY, SET_NEXT_URI); } } return TRUE; }
gboolean xmr_player_play(XmrPlayer *player) { XmrPlayerPrivate *priv; g_return_val_if_fail( player != NULL, FALSE); priv = player->priv; g_return_val_if_fail( priv->playbin != NULL, FALSE); g_return_val_if_fail( priv->uri != NULL, FALSE); if (priv->stream_change_pending == FALSE) { xmr_debug ("no stream change pending, just restarting playback"); start_state_change (player, GST_STATE_PLAYING, FINISH_TRACK_CHANGE); } else if (priv->current_track_finishing) { xmr_debug ("current track finishing -> just setting URI on playbin"); g_object_set(priv->playbin, "uri", priv->uri, NULL); track_change_done(player, NULL); } else { xmr_debug ("play next song"); start_state_change(player, GST_STATE_READY, SET_NEXT_URI); } return TRUE; }
static void state_change_finished (RBPlayerGst *mp, GError *error) { enum StateChangeAction action = mp->priv->state_change_action; mp->priv->state_change_action = DO_NOTHING; switch (action) { case DO_NOTHING: break; case PLAYER_SHUTDOWN: if (error != NULL) { g_warning ("unable to shut down player pipeline: %s\n", error->message); } break; case SET_NEXT_URI: if (error != NULL) { g_warning ("unable to stop playback: %s\n", error->message); } else { GstBus *bus; /* flush bus to ensure tags from the previous stream don't * get applied to the new one */ bus = gst_element_get_bus (mp->priv->playbin); gst_bus_set_flushing (bus, TRUE); gst_bus_set_flushing (bus, FALSE); gst_object_unref (bus); rb_debug ("setting new playback URI %s", mp->priv->uri); g_object_set (mp->priv->playbin, "uri", mp->priv->uri, NULL); start_state_change (mp, GST_STATE_PLAYING, FINISH_TRACK_CHANGE); } break; case STOP_TICK_TIMER: if (error != NULL) { g_warning ("unable to pause playback: %s\n", error->message); } else { if (mp->priv->tick_timeout_id != 0) { g_source_remove (mp->priv->tick_timeout_id); mp->priv->tick_timeout_id = 0; } } break; case FINISH_TRACK_CHANGE: track_change_done (mp, error); break; } }
static void state_change_finished(XmrPlayer *player, GError *error) { XmrPlayerPrivate *priv = player->priv; enum StateChangeAction action = priv->state_change_action; priv->state_change_action = DO_NOTHING; switch (action) { case DO_NOTHING: break; case PLAYER_SHUTDOWN: if (error != NULL) { g_warning ("unable to shut down player pipeline: %s\n", error->message); } break; case SET_NEXT_URI: if (error != NULL) { g_warning ("unable to stop playback: %s\n", error->message); } else { xmr_debug ("setting new playback URI %s", priv->uri); g_object_set (priv->playbin, "uri", priv->uri, NULL); start_state_change (player, GST_STATE_PLAYING, FINISH_TRACK_CHANGE); } break; case STOP_TICK_TIMER: if (error != NULL) { g_warning ("unable to pause playback: %s\n", error->message); } else { if (priv->tick_timeout_id != 0) { g_source_remove (priv->tick_timeout_id); priv->tick_timeout_id = 0; } } break; case FINISH_TRACK_CHANGE: track_change_done (player, error); break; } }