[MPlayer-dev-eng] Re: [PATCH] Recursively Nested ASX Playlists
Mrc Gran
mrc.gran at gmail.com
Sat Mar 10 23:40:14 CET 2007
Hello,
I've updated the patch making mplayer capable of playing recursively nested
asx playlists, removing a few unused lines and letting it cleaner (see
attachment).
I have been using it for days without detecting any problem with any site.
Has any developer had a look at it? I have not received any feedback.
[]s,
Marcus Granado
Hello,
>
> I'm sending a patch to make mplayer capable of playing recursively nested
> asx playlists.
> A nested asx playlist is one whose refs point to further asx list files
> instead of real media files such as wmv.
> (This patch is not to be confused with processing of entryrefs which seems
> to be already implemented at asxparser.c.)
>
> Both asx playlists and wmv files are of mime type x-ms-asf. This patches
> modifies stream/asf_streaming.c so that it looks for a file ending with
> '.asx' which, if found, returns a demux_type_playlist to mplayer.c instead
> of the expected demuxer_type_asf. This triggers mplayer.c to synchronously
> follow the recursive nested playlists.
> A new streaming type ASF_ASXPlaylist_e is added to asf.h to control the
> new code branch. The function play_tree_parser_get_line() also receives a
> new code branch to deal with buffered streams which is necessary in order to
> parse the playlist, buffered when the asf stream was opened.
>
> I felt the necessity to develop this patch because there are sites which
> use nested asx playlists, such as video.globo.com (see discussions at http://sourceforge.net/forum/forum.php?thread_id=1668761&forum_id=242727
> <http://sourceforge.net/forum/forum.php?thread_id=1668761&forum_id=242727>and
>
> http://sourceforge.net/mailarchive/forum.php?thread_id=31642270&forum_id=21800),
> and nested playlists are part of the microsoft specification for asx (
> http://msdn2.microsoft.com/en-us/library/bb262812.aspx).
> I also tested the patch against www.bbc.co.uk, www.cnn.com,
> http://wptv.wp.pl/news.html
> (mplayer -playlist http://i.wp.pl/a/f/asx/11771/wptvnews.asx) and all
> worked fine.
> Extra care was taken to modify the minimum amount of code and to minimize
> potential regressions.
>
> In case this patch is approved for inclusion in mplayer, I would be
> grateful if my name was cited in the list of contributors. All comments
> welcome.
>
> Thanks,
> Marcus C. Granado
> mrc [d-o-t] gran [a-t] gmail [d-o-t] com
> --
>
>
-------------- next part --------------
Index: stream/asf_streaming.c
===================================================================
--- stream/asf_streaming.c (revision 22505)
+++ stream/asf_streaming.c (working copy)
@@ -765,11 +765,42 @@
mp_msg(MSGT_NETWORK,MSGL_DBG2,"Response [%s]\n", http_hdr->buffer );
}
ret = asf_http_parse_response(asf_http_ctrl, http_hdr);
+
+ if (strstr(url->url,".asx")!=NULL) {
+ mp_msg(MSGT_NETWORK,MSGL_V,"ASXPlaylist detected: url=%s, bodysize=%i\n",url->url,http_hdr->body_size);
+ ret = 0;
+ asf_http_ctrl->streaming_type=ASF_ASXPlaylist_e;
+ }
+
if( ret<0 ) {
mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_HeaderParseFailed);
goto err_out;
}
switch( asf_http_ctrl->streaming_type ) {
+ case ASF_ASXPlaylist_e:
+
+ //read potentially remaining
+ //asx playlist data into buffer
+ do {
+ i = recv( fd, buffer, BUFFER_SIZE, 0 );
+ if( i<0 ) {
+ perror("read");
+ goto err_out;
+ }
+ if (i>0) http_response_append( http_hdr, buffer, i );
+ } while(i>0);
+
+ //move buffer from header to stream
+ if( http_hdr->body_size>0 ) {
+ if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {
+ goto err_out;
+ }
+ }
+
+ *demuxer_type = DEMUXER_TYPE_PLAYLIST;
+ done=1;
+ break;
+
case ASF_Live_e:
case ASF_Prerecorded_e:
case ASF_PlainText_e:
@@ -817,7 +848,7 @@
} while(!done);
stream->fd = fd;
- if( asf_http_ctrl->streaming_type==ASF_PlainText_e || asf_http_ctrl->streaming_type==ASF_Redirector_e ) {
+ if( asf_http_ctrl->streaming_type==ASF_PlainText_e || asf_http_ctrl->streaming_type==ASF_Redirector_e || asf_http_ctrl->streaming_type==ASF_ASXPlaylist_e) {
stream->streaming_ctrl->streaming_read = nop_streaming_read;
stream->streaming_ctrl->streaming_seek = nop_streaming_seek;
} else {
@@ -852,12 +883,13 @@
url_free(url);
mp_msg(MSGT_OPEN, MSGL_INFO, MSGTR_MPDEMUX_ASF_InfoStreamASFURL, stream->url);
- if((!strncmp(stream->url, "http", 4)) && (*file_format!=DEMUXER_TYPE_ASF && *file_format!=DEMUXER_TYPE_UNKNOWN)) {
+ if((!strncmp(stream->url, "http", 4)) && (*file_format!=DEMUXER_TYPE_ASF && *file_format!=DEMUXER_TYPE_UNKNOWN && *file_format!=DEMUXER_TYPE_PLAYLIST)) {
streaming_ctrl_free(stream->streaming_ctrl);
stream->streaming_ctrl = NULL;
return STREAM_UNSUPORTED;
}
+ *file_format = DEMUXER_TYPE_ASF;
if(asf_streaming_start(stream, file_format) < 0) {
mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_MPDEMUX_ASF_StreamingFailed);
streaming_ctrl_free(stream->streaming_ctrl);
@@ -865,7 +897,8 @@
return STREAM_UNSUPORTED;
}
- *file_format = DEMUXER_TYPE_ASF;
+ if (*file_format != DEMUXER_TYPE_PLAYLIST)
+ *file_format = DEMUXER_TYPE_ASF;
stream->type = STREAMTYPE_STREAM;
fixup_network_stream_cache(stream);
return STREAM_OK;
Index: mplayer.c
===================================================================
--- mplayer.c (revision 22505)
+++ mplayer.c (working copy)
@@ -2864,6 +2864,8 @@
mp_msg(MSGT_CPLAYER,MSGL_V,"Parsing playlist %s...\n",
filename_recode(filename));
entry = parse_playtree(mpctx->stream,0);
+ //TODO:limit depth of nested playlists
+ //to avoid following infinitely nested playlists.
mpctx->eof=playtree_add_playlist(entry);
goto goto_next_file;
}
Index: playtreeparser.c
===================================================================
--- playtreeparser.c (revision 22505)
+++ playtreeparser.c (working copy)
@@ -51,18 +51,46 @@
play_tree_parser_get_line(play_tree_parser_t* p) {
char *end,*line_end;
int r,resize = 0;
+ int buffered_stream=0;
+ if (p==NULL) return NULL;
+ if (p->stream !=NULL &&
+ p->stream->streaming_ctrl != NULL &&
+ p->stream->streaming_ctrl->buffer != NULL &&
+ p->stream->streaming_ctrl->buffer_size > 0) {
+ buffered_stream=1;
+ }
+
if(p->buffer == NULL) {
- p->buffer = malloc(BUF_STEP);
- p->buffer_size = BUF_STEP;
+ if (!buffered_stream) {
+ p->buffer = malloc(BUF_STEP);
+ p->buffer_size = BUF_STEP;
+ } else {
+ p->buffer_size = p->stream->streaming_ctrl->buffer_size + 1;
+ p->buffer = malloc(p->buffer_size);
+ memcpy( p->buffer, p->stream->streaming_ctrl->buffer, p->stream->streaming_ctrl->buffer_size );
+ p->buffer[p->buffer_size - 1] = '\0';
+ p->buffer_end = p->buffer_size;
+ p->stream->eof = 1;
+ free(p->stream->streaming_ctrl->buffer);
+ p->stream->streaming_ctrl->buffer=NULL;
+ p->stream->streaming_ctrl->buffer_size=0;
+ }
p->iter = p->buffer;
}
if(p->stream->eof && (p->buffer_end == 0 || p->iter[0] == '\0'))
return NULL;
-
- while(1) {
+ if (buffered_stream) {
+
+ end = strchr(p->iter,'\n');
+ if (!end) end = p->buffer + p->buffer_end;
+
+ } else {
+
+ while(1) {
+
if(resize) {
r = p->iter - p->buffer;
p->buffer = (char*)realloc(p->buffer,p->buffer_size+BUF_STEP);
@@ -91,6 +119,7 @@
continue;
}
break;
+ }
}
line_end = ((*(end-1)) == '\r') ? end-1 : end;
Index: libmpdemux/asf.h
===================================================================
--- libmpdemux/asf.h (revision 22505)
+++ libmpdemux/asf.h (working copy)
@@ -120,7 +120,8 @@
ASF_Prerecorded_e,
ASF_Redirector_e,
ASF_PlainText_e,
- ASF_Authenticate_e
+ ASF_Authenticate_e,
+ ASF_ASXPlaylist_e
} ASF_StreamType_e;
typedef struct {
More information about the MPlayer-dev-eng
mailing list