static int set_avtransport_uri(struct action_event *event) { if (obtain_instanceid(event, NULL) < 0) { return -1; } char *uri = upnp_get_string(event, "CurrentURI"); if (uri == NULL) { return -1; } service_lock(); char *meta = upnp_get_string(event, "CurrentURIMetaData"); // Transport URI/Meta set now, current URI/Meta when it starts playing. int requires_meta_update = replace_transport_uri_and_meta(uri, meta); if (transport_state_ == TRANSPORT_PLAYING) { // Uh, wrong state. // Usually, this should not be called while we are PLAYING, only // STOPPED or PAUSED. But if actually some controller sets this // while playing, probably the best is to update the current // current URI/Meta as well to reflect the state best. replace_current_uri_and_meta(uri, meta); } output_set_uri(uri, (requires_meta_update ? update_meta_from_stream : NULL)); service_unlock(); free(uri); free(meta); return 0; }
static void inform_play_transition_from_output(enum PlayFeedback fb) { service_lock(); switch (fb) { case PLAY_STOPPED: replace_transport_uri_and_meta("", ""); replace_current_uri_and_meta("", ""); change_transport_state(TRANSPORT_STOPPED); break; case PLAY_STARTED_NEXT_STREAM: { const char *av_uri = get_var(TRANSPORT_VAR_NEXT_AV_URI); const char *av_meta = get_var(TRANSPORT_VAR_NEXT_AV_URI_META); replace_transport_uri_and_meta(av_uri, av_meta); replace_current_uri_and_meta(av_uri, av_meta); replace_var(TRANSPORT_VAR_NEXT_AV_URI, ""); replace_var(TRANSPORT_VAR_NEXT_AV_URI_META, ""); break; } } service_unlock(); }
static int play(struct action_event *event) { if (obtain_instanceid(event, NULL) < 0) { return -1; } int rc = 0; service_lock(); switch (transport_state_) { // even if already playing, we must restart playback when Play // action is executed. Kinsky, for example, would not send Stop // when changing tracks and playback is already in progress - // it will just set new URI, and send Play command case TRANSPORT_PLAYING: case TRANSPORT_STOPPED: // If we were stopped before, we start a new song now. So just // set the time to zero now; otherwise we will see the old // value of the previous song until it updates some fractions // of a second later. replace_var(TRANSPORT_VAR_REL_TIME_POS, kZeroTime); /* >>> fall through */ case TRANSPORT_PAUSED_PLAYBACK: if (output_play(&inform_play_transition_from_output)) { upnp_set_error(event, 704, "Playing failed"); rc = -1; } else { change_transport_state(TRANSPORT_PLAYING); const char *av_uri = get_var(TRANSPORT_VAR_AV_URI); const char *av_meta = get_var(TRANSPORT_VAR_AV_URI_META); replace_current_uri_and_meta(av_uri, av_meta); } break; case TRANSPORT_NO_MEDIA_PRESENT: case TRANSPORT_TRANSITIONING: case TRANSPORT_PAUSED_RECORDING: case TRANSPORT_RECORDING: /* action not allowed in these states - error 701 */ upnp_set_error(event, UPNP_TRANSPORT_E_TRANSITION_NA, "Transition not allowed; allowed=%s", get_var(TRANSPORT_VAR_CUR_TRANSPORT_ACTIONS)); rc = -1; break; } service_unlock(); return rc; }
void timerPlay(char *uri) { service_lock(); output_stop(); change_transport_state(TRANSPORT_STOPPED); output_set_uri(uri, NULL); replace_var(TRANSPORT_VAR_REL_TIME_POS, kZeroTime); if (output_play(&inform_play_transition_from_output)) { } else { change_transport_state(TRANSPORT_PLAYING); const char *av_uri = get_var(TRANSPORT_VAR_AV_URI); const char *av_meta = get_var(TRANSPORT_VAR_AV_URI_META); replace_current_uri_and_meta(av_uri, av_meta); } service_unlock(); }