static int pl_addauto_unlocked(tcvp_playlist_t *tpl, char **files, int n, int p) { int i, nadd = 0; if(p < 0) p = tpl->nf + p + 1; if(p < 0) p = 0; for(i = 0; i < n; i++){ char *m = stream_magic_url(files[i]); if(!m) continue; if(!strcmp(m, "application/x-playlist")){ int np = pl_addlist(tpl, files[i], p); if(np > 0){ p += np; nadd += np; } } else { pl_add(tpl, files + i, 1, p++); nadd++; } free(m); } return nadd; }
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_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; }
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_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; }