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, "Redirecting 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"))) { bstr_split_tok(line, "=", &(bstr){0}, &line); if (line.len) pl_add(p, line); } } return 0; }
static int parse_ref_init(struct pl_parser *p) { bstr line = bstr_strip(pl_get_line(p)); if (!bstr_equals0(line, "[Reference]")) return -1; while (!pl_eof(p)) { line = bstr_strip(pl_get_line(p)); if (bstr_case_startswith(line, bstr0("Ref"))) { bstr_split_tok(line, "=", &(bstr){0}, &line); if (line.len) pl_add(p, line); } } return 0; }
static int parse_m3u(struct pl_parser *p) { bstr line = bstr_strip(pl_get_line(p)); if (!bstr_equals0(line, "#EXTM3U")) return -1; if (p->probing) return 0; while (!pl_eof(p)) { line = bstr_strip(pl_get_line(p)); if (line.len == 0 || bstr_startswith0(line, "#")) continue; pl_add(p, line); } return 0; }
static int parse_mov_rtsptext(struct pl_parser *p) { bstr line = pl_get_line(p); if (!bstr_eatstart(&line, bstr0("RTSPtext"))) return -1; if (p->probing) return 0; line = bstr_strip(line); do { if (bstr_case_startswith(line, bstr0("rtsp://"))) { pl_add(p, line); return 0; } } while (!pl_eof(p) && (line = bstr_strip(pl_get_line(p))).len); return -1; }
static int parse_m3u(struct pl_parser *p) { bstr line = bstr_strip(pl_get_line(p)); if (p->probing && !bstr_equals0(line, "#EXTM3U")) { // Last resort: if the file extension is m3u, it might be headerless. if (p->check_level == DEMUX_CHECK_UNSAFE) { char *ext = mp_splitext(p->real_stream->url, NULL); bstr data = stream_peek(p->real_stream, PROBE_SIZE); if (ext && data.len > 10 && maybe_text(data)) { const char *exts[] = {"m3u", "m3u8", NULL}; for (int n = 0; exts[n]; n++) { if (strcasecmp(ext, exts[n]) == 0) goto ok; } } } return -1; } ok: if (p->probing) return 0; char *title = NULL; while (line.len || !pl_eof(p)) { if (bstr_eatstart0(&line, "#EXTINF:")) { bstr duration, btitle; if (bstr_split_tok(line, ",", &duration, &btitle) && btitle.len) { talloc_free(title); title = bstrto0(NULL, btitle); } } else if (bstr_startswith0(line, "#EXT-X-")) { p->format = "hls"; } else if (line.len > 0 && !bstr_startswith0(line, "#")) { char *fn = bstrto0(NULL, line); struct playlist_entry *e = playlist_entry_new(fn); talloc_free(fn); e->title = talloc_steal(e, title); title = NULL; playlist_add(p->pl, e); } line = bstr_strip(pl_get_line(p)); } talloc_free(title); return 0; }
static int parse_pls(struct pl_parser *p) { bstr line = {0}; while (!line.len && !pl_eof(p)) line = bstr_strip(pl_get_line(p)); if (bstrcasecmp0(line, "[playlist]") != 0) return -1; if (p->probing) return 0; while (!pl_eof(p)) { line = bstr_strip(pl_get_line(p)); bstr key, value; if (bstr_split_tok(line, "=", &key, &value) && bstr_case_startswith(key, bstr0("File"))) { pl_add(p, value); } } return 0; }
static int parse_m3u(struct pl_parser *p) { bstr line = bstr_strip(pl_get_line(p)); if (p->probing && !bstr_equals0(line, "#EXTM3U")) { // Last resort: if the file extension is m3u, it might be headerless. if (p->check_level == DEMUX_CHECK_UNSAFE) { char *ext = mp_splitext(p->real_stream->url, NULL); bstr data = stream_peek(p->real_stream, PROBE_SIZE); if (ext && !strcmp(ext, "m3u") && data.len > 10 && maybe_text(data)) goto ok; } return -1; } ok: if (p->probing) return 0; while (line.len || !pl_eof(p)) { if (line.len > 0 && !bstr_startswith0(line, "#")) pl_add(p, line); line = bstr_strip(pl_get_line(p)); } return 0; }
static int parse_txt(struct pl_parser *p) { if (!p->force) return -1; if (p->probing) return 0; MP_WARN(p, "Reading plaintext playlist.\n"); while (!pl_eof(p)) { bstr line = bstr_strip(pl_get_line(p)); if (line.len == 0) continue; pl_add(p, line); } return 0; }