Index: stream/http.c =================================================================== --- stream/http.c (révision 19364) +++ stream/http.c (copie de travail) @@ -27,6 +27,9 @@ #include "network.h" #include "help_mp.h" +#define URL_YOU_TUBE_WATCH "http://www.youtube.com/watch?v=" +#define URL_YOU_TUBE_GET "http://www.youtube.com/get_video?video_id=%s&t=%s" +#define URL_YOU_TUBE_PLAYER "player2.swf?video_id=" extern mime_struct_t mime_type_table[]; extern int stream_cache_size; @@ -829,6 +832,7 @@ // Redirect case 301: // Permanently case 302: // Temporarily + case 303: // See Other // TODO: RFC 2616, recommand to detect infinite redirection loops next_url = http_get_field( http_hdr, "Location" ); if( next_url!=NULL ) { @@ -852,6 +856,46 @@ return -1; } +static char *get_youtube_video_url(stream_t *stream) { + char *vid, tid[128]; + int buf_len = 64 * 1024; + char *buf = malloc (buf_len); + char *video_url = NULL; + int pos = 0, len = 0; + char *s, *t; + + /* get YouTube video ID from URL */ + vid = stream->url + strlen (URL_YOU_TUBE_WATCH); + + /* grab the HTML page */ + do { + len = nop_streaming_read (stream->fd, buf + pos, buf_len, stream->streaming_ctrl); + pos += len; + } while (len != 0 && pos < buf_len); + + /* and parse it to retrieve the place where the Flash player is called */ + t = strstr (buf, URL_YOU_TUBE_PLAYER); + if (!t) + return NULL; + + /* now get the &=t parameter */ + s = strstr (t, "&t="); + if (!s) + return NULL; + + t = strstr (s + 3, "&nc="); + if (!t) + return NULL; + + snprintf (tid, ((t - s - 2) < 128) ? t - s - 2 : 128, "%s", s + 3); + video_url = malloc (strlen (URL_YOU_TUBE_GET) + strlen (vid) + strlen (tid) + 1); + + /* and finally, determine the real video url */ + sprintf (video_url, URL_YOU_TUBE_GET, vid, tid); + + return video_url; +} + static int fixup_open(stream_t *stream,int seekable) { HTTP_header_t *http_hdr = stream->streaming_ctrl->data; int is_icy = http_hdr && http_get_field(http_hdr, "Icy-MetaInt"); @@ -876,6 +920,59 @@ return STREAM_OK; } +static int open_youtube(stream_t *stream,int mode, void* opts, int* file_format) { + int seekable=0; + URL_t *url; + char *video_url = NULL; + + /* check for a valid YouTube.com URL */ + if (!strstr(stream->url,URL_YOU_TUBE_WATCH)) + return STREAM_UNSUPORTED; + + stream->streaming_ctrl = streaming_ctrl_new(); + if( stream->streaming_ctrl==NULL ) { + return STREAM_ERROR; + } + + stream->streaming_ctrl->bandwidth = network_bandwidth; + url = url_new(stream->url); + stream->streaming_ctrl->url = check4proxies(url); + url_free(url); + + /* this is a fake URL containing an HTML page. + * Let's download it, parse it and retrieve the real video url */ + http_streaming_start(stream, file_format); + video_url = get_youtube_video_url (stream); + + if (!video_url) { + streaming_ctrl_free(stream->streaming_ctrl); + stream->streaming_ctrl = NULL; + return STREAM_UNSUPORTED; + } + + + free (stream->url); + url_free (stream->streaming_ctrl->url); + + stream->url = strdup (video_url); + url = url_new(video_url); + stream->streaming_ctrl->url = check4proxies(url); + url_free(url); + + mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_HTTP_YOUTUBE, URL: %s\n", stream->url); + seekable = http_streaming_start(stream, file_format); + if(seekable < 0) { + streaming_ctrl_free(stream->streaming_ctrl); + stream->streaming_ctrl = NULL; + return STREAM_UNSUPORTED; + } + + /* content is Flash Video FLV */ + *file_format = DEMUXER_TYPE_LAVF; + + return fixup_open(stream, seekable); +} + static int open_s1(stream_t *stream,int mode, void* opts, int* file_format) { int seekable=0; URL_t *url; @@ -924,6 +1021,16 @@ return fixup_open(stream, seekable); } +stream_info_t stream_info_http_youtube = { + "HTTP Streaming from YouTube.com", + "null", + "Benjamin Zores", + "plain http", + open_youtube, + {"http", NULL}, + NULL, + 0 // Urls are an option string +}; stream_info_t stream_info_http1 = { "http streaming", Index: stream/stream.c =================================================================== --- stream/stream.c (révision 19364) +++ stream/stream.c (copie de travail) @@ -49,6 +49,7 @@ extern stream_info_t stream_info_rtsp; extern stream_info_t stream_info_rtp; extern stream_info_t stream_info_udp; +extern stream_info_t stream_info_http_youtube; extern stream_info_t stream_info_http1; extern stream_info_t stream_info_http2; #endif @@ -95,6 +96,7 @@ #endif #ifdef MPLAYER_NETWORK &stream_info_netstream, + &stream_info_http_youtube, &stream_info_http1, &stream_info_asf, &stream_info_pnm,