diff --git a/DOCS/interface-changes/mpv-protocol.txt b/DOCS/interface-changes/mpv-protocol.txt
new file mode 100644
index 0000000000..5238d2e6f6
--- /dev/null
+++ b/DOCS/interface-changes/mpv-protocol.txt
@@ -0,0 +1 @@
+add `mpv://` protocol
diff --git a/DOCS/man/mpv.rst b/DOCS/man/mpv.rst
index 3ec696f7f9..6fd8ab74fe 100644
--- a/DOCS/man/mpv.rst
+++ b/DOCS/man/mpv.rst
@@ -1280,6 +1280,12 @@ More options to configure this functionality are listed in `Watch Later`_.
PROTOCOLS
=========
+``mpv://...``
+
+ mpv protocol. This is used for starting mpv from URL handler. The protocol
+ is stripped and the rest is passed to the player as a normal open argument.
+ Only safe protocols are allowed to be opened this way.
+
``http://...``, ``https://``, ...
Many network protocols are supported, but the protocol prefix must always
diff --git a/demux/demux.c b/demux/demux.c
index a35d62bcaf..6b36ed0c12 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -50,8 +50,9 @@
#include "cue.h"
// Demuxer list
-extern const struct demuxer_desc demuxer_desc_edl;
-extern const struct demuxer_desc demuxer_desc_cue;
+extern const demuxer_desc_t demuxer_desc_mpv;
+extern const demuxer_desc_t demuxer_desc_edl;
+extern const demuxer_desc_t demuxer_desc_cue;
extern const demuxer_desc_t demuxer_desc_rawaudio;
extern const demuxer_desc_t demuxer_desc_rawvideo;
extern const demuxer_desc_t demuxer_desc_mf;
@@ -80,6 +81,7 @@ static const demuxer_desc_t *const demuxer_list[] = {
&demuxer_desc_mf,
&demuxer_desc_playlist,
&demuxer_desc_null,
+ &demuxer_desc_mpv,
NULL
};
diff --git a/demux/demux_mpv.c b/demux/demux_mpv.c
new file mode 100644
index 0000000000..b1338744ee
--- /dev/null
+++ b/demux/demux_mpv.c
@@ -0,0 +1,45 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see .
+ */
+
+#include "demux.h"
+
+#include
+#include
+
+static int open_mpv(struct demuxer *demuxer, enum demux_check check)
+{
+ if (check != DEMUX_CHECK_REQUEST)
+ return -1;
+
+ struct stream *s = demuxer->stream;
+ if (!s->info || strcmp(s->info->name, "mpv"))
+ return -1;
+
+ demuxer->playlist = talloc_zero(demuxer, struct playlist);
+ playlist_append_file(demuxer->playlist, s->path);
+ playlist_set_stream_flags(demuxer->playlist, demuxer->stream_origin);
+ demuxer->fully_read = true;
+ demux_close_stream(demuxer);
+
+ return 0;
+}
+
+const struct demuxer_desc demuxer_desc_mpv = {
+ .name = "mpv",
+ .desc = "mpv protocol",
+ .open = open_mpv,
+};
diff --git a/etc/mpv.desktop b/etc/mpv.desktop
index baef395de4..6fba23f626 100644
--- a/etc/mpv.desktop
+++ b/etc/mpv.desktop
@@ -45,7 +45,7 @@ Exec=mpv --player-operation-mode=pseudo-gui -- %U
Terminal=false
Categories=AudioVideo;Audio;Video;Player;TV;
MimeType=application/ogg;application/x-ogg;application/mxf;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/vnd.dolby.heaac.1;audio/vnd.dolby.heaac.2;audio/aiff;audio/x-aiff;audio/m4a;audio/x-m4a;application/x-extension-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/mpeg2;audio/mpeg3;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/musepack;audio/x-musepack;audio/ogg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg2;video/x-mpeg3;video/mp4v-es;video/x-m4v;video/mp4;application/x-extension-mp4;video/divx;video/vnd.divx;video/msvideo;video/x-msvideo;video/ogg;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;audio/x-ms-asf;application/vnd.ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/avi;video/x-flic;video/fli;video/x-flc;video/flv;video/x-flv;video/x-theora;video/x-theora+ogg;video/x-matroska;video/mkv;audio/x-matroska;application/x-matroska;video/webm;audio/webm;audio/vorbis;audio/x-vorbis;audio/x-vorbis+ogg;video/x-ogm;video/x-ogm+ogg;application/x-ogm;application/x-ogm-audio;application/x-ogm-video;application/x-shorten;audio/x-shorten;audio/x-ape;audio/x-wavpack;audio/x-tta;audio/AMR;audio/ac3;audio/eac3;audio/amr-wb;video/mp2t;audio/flac;audio/mp4;application/x-mpegurl;video/vnd.mpegurl;application/vnd.apple.mpegurl;audio/x-pn-au;video/3gp;video/3gpp;video/3gpp2;audio/3gpp;audio/3gpp2;video/dv;audio/dv;audio/opus;audio/vnd.dts;audio/vnd.dts.hd;audio/x-adpcm;application/x-cue;audio/m3u;audio/vnd.wave;video/vnd.avi;
-X-KDE-Protocols=appending,file,ftp,hls,http,https,mms,rist,rtmp,rtmps,rtmpt,rtmpts,rtp,rtsp,rtsps,sftp,smb,srt,srtp,webdav,webdavs
+X-KDE-Protocols=appending,file,ftp,hls,http,https,mms,mpv,rist,rtmp,rtmps,rtmpt,rtmpts,rtp,rtsp,rtsps,sftp,smb,srt,srtp,webdav,webdavs
StartupWMClass=mpv
Keywords=mpv;media;player;video;audio;tv;
Keywords[ar]=mpv;إم بي في;ام بي في;وسائط;مشغل;فيديو;مرئية;صوتي;تلفاز;
diff --git a/meson.build b/meson.build
index c1d42d3fbb..620c19f1f2 100644
--- a/meson.build
+++ b/meson.build
@@ -100,6 +100,7 @@ sources = files(
'demux/demux_mf.c',
'demux/demux_mkv.c',
'demux/demux_mkv_timeline.c',
+ 'demux/demux_mpv.c',
'demux/demux_null.c',
'demux/demux_playlist.c',
'demux/demux_raw.c',
@@ -189,6 +190,7 @@ sources = files(
'stream/stream_lavf.c',
'stream/stream_memory.c',
'stream/stream_mf.c',
+ 'stream/stream_mpv.c',
'stream/stream_null.c',
'stream/stream_slice.c',
diff --git a/stream/stream.c b/stream/stream.c
index f0cd52d8b0..20fae4a20e 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -42,6 +42,7 @@
#include "options/m_option.h"
#include "options/m_config.h"
+extern const stream_info_t stream_info_mpv;
extern const stream_info_t stream_info_cdda;
extern const stream_info_t stream_info_dvb;
extern const stream_info_t stream_info_null;
@@ -63,6 +64,7 @@ extern const stream_info_t stream_info_libarchive;
extern const stream_info_t stream_info_cb;
static const stream_info_t *const stream_list[] = {
+ &stream_info_mpv,
#if HAVE_CDDA
&stream_info_cdda,
#endif
diff --git a/stream/stream_mpv.c b/stream/stream_mpv.c
new file mode 100644
index 0000000000..dd0e6e25c0
--- /dev/null
+++ b/stream/stream_mpv.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see .
+ */
+
+#include "stream.h"
+
+#include
+#include
+
+static int open_mpv(stream_t *st)
+{
+ bstr proto = mp_split_proto(bstr0(st->path), NULL);
+ if (proto.len) {
+ if (!bstrcasecmp0(proto, "mpv")) {
+ MP_ERR(st, "Nested mpv:// is not allowed.\n");
+ return STREAM_NO_MATCH;
+ }
+ char **safe_protocols = stream_get_proto_list(true);
+ bool safe = str_in_list(proto, safe_protocols);
+ talloc_free(safe_protocols);
+ if (!safe) {
+ MP_ERR(st, "Unsafe protocol '%.*s' opened with mpv://.\n", BSTR_P(proto));
+ return STREAM_NO_MATCH;
+ }
+ }
+
+ st->demuxer = "mpv";
+ return STREAM_OK;
+}
+
+const stream_info_t stream_info_mpv = {
+ .name = "mpv",
+ .open = open_mpv,
+ .protocols = (const char*const[]){"mpv", NULL},
+};