struct mp_resolve_result *mp_resolve_quvi(const char *url, struct MPOpts *opts) { quvi_t q = quvi_new(); if (quvi_ok(q) == QUVI_FALSE) return NULL; // Don't try to use quvi on an URL that's not directly supported, since // quvi will do a network access anyway in order to check for HTTP // redirections etc. // The documentation says this will fail on "shortened" URLs. if (quvi_supports(q, (char *) url, QUVI_SUPPORTS_MODE_OFFLINE, QUVI_SUPPORTS_TYPE_ANY) == QUVI_FALSE) { quvi_free(q); return NULL; } mp_msg(MSGT_OPEN, MSGL_INFO, "[quvi] Checking URL...\n"); // Can use quvi_query_formats() to get a list of formats like this: // "fmt05_240p|fmt18_360p|fmt34_360p|fmt35_480p|fmt43_360p|fmt44_480p" // (This example is youtube specific.) // That call requires an extra net access. quvi_next_media_url() doesn't // seem to do anything useful. So we can't really do anything useful // except pass through the user's format setting. quvi_media_t m = quvi_media_new(q, (char *) url); if (quvi_ok(q) == QUVI_FALSE) { mp_msg(MSGT_OPEN, MSGL_ERR, "[quvi] %s\n", quvi_errmsg(q)); quvi_free(q); return NULL; } quvi_media_stream_select(m, opts->quvi_format); if (quvi_ok(q) == QUVI_FALSE) { mp_msg(MSGT_OPEN, MSGL_ERR, "[quvi] %s\n", quvi_errmsg(q)); quvi_free(q); return NULL; } struct mp_resolve_result *result = talloc_zero(NULL, struct mp_resolve_result); char *val; quvi_media_get(m, QUVI_MEDIA_STREAM_PROPERTY_URL, &val); if (quvi_ok(q) == QUVI_TRUE) result->url = talloc_strdup(result, val); quvi_media_get(m, QUVI_MEDIA_PROPERTY_TITLE, &val); if (quvi_ok(q) == QUVI_TRUE) result->title = talloc_strdup(result, val); quvi_media_free(m); quvi_free(q); if (!result->url) { talloc_free(result); result = NULL; } return result; }
gint main(gint argc, gchar **argv) { gint i,r; gchar *s; g_assert(qm == NULL); g_assert(q == NULL); memset(&opts, 0, sizeof(struct _opts_s)); setlocale(LC_ALL, ""); r = opts_new(argc, argv); if (r != EXIT_SUCCESS) return (r); q = quvi_new(); examples_exit_if_error(); if (opts.autoproxy == TRUE) examples_enable_autoproxy(); if (opts.verbose == TRUE) examples_enable_verbose(); quvi_set(q, QUVI_OPTION_CALLBACK_STATUS, (qcs) examples_status); for (i=0; opts.url[i] != NULL; ++i) { qm = quvi_media_new(q, opts.url[i]); examples_exit_if_error(); quvi_media_get(qm, QUVI_MEDIA_PROPERTY_TITLE, &s); g_print("[%s]\n title='%s'\n", __func__, s); if (opts.best == TRUE) { quvi_media_stream_choose_best(qm); dump_stream(); } else if (opts.stream != NULL) { quvi_media_stream_select(qm, opts.stream); examples_exit_if_error(); dump_stream(); } else dump_streams(); quvi_media_free(qm); qm = NULL; } opts_free(); examples_cleanup(); g_assert(qm == NULL); g_assert(q == NULL); return (r); }
static quvi_t new_q() { quvi_t q = quvi_new(); g_assert(q != NULL); g_assert_cmpint(quvi_errcode(q), ==, QUVI_OK); chk_verbose(q); return (q); }
gint main(gint argc, gchar **argv) { gchar *url = NULL; gint i = 1; g_assert(qr == NULL); g_assert(q == NULL); setlocale(LC_ALL, ""); q = quvi_new(); examples_exit_if_error(); quvi_set(q, QUVI_OPTION_CALLBACK_STATUS, (qcs) examples_status); for (; i<argc; ++i) { if (g_strcmp0("-v", argv[i]) == 0) examples_enable_verbose(); else if (g_strcmp0("-a", argv[i]) == 0) examples_enable_autoproxy(); else if (g_strcmp0("-h", argv[i]) == 0) help(); else url = argv[i]; } if (url == NULL) { g_printerr("[%s] no input given: using example URL instead\n", __func__); url = (gchar*) example_url; } g_printerr("[%s] url=%s\n", __func__, url); qr = quvi_resolve_new(q, url); examples_exit_if_error(); if (quvi_resolve_forwarded(qr) == QUVI_TRUE) { g_print("[%s] resolved=%s\n", __func__, quvi_resolve_destination_url(qr)); } else g_print("[%s] no redirection\n", __func__); examples_cleanup(); g_assert(qr == NULL); g_assert(q == NULL); return (0); }
static gboolean supports_uri (const char *uri) { quvi_t q; QuviBoolean r; q = quvi_new (); r = quvi_supports (q, uri, QUVI_SUPPORTS_MODE_OFFLINE, QUVI_SUPPORTS_TYPE_ANY); quvi_free (q); return r; }
static void parse_videosite (const char *uri) { quvi_t q; quvi_media_t qm; /* properties */ const char *video_uri; const char *title; const char *id; const char *content_type; const char *thumb_url; const char *container; double duration; double starttime; char *duration_str = NULL; char *starttime_str = NULL; if (!supports_uri (uri)) { g_print ("XPLAYER_PL_PARSER_RESULT_UNHANDLED"); return; } q = quvi_new (); qm = quvi_media_new (q, uri); /* Empty results list? */ if (quvi_media_stream_next(qm) != QUVI_TRUE) { if (debug) g_print ("Parsing '%s' failed with error: %s\n", uri, quvi_errmsg (q)); g_print ("XPLAYER_PL_PARSER_RESULT_ERROR"); goto out; } /* Choose the best stream */ quvi_media_stream_choose_best (qm); quvi_media_get (qm, QUVI_MEDIA_PROPERTY_TITLE, &title); quvi_media_get (qm, QUVI_MEDIA_PROPERTY_ID, &id); quvi_media_get (qm, QUVI_MEDIA_PROPERTY_THUMBNAIL_URL, &thumb_url); quvi_media_get (qm, QUVI_MEDIA_PROPERTY_DURATION_MS, &duration); if (duration) duration_str = g_strdup_printf ("%f", duration); quvi_media_get (qm, QUVI_MEDIA_STREAM_PROPERTY_URL, &video_uri); quvi_media_get (qm, QUVI_MEDIA_PROPERTY_START_TIME_MS, &starttime); if (starttime) starttime_str = g_strdup_printf ("%f", starttime); quvi_media_get (qm, QUVI_MEDIA_STREAM_PROPERTY_CONTAINER, &container); content_type = container_to_content_type (container); if (video_uri != NULL) { print (XPLAYER_PL_PARSER_FIELD_TITLE, title); print (XPLAYER_PL_PARSER_FIELD_ID, id); print (XPLAYER_PL_PARSER_FIELD_MOREINFO, uri); print (XPLAYER_PL_PARSER_FIELD_URI, video_uri); print (XPLAYER_PL_PARSER_FIELD_STARTTIME, starttime_str); print (XPLAYER_PL_PARSER_FIELD_CONTENT_TYPE, content_type); print (XPLAYER_PL_PARSER_FIELD_IMAGE_URI, thumb_url); print (XPLAYER_PL_PARSER_FIELD_DURATION, duration_str); } g_free (starttime_str); g_free (duration_str); out: quvi_media_free (qm); quvi_free (q); }
/* Test media properties. The 'e' parameter may be NULL, in which case * the test for exact values (e.g. title and ID) will be skipped. */ void qm_test(const gchar *func, const gchar *url, const qm_test_exact_t e, const qm_test_opts_t o) { quvi_media_t qm; quvi_t q; if (chk_skip(func) == TRUE) return; q = quvi_new(); g_assert(q != NULL); g_assert_cmpint(quvi_errcode(q), ==, QUVI_OK); chk_verbose(q); qm = quvi_media_new(q, url); g_test_message("errmsg=%s", quvi_errmsg(q)); g_assert_cmpint(quvi_errcode(q), ==, QUVI_OK); g_assert(qm != NULL); if (chk_complete()) { gint c; g_test_message("TEST_LEVEL=complete"); /* Exact values. */ if (e != NULL) { if (e->title != NULL) qm_cmp_s(QUVI_MEDIA_PROPERTY_TITLE, e->title); if (e->id != NULL) qm_cmp_s(QUVI_MEDIA_PROPERTY_ID, e->id); } /* Thumbnail, expected, but check length only. */ qm_chk_l(QUVI_MEDIA_PROPERTY_THUMBNAIL_URL); /* Optional. */ if (o->gt0.duration_ms == TRUE) qm_chk_gt0(QUVI_MEDIA_PROPERTY_DURATION_MS); if (o->gt0.start_time_ms== TRUE) qm_chk_gt0(QUVI_MEDIA_PROPERTY_START_TIME_MS); /* Streams. */ for (c=0; quvi_media_stream_next(qm) == QUVI_TRUE; ++c); g_assert_cmpint(c, >, 0); while (quvi_media_stream_next(qm) == QUVI_TRUE) { qm_chk_l(QUVI_MEDIA_STREAM_PROPERTY_URL); if (c >1) /* Must have a stream ID, when there are >1 streams. */ qm_chk_l(QUVI_MEDIA_STREAM_PROPERTY_ID); /* Optional. */ if (o->s_len_gt0.stream.container == TRUE) qm_chk_l(QUVI_MEDIA_STREAM_PROPERTY_CONTAINER); /* Optional: Video. */ if (o->gt0.stream.video.bitrate_kbit_s == TRUE) qm_chk_gt0(QUVI_MEDIA_STREAM_PROPERTY_VIDEO_BITRATE_KBIT_S); if (o->gt0.stream.video.height == TRUE) qm_chk_gt0(QUVI_MEDIA_STREAM_PROPERTY_VIDEO_HEIGHT); if (o->gt0.stream.video.width == TRUE) qm_chk_gt0(QUVI_MEDIA_STREAM_PROPERTY_VIDEO_WIDTH); if (o->s_len_gt0.stream.video.encoding == TRUE) qm_chk_l(QUVI_MEDIA_STREAM_PROPERTY_VIDEO_ENCODING); /* Optional: Audio. */ if (o->gt0.stream.audio.bitrate_kbit_s == TRUE) qm_chk_gt0(QUVI_MEDIA_STREAM_PROPERTY_AUDIO_BITRATE_KBIT_S); if (o->s_len_gt0.stream.audio.encoding == TRUE) qm_chk_l(QUVI_MEDIA_STREAM_PROPERTY_AUDIO_ENCODING); } } else {