summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-10-30 22:24:25 +0100
committerwm4 <wm4@nowhere>2014-10-30 22:25:08 +0100
commit56b852710ad0b6b1466427549db0792ee67318aa (patch)
treeb411336c0162e6e8ba85a7c2bdba441d18987784 /demux
parent8c3baffadbff167a75c34024374cd08dae4a9cdd (diff)
downloadmpv-56b852710ad0b6b1466427549db0792ee67318aa.tar.bz2
mpv-56b852710ad0b6b1466427549db0792ee67318aa.tar.xz
demux_playlist: redirect ASF streaming to mmsh://
I'm not sure if this could be done in libavformat instead. Probably not, because libavformat doesn't seem to have any mechanism for trying one protocol and reverting (or redirecting) to another one if needed. This commit is sort of a hack too, because it redirects the URL by pretending the http:// link is a playlist containing the mmsh:// link. The list of mime types is borrowed from MPlayer (which has completely different code to handle this).
Diffstat (limited to 'demux')
-rw-r--r--demux/demux_playlist.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/demux/demux_playlist.c b/demux/demux_playlist.c
index 9f533e1b8e..905778e058 100644
--- a/demux/demux_playlist.c
+++ b/demux/demux_playlist.c
@@ -27,6 +27,17 @@
#define PROBE_SIZE (8 * 1024)
+static bool check_mimetype(struct stream *s, const char *const *list)
+{
+ if (s->mime_type) {
+ for (int n = 0; list && list[n]; n++) {
+ if (strcmp(s->mime_type, list[n]) == 0)
+ return true;
+ }
+ }
+ return false;
+}
+
struct pl_parser {
struct mp_log *log;
struct stream *s;
@@ -88,6 +99,22 @@ static int parse_ref_init(struct pl_parser *p)
bstr line = bstr_strip(pl_get_line(p));
if (!bstr_equals0(line, "[Reference]"))
return -1;
+
+ // ASF http streaming redirection - this is needed because ffmpeg http://
+ // and mmsh:// can not automatically switch automatically between each
+ // others. Both protocols use http - MMSH requires special http headers
+ // to "activate" it, and will in other cases return this playlist.
+ static const char *const mmsh_types[] = {"audio/x-ms-wax",
+ "audio/x-ms-wma", "video/x-ms-asf", "video/x-ms-afs", "video/x-ms-wmv",
+ "video/x-ms-wma", "application/x-mms-framed",
+ "application/vnd.ms.wms-hdr.asfv1", NULL};
+ bstr burl = bstr0(p->s->url);
+ if (bstr_eatstart0(&burl, "http://") && check_mimetype(p->s, mmsh_types)) {
+ MP_INFO(p, "Redirectiong to mmsh://\n");
+ playlist_add_file(p->pl, talloc_asprintf(p, "mmsh://%.*s", BSTR_P(burl)));
+ return 0;
+ }
+
while (!pl_eof(p)) {
line = bstr_strip(pl_get_line(p));
if (bstr_case_startswith(line, bstr0("Ref"))) {
@@ -153,15 +180,15 @@ static int parse_txt(struct pl_parser *p)
return 0;
}
+#define MIME_TYPES(...) \
+ .mime_types = (const char*const[]){__VA_ARGS__, NULL}
+
struct pl_format {
const char *name;
int (*parse)(struct pl_parser *p);
const char *const *mime_types;
};
-#define MIME_TYPES(...) \
- .mime_types = (const char*const[]){__VA_ARGS__, NULL}
-
static const struct pl_format formats[] = {
{"m3u", parse_m3u,
MIME_TYPES("audio/mpegurl", "audio/x-mpegurl", "application/x-mpegurl")},
@@ -172,17 +199,6 @@ static const struct pl_format formats[] = {
{"txt", parse_txt},
};
-static bool check_mimetype(struct stream *s, const char *const *list)
-{
- if (s->mime_type) {
- for (int n = 0; list && list[n]; n++) {
- if (strcmp(s->mime_type, list[n]) == 0)
- return true;
- }
- }
- return false;
-}
-
static const struct pl_format *probe_pl(struct pl_parser *p)
{
int64_t start = stream_tell(p->s);