From 04bdd7af72aa9ab5aa81e38ca85d3f40e76f16d4 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 19 Nov 2013 22:26:35 +0100 Subject: timeline: add edl:// URIs Questionable change from user perspective, but internally needed to implement the next commit. Also useful for testing timeline stuff. --- DOCS/edl-mpv.rst | 9 +++++++++ DOCS/man/en/mpv.rst | 1 + Makefile | 1 + demux/demux_edl.c | 4 ++++ mpvcore/player/timeline/tl_edl.c | 4 +++- mpvcore/player/timeline/tl_mpv_edl.c | 5 +++-- stream/stream.c | 2 ++ stream/stream.h | 1 + stream/stream_edl.c | 21 +++++++++++++++++++++ 9 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 stream/stream_edl.c diff --git a/DOCS/edl-mpv.rst b/DOCS/edl-mpv.rst index 611182b003..4bdf5f7e0b 100644 --- a/DOCS/edl-mpv.rst +++ b/DOCS/edl-mpv.rst @@ -92,3 +92,12 @@ to ``20``, ``param3`` to ``value,escaped``, ``param4`` to ``value2``. Instead of line breaks, the character ``;`` can be used. Line feed bytes and ``;`` are treated equally. + +Syntax of EDL URIs +================== + +mpv accepts ``inline`` EDL data in form of ``edl://`` URIs. Other than the +header, the syntax is exactly the same. It's far more convenient to use ``;`` +instead of line breaks, but that is orthogonal. + +Example: ``edl://f1.mkv,length=5,start=10;f2.mkv,30,20;f3.mkv`` diff --git a/DOCS/man/en/mpv.rst b/DOCS/man/en/mpv.rst index 0ee64d41b6..da59041d7d 100644 --- a/DOCS/man/en/mpv.rst +++ b/DOCS/man/en/mpv.rst @@ -32,6 +32,7 @@ SYNOPSIS | **mpv** \mf://[filemask|\@listfile] [-mf options] [options] | **mpv** cdda://track[-endtrack][:speed][/device] [options] | **mpv** [file|mms[t]|http|httpproxy|rt[s]p|ftp|udp|smb]://[user:pass\@]URL[:port] [options] +| **mpv** edl://[edl specification as in edl-mpv.rst] DESCRIPTION diff --git a/Makefile b/Makefile index 07d05d7fe0..0f2707677f 100644 --- a/Makefile +++ b/Makefile @@ -234,6 +234,7 @@ SOURCES = audio/audio.c \ stream/rar.c \ stream/stream.c \ stream/stream_avdevice.c \ + stream/stream_edl.c \ stream/stream_file.c \ stream/stream_lavf.c \ stream/stream_memory.c \ diff --git a/demux/demux_edl.c b/demux/demux_edl.c index dd6c660f74..62103d67d2 100644 --- a/demux/demux_edl.c +++ b/demux/demux_edl.c @@ -34,6 +34,10 @@ static bool test_header(struct stream *s, char *header) static int try_open_file(struct demuxer *demuxer, enum demux_check check) { struct stream *s = demuxer->stream; + if (s->uncached_type == STREAMTYPE_EDL) { + demuxer->file_contents = bstr0(s->url); + return 0; + } if (check >= DEMUX_CHECK_UNSAFE) { if (!test_header(s, "mplayer EDL file") && !test_header(s, "mpv EDL v0\n")) diff --git a/mpvcore/player/timeline/tl_edl.c b/mpvcore/player/timeline/tl_edl.c index b4715e5a1f..7fe6547c35 100644 --- a/mpvcore/player/timeline/tl_edl.c +++ b/mpvcore/player/timeline/tl_edl.c @@ -70,7 +70,9 @@ void build_edl_timeline(struct MPContext *mpctx) struct bstr *lines = bstr_splitlines(tmpmem, mpctx->demuxer->file_contents); int linec = MP_TALLOC_ELEMS(lines); struct bstr header = bstr0("mplayer EDL file, version "); - if (bstr_startswith0(lines[0], "mpv EDL v0\n")) { + if (bstr_startswith0(lines[0], "mpv EDL v0\n") || + mpctx->demuxer->stream->uncached_type == STREAMTYPE_EDL) + { build_mpv_edl_timeline(mpctx); goto out; } diff --git a/mpvcore/player/timeline/tl_mpv_edl.c b/mpvcore/player/timeline/tl_mpv_edl.c index 4c44ea9fc8..1f4bbc268e 100644 --- a/mpvcore/player/timeline/tl_mpv_edl.c +++ b/mpvcore/player/timeline/tl_mpv_edl.c @@ -268,8 +268,9 @@ void build_mpv_edl_timeline(struct MPContext *mpctx) mp_msg(MSGT_CPLAYER, MSGL_ERR, "Error in EDL.\n"); return; } - // Don't allow arbitrary paths - fix_filenames(parts, mpctx->demuxer->filename); + // Source is .edl and not edl:// => don't allow arbitrary paths + if (mpctx->demuxer->stream->uncached_type != STREAMTYPE_EDL) + fix_filenames(parts, mpctx->demuxer->filename); build_timeline(mpctx, parts); talloc_free(parts); } diff --git a/stream/stream.c b/stream/stream.c index 3844721346..3febfa4189 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -78,6 +78,7 @@ extern const stream_info_t stream_info_dvd; extern const stream_info_t stream_info_bluray; extern const stream_info_t stream_info_rar_filter; extern const stream_info_t stream_info_rar_entry; +extern const stream_info_t stream_info_edl; static const stream_info_t *const stream_list[] = { #if HAVE_VCD @@ -114,6 +115,7 @@ static const stream_info_t *const stream_list[] = { &stream_info_memory, &stream_info_null, &stream_info_mf, + &stream_info_edl, &stream_info_rar_filter, &stream_info_rar_entry, &stream_info_file, diff --git a/stream/stream.h b/stream/stream.h index 651aa9a310..e4864f81b1 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -43,6 +43,7 @@ enum streamtype { STREAMTYPE_PVR, STREAMTYPE_TV, STREAMTYPE_MF, + STREAMTYPE_EDL, STREAMTYPE_AVDEVICE, }; diff --git a/stream/stream_edl.c b/stream/stream_edl.c new file mode 100644 index 0000000000..8f9c5a90af --- /dev/null +++ b/stream/stream_edl.c @@ -0,0 +1,21 @@ +// Dummy stream implementation to enable demux_edl, which is in turn a +// dummy demuxer implementation to enable tl_edl. + +#include "stream.h" + +static int s_open (struct stream *stream, int mode) +{ + if (mode != STREAM_READ) + return STREAM_ERROR; + + stream->type = STREAMTYPE_EDL; + stream->demuxer = "edl"; + + return STREAM_OK; +} + +const stream_info_t stream_info_edl = { + .name = "edl", + .open = s_open, + .protocols = (const char*[]){"edl", NULL}, +}; -- cgit v1.2.3