stream: handle mms streaming with ffmpeg

Use ffmpeg (stream_lavf) instead of internal mms support (asf_streaming.c)
for mms://, mmsh://, mmst:// URLs.

The old implementation is available under mp_mms:// etc.

There are some caveats with this:
- mms:// now always maps to mmsh://. It won't try mmst://. (I'm not sure
  if mms:// URLs really can use the mmst protocol, though.)
- MMS streams under the http:// prefix are not handled. (ffmpeg ticket
  #2001.) (Was already broken in mpv since c02f25.)
- It downloads all video streams now. MMS streams often have redundant
  video streams, which encode the main stream at different quality. The
  client is supposed to select one according to its bandwidth
  requirements. (Explicit MMS stream selection has been broken in mpv
  for a while, because MPOpts.vid maps to the stream number, not the
  demuxer's stream ID - but the old logic doesn't work anyway when
  using demuxer_lavf as opposed to demux_asf.)
This commit is contained in:
wm4 2012-12-08 15:41:03 +01:00
parent 5bf8706d1f
commit eb787267c8
3 changed files with 23 additions and 14 deletions

View File

@ -77,7 +77,7 @@ static int asf_streaming_start( stream_t *stream, int *demuxer_type) {
int port = stream->streaming_ctrl->url->port;
//Is protocol mms or mmst?
if (!strcasecmp(proto, "mmst") || !strcasecmp(proto, "mms"))
if (!strcasecmp(proto, "mp_mmst") || !strcasecmp(proto, "mp_mms"))
{
mp_msg(MSGT_NETWORK,MSGL_V,"Trying ASF/TCP...\n");
fd = asf_mmst_streaming_start( stream );
@ -88,9 +88,9 @@ static int asf_streaming_start( stream_t *stream, int *demuxer_type) {
}
//Is protocol http, http_proxy, or mms?
if (!strcasecmp(proto, "http_proxy") || !strcasecmp(proto, "http") ||
!strcasecmp(proto, "mms") || !strcasecmp(proto, "mmsh") ||
!strcasecmp(proto, "mmshttp"))
if (!strcasecmp(proto, "mp_http_proxy") || !strcasecmp(proto, "mp_http") ||
!strcasecmp(proto, "mp_mms") || !strcasecmp(proto, "mp_mmsh") ||
!strcasecmp(proto, "mp_mmshttp"))
{
mp_msg(MSGT_NETWORK,MSGL_V,"Trying ASF/HTTP...\n");
fd = asf_http_streaming_start( stream, demuxer_type );
@ -552,7 +552,7 @@ static HTTP_header_t *asf_http_request(streaming_ctrl_t *streaming_ctrl) {
http_add_basic_authentication( http_hdr, url->username, url->password );
// Check if we are using a proxy
if( !strcasecmp( url->protocol, "http_proxy" ) ) {
if( !strcasecmp( url->protocol, "mp_http_proxy" ) ) {
server_url = url_new( (url->file)+1 );
if( server_url==NULL ) {
mp_tmsg(MSGT_NETWORK,MSGL_ERR,"invalid proxy URL\n");
@ -707,7 +707,7 @@ static int asf_http_streaming_start( stream_t *stream, int *demuxer_type ) {
done = 1;
if( fd>0 ) closesocket( fd );
if( !strcasecmp( url->protocol, "http_proxy" ) ) {
if( !strcasecmp( url->protocol, "mp_http_proxy" ) ) {
if( url->port==0 ) url->port = 8080;
} else {
if( url->port==0 ) url->port = 80;
@ -826,7 +826,7 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
stream->streaming_ctrl->url = url_new_with_proxy(stream->url);
mp_tmsg(MSGT_OPEN, MSGL_INFO, "STREAM_ASF, URL: %s\n", stream->url);
if((!strncmp(stream->url, "http", 4)) && (*file_format!=DEMUXER_TYPE_ASF && *file_format!=DEMUXER_TYPE_UNKNOWN)) {
if((!strncmp(stream->url, "mp_http", 4)) && (*file_format!=DEMUXER_TYPE_ASF && *file_format!=DEMUXER_TYPE_UNKNOWN)) {
streaming_ctrl_free(stream->streaming_ctrl);
stream->streaming_ctrl = NULL;
return STREAM_UNSUPPORTED;
@ -851,7 +851,7 @@ const stream_info_t stream_info_asf = {
"Bertrand, Reimar Doeffinger, Albeu",
"originally based on work by Majormms (is that code still there?)",
open_s,
{"mms", "mmst", "http", "http_proxy", "mmsh", "mmshttp", NULL},
{"mp_mms", "mp_mmst", "mp_http", "mp_http_proxy", "mp_mmsh", "mp_mmshttp", NULL},
NULL,
0 // Urls are an option string
};

View File

@ -81,7 +81,7 @@
#define STREAM_ERROR 0
#define STREAM_OK 1
#define MAX_STREAM_PROTOCOLS 10
#define MAX_STREAM_PROTOCOLS 20
#define STREAM_CTRL_RESET 0
#define STREAM_CTRL_GET_TIME_LENGTH 1

View File

@ -94,9 +94,9 @@ static const char * const prefix[] = { "lavf://", "ffmpeg://" };
static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
{
int flags = 0;
const char *filename;
AVIOContext *avio = NULL;
int res = STREAM_ERROR;
void *temp = talloc_new(NULL);
if (mode == STREAM_READ)
flags = AVIO_FLAG_READ;
@ -108,9 +108,8 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
goto out;
}
if (stream->url)
filename = stream->url;
else {
const char *filename = stream->url;
if (!filename) {
mp_msg(MSGT_OPEN, MSGL_ERR, "[ffmpeg] No URL\n");
goto out;
}
@ -129,6 +128,14 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
}
mp_msg(MSGT_OPEN, MSGL_V, "[ffmpeg] Opening %s\n", filename);
// Replace "mms://" with "mmsh://", so that most mms:// URLs just work.
bstr b_filename = bstr0(filename);
if (bstr_eatstart0(&b_filename, "mms://") ||
bstr_eatstart0(&b_filename, "mmshttp://"))
{
filename = talloc_asprintf(temp, "mmsh://%.*s", BSTR_P(b_filename));
}
if (avio_open(&avio, filename, flags) < 0)
goto out;
@ -157,6 +164,7 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
res = STREAM_OK;
out:
talloc_free(temp);
return res;
}
@ -166,7 +174,8 @@ const stream_info_t stream_info_ffmpeg = {
"",
"",
open_f,
{ "lavf", "ffmpeg", "rtmp", "rtsp", "http", "https", NULL },
{ "lavf", "ffmpeg", "rtmp", "rtsp", "http", "https", "mms", "mmst", "mmsh",
"mmshttp", NULL },
NULL,
1 // Urls are an option string
};