static bool parse_track_dict( demux_t *p_demux, input_item_node_t *p_input_node, track_elem_t *p_track, xml_reader_t *p_xml_reader, const char *psz_element, xml_elem_hnd_t *p_handlers ) { VLC_UNUSED(psz_element); VLC_UNUSED(p_handlers); input_item_t *p_new_input = NULL; int i_ret; p_track = new_track(); xml_elem_hnd_t track_elements[] = // sunqueen modify start // { {"array", COMPLEX_CONTENT, {.cmplx = skip_element} }, // {"key", SIMPLE_CONTENT, {.smpl = save_data} }, // {"integer", SIMPLE_CONTENT, {.smpl = save_data} }, // {"string", SIMPLE_CONTENT, {.smpl = save_data} }, // {"date", SIMPLE_CONTENT, {.smpl = save_data} }, { {"array", COMPLEX_CONTENT, {(bool (__cdecl *)(track_elem_t *,const char *,char *))skip_element} }, {"key", SIMPLE_CONTENT, {save_data} }, {"integer", SIMPLE_CONTENT, {save_data} }, {"string", SIMPLE_CONTENT, {save_data} }, {"date", SIMPLE_CONTENT, {save_data} }, // sunqueen modify end {"true", SIMPLE_CONTENT, {NULL} }, {"false", SIMPLE_CONTENT, {NULL} }, {NULL, UNKNOWN_CONTENT, {NULL} } }; i_ret = parse_dict( p_demux, p_input_node, p_track, p_xml_reader, "dict", track_elements ); msg_Dbg( p_demux, "name: %s, artist: %s, album: %s, genre: %s, trackNum: %s, location: %s", p_track->name, p_track->artist, p_track->album, p_track->genre, p_track->trackNum, p_track->location ); if( !p_track->location ) { msg_Err( p_demux, "Track needs Location" ); free_track( p_track ); return false; } msg_Info( p_demux, "Adding '%s'", p_track->location ); p_new_input = input_item_New( p_track->location, NULL ); input_item_node_AppendItem( p_input_node, p_new_input ); /* add meta info */ add_meta( p_new_input, p_track ); vlc_gc_decref( p_new_input ); p_demux->p_sys->i_ntracks++; free_track( p_track ); return i_ret; }
//================================================================ void free_track(int scene, int trackid) { if(!is_track(scene,trackid)) return; free_track(trackscenevec[scene]->trackvec[trackid]); trackscenevec[scene]->trackvec[trackid] = NULL; }
void free_all_tracks(void) { int i; for(i=0; i<MAXTRACKS; i++) free_track(i); last_track = 0; return; }
//================================================================ void free_all_tracks(int scene) { if(!is_track_scene(scene)) return; for( int i = 0; i < trackscenevec[scene]->trackvec.size(); ++i) { free_track(trackscenevec[scene]->trackvec[i]); trackscenevec[scene]->trackvec[i] = NULL; } trackscenevec[scene]->trackvec.clear(); trackscenevec[scene]->zorder.clear(); }
//================================================================ void free_all_tracks() { if(!is_scene_bound()) return; if(!is_track_scene(BoundScene)) return; for( int i = 0; i < trackscenevec[BoundScene]->trackvec.size(); ++i) { free_track(trackscenevec[BoundScene]->trackvec[i]); trackscenevec[BoundScene]->trackvec[i] = NULL; } trackscenevec[BoundScene]->trackvec.clear(); trackscenevec[BoundScene]->zorder.clear(); }
Track *add_track(Resource *r, char *name, MediaProperties *prop_hints) { Track *t; t = g_slice_new0(Track); t->lock = g_mutex_new(); t->parent = r; t->name = name; t->sdp_description = g_string_new(""); g_string_append_printf(t->sdp_description, "a=control:%s\r\n", name); memcpy(&t->properties, prop_hints, sizeof(MediaProperties)); switch (t->properties.media_source) { case STORED_SOURCE: if ( !(t->parser = mparser_find(t->properties.encoding_name)) ) { xlog(LOG_FAT, "Could not find a valid parser\n"); goto error; } t->properties.media_type = t->parser->media_type; break; case LIVE_SOURCE: break; default: g_assert_not_reached(); break; } if (t->parser && t->parser->init && t->parser->init(t) != 0) { xlog(LOG_FAT, "Could not initialize parser for %s\n", t->properties.encoding_name); goto error; } r->tracks = g_list_append(r->tracks, t); return t; error: free_track(t, NULL); return NULL; }
Track *add_track(Resource *r, TrackInfo *info, MediaProperties *prop_hints) { Track *t; gint new_producer; // TODO: search first of all in exclusive tracks if(r->num_tracks>=MAX_TRACKS) return NULL; t = g_slice_new0(Track); t->lock = g_mutex_new(); t->parent = r; t->info = g_slice_new0(TrackInfo); memcpy(t->info, info, sizeof(TrackInfo)); memcpy(&t->properties, prop_hints, sizeof(MediaProperties)); switch (t->properties.media_source) { case MS_stored: /* demuxer_jm */ if (r->mode == OM_SETUP) { if (prop_hints->media_type == MP_video) { if( !(t->producer = bq_producer_new(free_payload, NULL, &new_producer)) ) { rc_log(RC_LOG_FATAL, "add_track()->bq_producer_new() failed!"); goto error; } if (new_producer) { r_start_track(r, t->producer, t->info->mrl); } r->vp = t->producer; } else { if (r->vp) { t->producer = bq_producer_ref(r->vp); } } } if ( !(t->parser = mparser_find(t->properties.encoding_name)) ) { rc_log(RC_LOG_FATAL, "add_track()->mparser_find() failed!"); goto error; } if (t->parser->init(t)) { rc_log(RC_LOG_FATAL, "add_track()->parser->init(), for encoding:%s failed!", t->properties.encoding_name); goto error; } t->properties.media_type = t->parser->info->media_type; break; case MS_live: /* demuxer_ls */ if (r->mode == OM_SETUP) { if( !(t->producer = bq_producer_new(free_payload, t->info->mrl, &new_producer)) ) { rc_log(RC_LOG_FATAL, "add_track()->bq_producer_new() failed!"); goto error; } if (new_producer) { r_start_track(r, t->producer, t->info->mrl); } } break; default: rc_log(RC_LOG_FATAL, "add_track():Media source not supported!"); break; } r->tracks = g_list_append(r->tracks, t); r->num_tracks++; return t; error: free_track(t, r); return NULL; }
// // Function called when a new HTTP request have been recieved. // static void http_handler(struct evhttp_request *request, void *userdata) { struct owl_state* state = userdata; // Setup general response headers struct evkeyvalq *headers = evhttp_request_get_output_headers(request); evhttp_add_header(headers, "Server", USER_AGENT); // Get the requested URI const char* uri = evhttp_request_get_uri(request); const int http_method = evhttp_request_get_command(request); if( http_method != EVHTTP_REQ_GET && http_method != EVHTTP_REQ_PUT && http_method != EVHTTP_REQ_POST) { evhttp_send_error(request, 501, "Not Implemented"); return; } TRACE("Received HTTP request: %s (method %d)\n", uri, http_method); // Keep the request for async usage state->http_request = request; // // Retrieve application state (sync) if(string_starts_with(uri, "/api/state") && http_method == EVHTTP_REQ_GET) { state_action(state); } // // Shutdown owl application (async) else if(string_starts_with(uri, "/api/shutdown") && http_method == EVHTTP_REQ_GET) { shutdown_action(state); } // // Try to login to Spotify (async) else if(string_starts_with(uri, "/api/login") && http_method == EVHTTP_REQ_GET) { char* username = extract_uri_section(2, uri); char* password = extract_uri_section(3, uri); if(username != NULL && password != NULL) { login_to_spotify_action(state, username, password); } else { WARN("Could not extract username and password in order to login to Spotify!\n"); respond_error(request, OWL_HTTO_ERROR_NO_LOGIN_DETAILS, "No username or password given"); } } else if(string_starts_with(uri, "/api/login") && http_method == EVHTTP_REQ_POST) { TRACE("POST LOGIN\n"); get_post_argument(request, "username"); evhttp_send_error(request, 501, "Not Implemented"); } // // Logout from spotify (async) else if(string_starts_with(uri, "/api/logout") && http_method == EVHTTP_REQ_GET) { if(state->state > OWL_STATE_LOGGING_IN && state->state < OWL_STATE_LOGGING_OUT) logout_from_spotify_action(state); else respond_success(request); } // // Clear the entire queue else if(string_starts_with(uri, "/api/queue/clear") && http_method == EVHTTP_REQ_GET) { if(state->state < OWL_STATE_IDLE || state->state > OWL_STATE_PLAYING) { respond_error(request, OWL_HTTP_ERROR_NOT_LOGGED_IN, "Operation not allowed when not logged in"); } else { const int size = queue_size(state->spotify_state->queue); for(int i = 0; i < size; i++) { owl_track *track = pop_from_queue(state->spotify_state->queue); free_track(track); } respond_success(request); } } // // Get the current playback queue (sync) else if(string_starts_with(uri, "/api/queue") && http_method == EVHTTP_REQ_GET) { if(state->state < OWL_STATE_IDLE || state->state > OWL_STATE_PLAYING) { WARN("Operation not allowed at this state (%d)\n", state->state); respond_error(request, OWL_HTTP_ERROR_NOT_LOGGED_IN, "Operation not allowed when not logged in"); } else { respond_with_queue(state->http_request, state->spotify_state->queue); } } // // Serve static file immediately else { // Create the buffer to retrn as content struct evbuffer *content_buffer = evbuffer_new(); // If not a handler this is a static request char *static_file = (char *) malloc(strlen(doc_root) + strlen(uri) + 1); stpcpy(stpcpy(static_file, doc_root), uri); TRACE("Looking for static file: %s\n", static_file); bool file_exists = 1; struct stat st; if(stat(static_file, &st) == -1 || S_ISDIR(st.st_mode)) { file_exists = 0; evhttp_send_error(request, HTTP_NOTFOUND, "Not Found"); } if(file_exists) { const int file_size = st.st_size; FILE *fp = fopen(static_file, "r"); const char* content_type = resolve_content_type(static_file); evbuffer_add_file(content_buffer, fileno(fp), 0, file_size); // will close TRACE("Resolving content type for filename: %s to: %s\n", static_file, content_type); evhttp_add_header(headers, "Content-Type", content_type); evhttp_send_reply(request, HTTP_OK, "OK", content_buffer); } free(static_file); // Send the data evhttp_send_reply(request, HTTP_OK, USER_AGENT, content_buffer); // Free memrory evbuffer_free(content_buffer); } return; }