Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8751,7 +8751,7 @@ Miscellaneous

Registers mpv as a media player on Windows. This includes adding registry
entries to associate mpv with media files and protocols, as well as enabling
autoplay handlers for Blu-ray, DVD, and CD-Audio.
autoplay handlers for Blu-ray, DVD, DVD-Audio, and CD-Audio.

Note that the registration is done in-place, so the current mpv.exe path will
be used. If you move mpv after registering it, you can re-run this command to
Expand All @@ -8764,7 +8764,8 @@ Miscellaneous

The list of the file extensions to register, can be controlled with the
``--video-exts``, ``--audio-exts``, ``--image-exts``, ``--playlist-exts``
and ``--archive-exts`` options.
and ``--archive-exts`` options. Disc images (``.iso``) and the ``.ifo``
and ``.bdmv`` files of DVD and Blu-ray folders are registered as well.

By default, mpv will be registered for the current user. To register it for
all users, run mpv as an administrator with this option. However, this is
Expand Down
85 changes: 60 additions & 25 deletions TOOLS/osxbundle/mpv.app/Contents/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
<string>io.mpv.mk3d</string>
<string>io.mpv.mts</string>
<string>io.mpv.nsv</string>
<string>io.mpv.vcd</string>
<string>io.mpv.vob</string>
<string>io.mpv.webm</string>
<string>io.mpv.wmv</string>
Expand All @@ -89,6 +88,24 @@
<string>public.video</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>Disc File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSItemContentTypes</key>
<array>
<string>io.mpv.bdmv</string>
<string>io.mpv.ifo</string>
<string>public.iso-image</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
Expand Down Expand Up @@ -191,7 +208,6 @@
<array>
<string>cdda</string>
<string>dvd</string>
<string>vcd</string>
Comment thread
kasper93 marked this conversation as resolved.
Resolved
<string>bd</string>
</array>
</dict>
Expand Down Expand Up @@ -747,29 +763,6 @@
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>Video CD File</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.vcd</string>
<key>UTTypeReferenceURL</key>
<string>https://en.wikipedia.org/wiki/Video_CD</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>vcd</string>
<string>svcd</string>
<string>dat</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
Expand Down Expand Up @@ -958,6 +951,48 @@
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>DVD Information File</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.ifo</string>
<key>UTTypeReferenceURL</key>
<string>https://en.wikipedia.org/wiki/DVD-Video</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>ifo</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Blu-ray Disc Information File</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.bdmv</string>
<key>UTTypeReferenceURL</key>
<string>https://en.wikipedia.org/wiki/Blu-ray</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>bdmv</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
Expand Down
2 changes: 1 addition & 1 deletion etc/mpv.desktop
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ TryExec=mpv
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;
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-content/video-dvd;x-content/video-bluray;x-content/audio-dvd;application/vnd.efi.iso;application/x-cd-image;
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;
Expand Down
108 changes: 63 additions & 45 deletions osdep/w32_register.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,50 @@ static wchar_t *w32_get_shortcut_path(struct mp_log *log)
return shortcut_path;
}

static void remove_registration(struct mp_log *log, HKEY root)
{
reg_del(log, root, KEY_MPV_APP_PATH(".exe"), NULL);
reg_del(log, root, KEY_MPV_APP_PATH(".com"), NULL);
reg_del(log, root, KEY_MPV_APP, NULL);
reg_del(log, root, KEY_MPV_CAPABILITIES_APP, NULL);
reg_del(log, root, L"Software\\RegisteredApplications", MPV_NAME);

reg_del(log, root, KEY_MPV_PROG_ID("bluray"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("cdda"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("dvd"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("dvda"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("file"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("url"), NULL);

reg_del(log, root, KEY_AUTOPLAY L"\\Handlers\\MpvPlayCDAudioOnArrival", NULL);
reg_del(log, root, KEY_AUTOPLAY L"\\EventHandlers\\PlayCDAudioOnArrival",
L"MpvPlayCDAudioOnArrival");
reg_del(log, root, KEY_AUTOPLAY L"\\Handlers\\MpvPlayDVDMovieOnArrival", NULL);
reg_del(log, root, KEY_AUTOPLAY L"\\EventHandlers\\PlayDVDMovieOnArrival",
L"MpvPlayDVDMovieOnArrival");
reg_del(log, root, KEY_AUTOPLAY L"\\Handlers\\MpvPlayDVDAudioOnArrival", NULL);
reg_del(log, root, KEY_AUTOPLAY L"\\EventHandlers\\PlayDVDAudioOnArrival",
L"MpvPlayDVDAudioOnArrival");
reg_del(log, root, KEY_AUTOPLAY L"\\Handlers\\MpvPlayBluRayOnArrival", NULL);
reg_del(log, root, KEY_AUTOPLAY L"\\EventHandlers\\PlayBluRayOnArrival",
L"MpvPlayBluRayOnArrival");

wchar_t *shortcut_path = w32_get_shortcut_path(log);
if (shortcut_path) {
mp_msg(log, MSGL_V, "Removing shortcut: '%ls'\n", shortcut_path);
if (!DeleteFileW(shortcut_path)) {
DWORD err = GetLastError();
mp_msg(log, err == ERROR_FILE_NOT_FOUND ? MSGL_DEBUG : MSGL_ERR,
"Failed to delete shortcut: '%ls' -> %s\n", shortcut_path,
mp_LastError_to_str());
}
LocalFree(shortcut_path);
}

reg_del(log, root, KEY_MPV_UNINSTALL, NULL);
}

#define REGISTER_AUTOPLAY_HANDLER(media, event, action) \
reg_add_str(log, root, KEY_MPV_PROG_ID(media) L"\\shell", NULL, L"open"); \
reg_add_str(log, root, KEY_MPV_PROG_ID(media) L"\\shell\\open\\command", \
NULL, L"mpv.exe " media L":// --" media L"-device=%L"); \
reg_add_str(log, root, \
Expand Down Expand Up @@ -258,6 +300,8 @@ static void w32_register(struct MPContext *mpctx)
mp_msg(log, MSGL_INFO, "Registering mpv for %s...\n",
root == HKEY_LOCAL_MACHINE ? "all users" : "the current user");

remove_registration(log, root);

// Register mpv as an application
// <https://learn.microsoft.com/windows/win32/shell/app-registration>
reg_add_str(log, root, KEY_MPV_APP_PATH(".exe"), NULL, mpv_path);
Expand All @@ -275,7 +319,6 @@ static void w32_register(struct MPContext *mpctx)
// reg_add_str(log, root, KEY_MPV_APP, L"FriendlyAppName", MPV_FRIENDLY_NAME);

// Add shell open command
reg_add_str(log, root, KEY_MPV_APP L"\\shell", NULL, L"open");
reg_add_str(log, root, KEY_MPV_APP L"\\shell\\open\\command", NULL,
L"mpv.exe -- \"%L\"");

Expand All @@ -294,7 +337,6 @@ static void w32_register(struct MPContext *mpctx)
reg_add_dwr(log, root, KEY_MPV_PROG_ID("url"), L"EditFlags", FTA_Show);
reg_add_str(log, root, KEY_MPV_PROG_ID("url"), L"FriendlyTypeName",
L"mpv URL handler");
reg_add_str(log, root, KEY_MPV_PROG_ID("url") L"\\shell", NULL, L"open");
reg_add_str(log, root, KEY_MPV_PROG_ID("url") L"\\shell\\open\\command",
NULL, L"mpv.exe -- \"%L\"");
reg_add_str(log, root, KEY_MPV_PROG_ID("url") L"\\shell\\open\\ddeexec",
Expand Down Expand Up @@ -336,20 +378,30 @@ static void w32_register(struct MPContext *mpctx)
mp_from_utf8(tmp, protocols_str));
}

// Register file handler
reg_add_str(log, root, KEY_MPV_PROG_ID("file"), NULL, L"mpv");
reg_add_str(log, root, KEY_MPV_PROG_ID("file"), L"FriendlyTypeName", L"mpv Media File");
// Register file handler. Without a name, so it will be identified by its extension.
reg_add_dwr(log, root, KEY_MPV_PROG_ID("file"), L"EditFlags", FTA_OpenIsSafe);
reg_add_str(log, root, KEY_MPV_PROG_ID("file") L"\\shell", NULL, L"open");
reg_add_str(log, root, KEY_MPV_PROG_ID("file") L"\\shell\\open\\command",
NULL, L"mpv.exe -- \"%L\"");

// Register file associations
char *disc_exts[] = {
#if HAVE_DVDNAV || HAVE_DVDA || HAVE_LIBBLURAY
"iso",
#endif
#if HAVE_DVDNAV || HAVE_DVDA
"ifo",
#endif
#if HAVE_LIBBLURAY
"bdmv",
#endif
NULL
};
char **exts_groups[] = {
#if HAVE_LIBARCHIVE
mpctx->opts->archive_exts,
#endif
mpctx->opts->audio_exts,
disc_exts,
mpctx->opts->image_exts,
mpctx->opts->playlist_exts,
mpctx->opts->video_exts,
Expand Down Expand Up @@ -425,6 +477,8 @@ static void w32_register(struct MPContext *mpctx)
if (SUCCEEDED(PathCchRemoveFileSpec(mpv_path, MP_PATH_MAX)))
reg_add_str(log, root, KEY_MPV_UNINSTALL, L"InstallLocation", mpv_path);

SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);

mp_msg(log, MSGL_INFO, "mpv has been successfully registered.\n");
mp_msg(log, MSGL_INFO, "Note: The mpv binary has not been copied or moved. Please keep it in the current directory.\n");
mp_msg(log, MSGL_INFO, "If you move it, simply run this process again to re-register.\n");
Expand All @@ -440,45 +494,9 @@ static void w32_unregister(struct MPContext *mpctx)
mp_msg(log, MSGL_INFO, "Unregistering mpv for %s...\n",
root == HKEY_LOCAL_MACHINE ? "all users" : "the current user");

reg_del(log, root, KEY_MPV_APP_PATH(".exe"), NULL);
reg_del(log, root, KEY_MPV_APP_PATH(".com"), NULL);
reg_del(log, root, KEY_MPV_APP, NULL);
reg_del(log, root, KEY_MPV_CAPABILITIES_APP, NULL);
reg_del(log, root, L"Software\\RegisteredApplications", MPV_NAME);

reg_del(log, root, KEY_MPV_PROG_ID("bluray"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("cdda"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("dvd"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("dvda"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("file"), NULL);
reg_del(log, root, KEY_MPV_PROG_ID("url"), NULL);
remove_registration(log, root);

reg_del(log, root, KEY_AUTOPLAY L"\\Handlers\\MpvPlayCDAudioOnArrival", NULL);
reg_del(log, root, KEY_AUTOPLAY L"\\EventHandlers\\PlayCDAudioOnArrival",
L"MpvPlayCDAudioOnArrival");
reg_del(log, root, KEY_AUTOPLAY L"\\Handlers\\MpvPlayDVDMovieOnArrival", NULL);
reg_del(log, root, KEY_AUTOPLAY L"\\EventHandlers\\PlayDVDMovieOnArrival",
L"MpvPlayDVDMovieOnArrival");
reg_del(log, root, KEY_AUTOPLAY L"\\Handlers\\MpvPlayDVDAudioOnArrival", NULL);
reg_del(log, root, KEY_AUTOPLAY L"\\EventHandlers\\PlayDVDAudioOnArrival",
L"MpvPlayDVDAudioOnArrival");
reg_del(log, root, KEY_AUTOPLAY L"\\Handlers\\MpvPlayBluRayOnArrival", NULL);
reg_del(log, root, KEY_AUTOPLAY L"\\EventHandlers\\PlayBluRayOnArrival",
L"MpvPlayBluRayOnArrival");

wchar_t *shortcut_path = w32_get_shortcut_path(log);
if (shortcut_path) {
mp_msg(log, MSGL_V, "Removing shortcut: '%ls'\n", shortcut_path);
if (!DeleteFileW(shortcut_path)) {
DWORD err = GetLastError();
mp_msg(log, err == ERROR_FILE_NOT_FOUND ? MSGL_DEBUG : MSGL_ERR,
"Failed to delete shortcut: '%ls' -> %s\n", shortcut_path,
mp_LastError_to_str());
}
LocalFree(shortcut_path);
}

reg_del(log, root, KEY_MPV_UNINSTALL, NULL);
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);

mp_msg(log, MSGL_INFO, "mpv has been successfully unregistered.\n");
mp_msg(log, MSGL_INFO, "You may now safely delete the mpv binary if desired.\n");
Expand Down
10 changes: 7 additions & 3 deletions stream/stream_bluray.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,7 +1742,7 @@ const stream_info_t stream_info_bluray = {

static bool check_bdmv(const char *path)
{
if (strcasecmp(mp_basename(path), "MovieObject.bdmv"))
if (!bstr_case_endswith(bstr0(path), bstr0(".bdmv")))
return false;

FILE *temp = fopen(path, "rb");
Expand All @@ -1754,7 +1754,10 @@ static bool check_bdmv(const char *path)

if (fread(data, 50, 1, temp) == 1) {
bstr bdata = {data, 50};
ret = bstr_startswith0(bdata, "MOBJ0100") || // AVCHD
ret = bstr_startswith0(bdata, "INDX0100") || // AVCHD
bstr_startswith0(bdata, "INDX0200") || // Blu-ray
bstr_startswith0(bdata, "INDX0300") || // UHD BD
bstr_startswith0(bdata, "MOBJ0100") || // AVCHD
bstr_startswith0(bdata, "MOBJ0200") || // Blu-ray
bstr_startswith0(bdata, "MOBJ0300"); // UHD BD
}
Expand Down Expand Up @@ -1815,7 +1818,8 @@ static int bdmv_dir_stream_open(stream_t *stream)
}

// We allow the path to point to a directory containing BDMV/, a
// directory containing MovieObject.bdmv, or that file itself.
// directory containing MovieObject.bdmv, or index.bdmv or
// MovieObject.bdmv in it.
if (!check_bdmv(path)) {
// On UNIX, just assume the filename has always this case.
char *npath = mp_path_join(priv, path, "MovieObject.bdmv");
Expand Down
10 changes: 5 additions & 5 deletions stream/stream_dvda.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,19 +878,19 @@ const stream_info_t stream_info_dvda = {
.stream_origin = STREAM_ORIGIN_UNSAFE,
};

// Check if this is likely to be AUDIO_TS.IFO.
// Check if this is likely to be an IFO file of a DVD-Audio disc.
static bool check_ifo(const char *path)
{
if (strcasecmp(mp_basename(path), "audio_ts.ifo"))
if (!bstr_case_endswith(bstr0(path), bstr0(".ifo")))
return false;

FILE *temp = fopen(path, "rb");
if (!temp)
return false;

char data[12];
char data[8];
bool r = fread(data, sizeof(data), 1, temp) == 1 &&
memcmp(data, "DVDAUDIO-AMG", 12) == 0;
memcmp(data, "DVDAUDIO", 8) == 0;

fclose(temp);
return r;
Expand Down Expand Up @@ -929,7 +929,7 @@ static int ifo_dvda_stream_open(stream_t *stream)
}

// We allow the path to point to a directory containing AUDIO_TS/, a
// directory containing AUDIO_TS.IFO, or that file itself.
// directory containing AUDIO_TS.IFO, or any IFO file in it.
if (!check_ifo(path)) {
// On UNIX, just assume the filename is always uppercase.
char *npath = mp_path_join(priv, path, "AUDIO_TS.IFO");
Expand Down
Loading
Loading