Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27996bf1de | ||
|
|
e3d3a47c0d | ||
|
|
b109d20ef7 | ||
|
|
3c7d49c38f | ||
|
|
0ba2da8a76 | ||
|
|
1871f2a703 | ||
|
|
4a8e5ea269 | ||
|
|
367665b4c4 | ||
|
|
46437e96c6 | ||
|
|
29d3bbdaa2 | ||
|
|
16c3b27d0a | ||
|
|
f8dc208d0c | ||
|
|
6d006a5a39 | ||
|
|
6a355959d9 | ||
|
|
36bdbbe716 | ||
|
|
c269fa1609 | ||
|
|
0f1d6c09e0 | ||
|
|
b677937c27 | ||
|
|
fdd648bdf9 | ||
|
|
334fd10f1c | ||
|
|
226735331c | ||
|
|
5523370ab9 | ||
|
|
8c7d61f1d9 | ||
|
|
f021b5a379 | ||
|
|
43e164964c | ||
|
|
aeb64723fd | ||
|
|
f935838b2d | ||
|
|
ec46ad79e2 | ||
|
|
d6ccc4d8de | ||
|
|
8664dc3c47 | ||
|
|
51ce535822 | ||
|
|
e33df9b7bc | ||
|
|
6310bd60e6 | ||
|
|
6729e39983 | ||
|
|
88f247c0af |
No files matched your search
@@ -1,25 +0,0 @@
|
||||
### mpv version and platform
|
||||
|
||||
If you're not using git master or the latest release, update.
|
||||
Releases are listed here: https://github.com/mpv-player/mpv/releases
|
||||
|
||||
### Reproduction steps
|
||||
|
||||
### Expected behavior
|
||||
|
||||
### Actual behavior
|
||||
|
||||
### Log file
|
||||
|
||||
Make a log file made with -v or --log-file=output.txt, paste it to
|
||||
http://sprunge.us or a similar site, and replace this text with a link to it.
|
||||
|
||||
Providing a log file is strongly encouraged. It is very helpful for reproducing
|
||||
bugs or getting important technical context. Without a log it might not be
|
||||
possible to analyze and fix certain bugs, and your bug report will be closed
|
||||
or ignored.
|
||||
|
||||
### Sample files
|
||||
|
||||
Sample files needed to reproduce this issue can be uploaded to https://0x0.st/
|
||||
or similar sites. (Only needed if the issue cannot be reproduced without it.)
|
||||
@@ -1,7 +0,0 @@
|
||||
Ideally, you shouldn't need enter any text here, and your commit messages should
|
||||
explain your changes sufficiently (especially why they are needed). Read
|
||||
https://github.com/mpv-player/mpv/blob/master/DOCS/contribute.md for coding
|
||||
style and development conventions. Remove this text block, but if you haven't
|
||||
agreed to it before, leave the following sentence in place:
|
||||
|
||||
I agree that my changes can be relicensed to LGPL 2.1 or later.
|
||||
+1
-3
@@ -14,12 +14,12 @@
|
||||
/input/input_conf.h
|
||||
/tags
|
||||
/TAGS
|
||||
/video/out/gl_video_shaders.h
|
||||
/video/out/x11_icon.inc
|
||||
/demux/ebml_defs.c
|
||||
/demux/ebml_types.h
|
||||
/sub/osd_font.h
|
||||
/player/lua/*.inc
|
||||
/player/builtin_conf.inc
|
||||
/DOCS/man/mpv.1
|
||||
/DOCS/man/mpv.aux
|
||||
/DOCS/man/mpv.log
|
||||
@@ -28,8 +28,6 @@
|
||||
/DOCS/man/mpv.toc
|
||||
|
||||
/waf
|
||||
/waf-*
|
||||
/waf3-*
|
||||
/build
|
||||
/.waf*
|
||||
/.lock-waf_*
|
||||
|
||||
+7
-32
@@ -2,27 +2,19 @@ language: c
|
||||
|
||||
os:
|
||||
- linux
|
||||
#- osx
|
||||
- osx
|
||||
env:
|
||||
matrix:
|
||||
- LIBAV=libav-stable
|
||||
- LIBAV=libav-git
|
||||
- LIBAV=ffmpeg-stable
|
||||
- LIBAV=ffmpeg-git
|
||||
global:
|
||||
# Coverity token
|
||||
- secure: "H21mSRlMhk4BKS0xHZvCFGJxteCP0hRVUxTuNfM2Z9HBsyutuLEYMtViLO86VtM+Tqla3xXPzUdS4ozLwI72Ax/5ZUDXACROj73yW6QhFB5D6rLut12+FjqC7M33Qv2hl0xwgNBmR5dsm1ToP37+Wn+ecJQNvN8fkTXF+HVzOEw="
|
||||
# Travis token for mpv.io
|
||||
- secure: "nlTVLJK6kRhtXvhKCoJ3YdFGHuKaq/eHowfPw25hqRWuBOZd+HjHY5KIYjV7SxuKFDpJE4GpNcvA3Q31nsqomxpkLYgrwjg6TSazN7ZP+x85ZgV1QGFebrPfGm2n5UR5CAPAwFoeF3pZheLi4bajVzwq1fWW+x3grS188P9OZso="
|
||||
- LIBAV=libav-stable
|
||||
- LIBAV=libav-git
|
||||
- LIBAV=ffmpeg-stable
|
||||
- LIBAV=ffmpeg-git
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- ci
|
||||
- coverity_scan
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
@@ -32,34 +24,17 @@ matrix:
|
||||
env: LIBAV=libav-git
|
||||
- os: osx
|
||||
env: LIBAV=ffmpeg-git
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
- os: linux
|
||||
env: LIBAV=ffmpeg-stable
|
||||
- os: linux
|
||||
compiler: clang
|
||||
|
||||
before_install: TOOLS/travis-deps libass-stable $LIBAV
|
||||
before_install: ./travis-deps libass-stable $LIBAV
|
||||
script:
|
||||
- ./bootstrap.py
|
||||
- ./waf configure
|
||||
- ./waf build
|
||||
after_script: TOOLS/travis-rebuild-website
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
irc:
|
||||
channels:
|
||||
- "irc.freenode.org#mpv-devel"
|
||||
- "irc.freenode.org#mpv-player-dev"
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "mpv-player/mpv"
|
||||
description: "Build submitted via Travis CI"
|
||||
notification_email: mpv-team@googlegroups.com
|
||||
build_command_prepend: "./bootstrap.py && ./waf configure"
|
||||
build_command: "./waf build"
|
||||
branch_pattern: coverity_scan
|
||||
@@ -2,17 +2,9 @@ mpv is a fork of mplayer2, which is a fork of MPlayer.
|
||||
|
||||
mpv as a whole is licensed as GPL version 2 or later (see LICENSE). Most source
|
||||
files are GPLv2+, but some files are available under a more liberal license,
|
||||
such as LGPLv2.1+, BSD, MIT, ISC, and possibly others. Look at the copyright
|
||||
such as LGPLv2+, BSD, MIT, ISC, and possibly others. Look at the copyright
|
||||
header of each source file, and grep the sources for "Copyright" if you need
|
||||
to know details. C source files without Copyright notice are licensed as
|
||||
LGPLv2.1+. Also see the list of files with specific licenses below (not all
|
||||
files can have a standard license header).
|
||||
|
||||
All new contributions must be LGPLv2.1+ licensed, or if the changes are done on
|
||||
GPL code, must come with the implicit agreement that the project can relicense
|
||||
the code to LGPLv2.1+ at a later point without asking the contributor. (This
|
||||
is a safeguard for making potential relicensing of the project to LGPLv2.1+
|
||||
easier.) Using a more liberal license compatible to LGPLv2.1+ is also ok.
|
||||
to know details. Files without Copyright notice are licensed as LGPLv2+.
|
||||
|
||||
For information about authors and contributors, consult the git log, which
|
||||
contains the complete SVN and CVS history as well.
|
||||
@@ -25,328 +17,3 @@ MPlayer as a whole is licensed under GPLv2 (incompatible to GPLv3!), because
|
||||
some files are licensed to GPLv2 (and _not_ any later version of the license).
|
||||
In particular, this affects the file libmpdemux/demux_ty_osd.c. It is disabled
|
||||
under mplayer2, and has been removed from mpv.
|
||||
|
||||
"v2.1+" in this context means "version 2.1 or later".
|
||||
|
||||
Some libraries are GPLv2+ or GPLv3+ only. Building mpv with Samba support makes
|
||||
it GPLv3+.
|
||||
|
||||
Source files with specific licenses:
|
||||
- etc/input.conf is LGPLv2.1+
|
||||
- etc/builtin.conf is LGPLv2.1+
|
||||
- etc/encoding-profiles.conf is LGPLv2.1+
|
||||
- all mpv icons and derived files are LGPLv2.1+ (mpv-icon-8bit-16x16.png etc.)
|
||||
- everything else under etc/ is unknown
|
||||
- everything under DOCS/man/ is GPLv2+
|
||||
- sub/osd_font.otf is LGPLv2.1+
|
||||
- version.sh is LGPLv2+
|
||||
- bootstrap.py is unknown (probably GPLv2+ or LGPLv2+)
|
||||
- the build system (wscript, waftools/*) is LGPLv2+, some parts BSD
|
||||
|
||||
Some files are marked with "Almost LGPL." These files are GPL, but all authors
|
||||
have agreed to relicense them to LGPL. the problem is that one of the authors is
|
||||
Michael Niedermayer, who cited the following conditions for relicensing:
|
||||
|
||||
http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2016-September/073535.html
|
||||
|
||||
We assume the first 3 conditions are fulfilled. The last condition can be
|
||||
interpreted as that his code can be changed to LGPL only as soon as the "core"
|
||||
of mpv changes to LGPL. We interpret "core" as something minimal, that can
|
||||
actually be built and run, with all GPL code disabled.
|
||||
|
||||
Some files are LGPLv3+. This is due to the contributions of a single developer
|
||||
going by the SVN username "iive". The chosen license of this project is
|
||||
LGPLv2.1+. The affected files will be changed to LGPLv2.1+ at the earliest
|
||||
opportunity, for example if his contributions disappear by being replaced
|
||||
or removed. All new contributions to these files are implied to be LGPLv2.1+.
|
||||
|
||||
LGPL relicensing status. Files which require some sort of action to get a basic
|
||||
LGPL player core (relicensing, replacement, or partial/full rewrites) are marked
|
||||
with an "x".
|
||||
|
||||
audio/decode/ad.h LGPL
|
||||
audio/decode/ad_lavc.c LGPL
|
||||
audio/decode/ad_spdif.c LGPL
|
||||
audio/decode/dec_audio.* LGPL
|
||||
x audio/filter/af.* must be killed (main author disagreed)
|
||||
(required for LGPL core: a new filter chain must be written)
|
||||
audio/filter/af_channel.c must be killed (main author disagreed)
|
||||
audio/filter/af_equalizer.c must be killed (main author disagreed)
|
||||
audio/filter/af_pan.c must be killed (main author disagreed)
|
||||
audio/filter/af_volume.c must be killed (main author disagreed)
|
||||
audio/filter/equalizer.h must be killed (main author disagreed)
|
||||
audio/filter/tools.c must be killed (main author disagreed)
|
||||
audio/filter/af_format.c LGPL
|
||||
audio/filter/af_lavc3enc.c LGPL
|
||||
audio/filter/af_lavfi.c LGPL
|
||||
audio/filter/af_scaletempo.c LGPL
|
||||
audio/filter/af_rubberband.c LGPL
|
||||
audio/out/ao.c LGPL
|
||||
audio/out/ao.h LGPL
|
||||
audio/out/ao_alsa.c extremely hard (original author did not decide)
|
||||
audio/out/ao_audiounit.m LGPL
|
||||
audio/out/ao_coreaudio.c LGPL
|
||||
audio/out/ao_coreaudio_chmap.c LGPL
|
||||
audio/out/ao_coreaudio_chmap.h LGPL
|
||||
audio/out/ao_coreaudio_exclusiv LGPL
|
||||
audio/out/ao_coreaudio_properti LGPL
|
||||
audio/out/ao_coreaudio_properti LGPL
|
||||
audio/out/ao_coreaudio_utils.c LGPL
|
||||
audio/out/ao_coreaudio_utils.h LGPL
|
||||
audio/out/ao_jack.c will stay GPL
|
||||
audio/out/ao_lavc.c LGPL
|
||||
audio/out/ao_null.c LGPL
|
||||
audio/out/ao_openal.c LGPL
|
||||
audio/out/ao_opensles.c LGPL
|
||||
audio/out/ao_oss.c will stay GPL
|
||||
audio/out/ao_pcm.c LGPL
|
||||
audio/out/ao_pulse.c LGPL
|
||||
audio/out/ao_rsound.c LGPL
|
||||
audio/out/ao_sdl.c LGPL
|
||||
audio/out/ao_sndio.c LGPL (BSD)
|
||||
audio/out/ao_wasapi.c LGPL
|
||||
audio/out/ao_wasapi_changenotif LGPL
|
||||
audio/out/ao_wasapi.h LGPL
|
||||
audio/out/ao_wasapi_utils.c LGPL
|
||||
audio/out/internal.h LGPL
|
||||
audio/out/pull.c LGPL
|
||||
audio/out/push.c LGPL
|
||||
x audio/audio.* very hard (mp_audio based of anders' af_audio)
|
||||
(required for LGPL core: determine if the struct can be used anyway, or
|
||||
devise a cheap AVFrame wrapper)
|
||||
audio/audio_buffer.* LGPL
|
||||
audio/chmap.* LGPL
|
||||
audio/chmap_sel.* LGPL
|
||||
audio/fmt-conversion.* LGPL
|
||||
audio/format.* LGPL
|
||||
common/av_common.* LGPL
|
||||
common/av_log.c almost LGPL
|
||||
common/av_log.h LGPL
|
||||
common/codecs.* LGPL
|
||||
common/common.* LGPL
|
||||
common/encode.h LGPL
|
||||
common/encode_lavc.* LGPL
|
||||
common/global.h LGPL
|
||||
common/msg.c almost LGPL
|
||||
common/msg_control.h LGPL
|
||||
common/msg.h LGPL
|
||||
common/playlist.* LGPL
|
||||
common/recorder.* LGPL
|
||||
common/tags.* LGPL
|
||||
common/version.c LGPL
|
||||
demux/codec_tags.* LGPL
|
||||
demux/cue.* LGPL
|
||||
demux/demux.* LGPL
|
||||
demux/demux_cue.c LGPL
|
||||
demux/demux_disc.c LGPL
|
||||
demux/demux_edl.c LGPL
|
||||
demux/demux_lavf.c almost LGPL
|
||||
demux/demux_libarchive.c LGPL
|
||||
demux/demux_mf.c LGPLv3+
|
||||
demux/demux_mkv.c LGPL (mostly)
|
||||
demux/demux_mkv_timeline.c LGPL
|
||||
demux/demux_null.c LGPL
|
||||
demux/demux_playlist.c LGPL
|
||||
demux/demux_rar.c LGPL
|
||||
demux/demux_raw.c almost LGPL
|
||||
demux/demux_timeline.c LGPL
|
||||
demux/demux_tv.c will stay GPL
|
||||
demux/ebml.* LGPL
|
||||
demux/matroska.h LGPL
|
||||
demux/packet.* LGPL
|
||||
demux/stheader.h LGPL
|
||||
demux/timeline.* LGPL
|
||||
input/cmd_* LGPL
|
||||
input/event.* LGPL
|
||||
input/input.* LGPL
|
||||
input/ipc.c LGPL
|
||||
input/ipc-unix.c LGPL
|
||||
input/ipc-win.c LGPL
|
||||
input/keycodes.* LGPL
|
||||
input/pipe-win32.c LGPL
|
||||
libmpv/*.* LGPL
|
||||
misc/*.* LGPL
|
||||
options/m_config.* LGPL
|
||||
options/m_option.c almost LGPL
|
||||
options/m_option.h LGPL
|
||||
options/m_property.* LGPL
|
||||
options/options.* LGPL
|
||||
options/parse_commandline.* LGPL
|
||||
options/parse_configfile.* LGPL
|
||||
options/path.* LGPL
|
||||
osdep/android/* LGPL (BSD)
|
||||
osdep/ar/* LGPL (BSD)
|
||||
osdep/atomic.h LGPL
|
||||
osdep/compiler.h LGPL
|
||||
osdep/endian.h LGPL
|
||||
osdep/glob-win.c LGPL
|
||||
osdep/io.* LGPL
|
||||
osdep/macosx_application.h LGPL
|
||||
osdep/macosx_application.m LGPL
|
||||
osdep/macosx_application_objc.h LGPL
|
||||
osdep/macosx_compat.h LGPL
|
||||
osdep/macosx_events.* LGPL
|
||||
osdep/macosx_events_objc.h LGPL
|
||||
osdep/macosx_touchbar.* LGPL
|
||||
osdep/macosx_versions.h LGPL
|
||||
osdep/main-fn-cocoa.c LGPL
|
||||
osdep/main-fn.h LGPL
|
||||
osdep/main-fn-unix.c LGPL
|
||||
osdep/main-fn-win.c LGPL
|
||||
osdep/mpv.exe.manifest LGPL
|
||||
osdep/mpv.rc LGPL
|
||||
osdep/path.h LGPL
|
||||
osdep/path-macosx.m LGPL
|
||||
osdep/path-unix.c LGPL
|
||||
osdep/path-win.c LGPL
|
||||
osdep/semaphore.h LGPL
|
||||
osdep/semaphore_osx.c LGPL
|
||||
osdep/strnlen.h LGPL
|
||||
osdep/subprocess.* LGPL
|
||||
osdep/subprocess-posix.c LGPL
|
||||
osdep/subprocess-win.c LGPL
|
||||
osdep/terminal.h LGPL
|
||||
osdep/terminal-unix.c LGPL
|
||||
osdep/terminal-win.c LGPL
|
||||
osdep/threads.* LGPL
|
||||
osdep/timer.c LGPL
|
||||
osdep/timer.h LGPL
|
||||
osdep/timer-darwin.c LGPL (MIT)
|
||||
osdep/timer-linux.c LGPL
|
||||
osdep/timer-win2.c LGPL
|
||||
osdep/w32_keyboard.c LGPL
|
||||
osdep/w32_keyboard.h LGPL
|
||||
osdep/win32-console-wrapper.c LGPL (BSD)
|
||||
osdep/win32/* LGPL (ISC)
|
||||
osdep/windows_utils.* LGPL
|
||||
x player/audio.c LGPL (dysfunctional due to libaf)
|
||||
player/client.* LGPL (ISC)
|
||||
player/command.c LGPL
|
||||
player/command.h LGPL
|
||||
player/configfiles.c LGPL
|
||||
player/core.h LGPL
|
||||
player/external_files.* LGPL
|
||||
player/lavfi.* LGPL
|
||||
player/loadfile.c LGPL
|
||||
player/lua/*.* LGPL
|
||||
player/lua.c LGPL
|
||||
player/misc.c LGPL
|
||||
player/osd.c LGPL
|
||||
player/playloop.c LGPL
|
||||
player/screenshot.* LGPL
|
||||
player/scripting.* LGPL
|
||||
player/sub.c LGPL
|
||||
player/video.c LGPL
|
||||
stream/ai_* will stay GPL (TV code)
|
||||
stream/audio_in.* will stay GPL (TV code)
|
||||
stream/cache.c LGPLv3+
|
||||
stream/cache_file.c LGPL
|
||||
stream/cookies.* LGPL
|
||||
stream/dvb* must stay GPL
|
||||
stream/frequencies.* must stay GPL
|
||||
stream/rar.* LGPL
|
||||
stream/stream_avdevice.c LGPL
|
||||
stream/stream_bluray.c LGPL
|
||||
stream/stream.* LGPL
|
||||
stream/stream_cb.c LGPL
|
||||
stream/stream_cdda.c unknown
|
||||
stream/stream_dvb.* must stay GPL
|
||||
stream/stream_dvd.c unknown
|
||||
stream/stream_dvd_common.* unknown
|
||||
stream/stream_dvdnav.c unknown
|
||||
stream/stream_edl.c LGPL
|
||||
stream/stream_file.c LGPL
|
||||
stream/stream_lavf.c LGPL
|
||||
stream/stream_libarchive.* LGPL
|
||||
stream/stream_memory.c LGPL
|
||||
stream/stream_mf.c LGPL
|
||||
stream/stream_null.c LGPL
|
||||
stream/stream_rar.c LGPL
|
||||
stream/stream_smb.c will stay GPLv3
|
||||
stream/stream_tv.c will stay GPL
|
||||
stream/tv* will stay GPL
|
||||
sub/* LGPL
|
||||
ta/* LGPL (ISC)
|
||||
video/decode/d3d.* LGPL
|
||||
video/decode/dec_video.* almost LGPL
|
||||
video/decode/hw_cuda.c LGPL
|
||||
video/decode/hw_d3d11va.c LGPL
|
||||
video/decode/hw_dxva2.c LGPL
|
||||
video/decode/hw_videotoolbox.c LGPL
|
||||
video/decode/lavc.h almost LGPLv3+
|
||||
video/decode/vd.h LGPL
|
||||
video/decode/vd_lavc.c almost LGPLv3+
|
||||
video/filter/refqueue.* LGPL
|
||||
video/filter/vf.c LGPL
|
||||
video/filter/vf.h LGPL (mostly)
|
||||
video/filter/vf_buffer.c LGPL
|
||||
video/filter/vf_crop.c will be deleted
|
||||
video/filter/vf_d3d11vpp.c LGPL
|
||||
video/filter/vf_dsize.c will be deleted
|
||||
video/filter/vf_eq.c will be deleted
|
||||
video/filter/vf_expand.c will be deleted
|
||||
video/filter/vf_flip.c will be deleted
|
||||
video/filter/vf_format.c will be deleted
|
||||
video/filter/vf_gradfun.c will be deleted
|
||||
video/filter/vf_lavfi.* LGPL
|
||||
video/filter/vf_mirror.c will be deleted
|
||||
video/filter/vf_noformat.c will be deleted
|
||||
video/filter/vf_pullup.c will be deleted
|
||||
video/filter/vf_rotate.c will be deleted
|
||||
video/filter/vf_scale.c will be deleted
|
||||
video/filter/vf_stereo3d.c will be deleted
|
||||
video/filter/vf_sub.c will be deleted
|
||||
video/filter/vf_vapoursynth.c LGPL
|
||||
video/filter/vf_vavpp.c LGPL
|
||||
video/filter/vf_vdpaupp.c LGPL
|
||||
video/filter/vf_yadif.c will be deleted
|
||||
video/csputils.* LGPL
|
||||
video/fmt-conversion.* LGPL
|
||||
video/gpu_memcpy.* will be deleted
|
||||
video/hwdec.* LGPL
|
||||
video/image_writer.* LGPL
|
||||
video/img_format.* LGPL
|
||||
video/mp_image.* almost LGPL
|
||||
video/mp_image_pool.* LGPL
|
||||
video/out/aspect.* LGPL
|
||||
video/out/bitmap_packer.* LGPL
|
||||
video/out/cocoa* LGPL
|
||||
video/out/d3d_shader_420p.h LGPL
|
||||
video/out/d3d_shader_nv12.h LGPL
|
||||
video/out/d3d_shader_yuv.hlsl LGPL
|
||||
video/out/dither.* LGPL
|
||||
video/out/drm_common.* LGPL
|
||||
video/out/filter_kernels.* LGPL (BSD)
|
||||
video/out/opengl/hwdec_vaglx.c GPL
|
||||
video/out/opengl/* LGPL
|
||||
video/out/vo.c LGPL
|
||||
video/out/vo.h LGPL
|
||||
video/out/vo_caca.c unknown
|
||||
video/out/vo_direct3d.c unknown
|
||||
video/out/vo_drm.c LGPL
|
||||
video/out/vo_image.c LGPL
|
||||
video/out/vo_lavc.c LGPL
|
||||
video/out/vo_null.c LGPL
|
||||
video/out/vo_opengl.c LGPL
|
||||
video/out/vo_opengl_cb.c LGPL
|
||||
video/out/vo_rpi.c LGPL
|
||||
video/out/vo_sdl.c LGPL
|
||||
video/out/vo_tct.c LGPL
|
||||
video/out/vo_vaapi.c probably impossible (some company's code)
|
||||
video/out/vo_vdpau.c probably impossible (nVidia's code)
|
||||
video/out/vo_wayland.c LGPL
|
||||
video/out/vo_x11.c probably impossible
|
||||
video/out/vo_xv.c probably impossible
|
||||
video/out/w32_common.* LGPL
|
||||
video/out/wayland* LGPL
|
||||
video/out/win32/* LGPL
|
||||
video/out/win_state.* LGPL
|
||||
video/out/x11_common.* probably impossible
|
||||
video/out/x11_icon.bin LGPL
|
||||
video/sws_utils.* almost LGPL
|
||||
video/vaapi.* hard (GPL-only parts must be ifdefed)
|
||||
video/vdpau.c hard (GPL-only parts must be ifdefed)
|
||||
video/vdpau_functions.inc LGPL
|
||||
video/vdpau.h unknown
|
||||
video/vdpau_mixer.* actual code must be rewritten
|
||||
video/vt.* LGPL
|
||||
+6
-130
@@ -4,7 +4,9 @@ Introduction
|
||||
This file lists all changes that can cause compatibility issues when using
|
||||
mpv through the client API (libmpv and ``client.h``). Since the client API
|
||||
interfaces to input handling (commands, properties) as well as command line
|
||||
options, you should also look at ``interface-changes.rst``.
|
||||
options, this list is interesting for other uses of mpv, such as the Lua
|
||||
scripting interface, key bindings in ``input.rst``, or plain command line
|
||||
usage.
|
||||
|
||||
Normally, changes to the C API that are incompatible to previous iterations
|
||||
receive a major version bump (i.e. the first version number is increased),
|
||||
@@ -18,140 +20,14 @@ The version number is the same as used for MPV_CLIENT_API_VERSION (see
|
||||
|
||||
Also, read the section ``Compatibility`` in ``client.h``.
|
||||
|
||||
Options, commands, properties
|
||||
=============================
|
||||
|
||||
Changes to these are not listed here, but in ``interface-changes.rst``. (Before
|
||||
client API version 1.17, they were listed here partially.)
|
||||
|
||||
This listing includes changes to the bare C API and behavior only, not what
|
||||
you can access with them.
|
||||
|
||||
API changes
|
||||
===========
|
||||
|
||||
::
|
||||
|
||||
--- mpv 0.26.0 ---
|
||||
1.25 - remove setting "no-" options via mpv_set_option*(). (See corresponding
|
||||
deprecation in 0.23.0.)
|
||||
--- mpv 0.25.0 ---
|
||||
1.24 - add a MPV_ENABLE_DEPRECATED preprocessor symbol, which can be defined
|
||||
by the user to exclude deprecated API symbols from the C headers
|
||||
--- mpv 0.23.0 ---
|
||||
1.24 - the deprecated mpv_suspend() and mpv_resume() APIs now do nothing.
|
||||
--- mpv 0.22.0 ---
|
||||
1.23 - deprecate setting "no-" options via mpv_set_option*(). For example,
|
||||
instead of "no-video=" you should set "video=no".
|
||||
- do not override the SIGPIPE signal handler anymore. This was done as
|
||||
workaround for the FFmpeg TLS code, which has been fixed long ago.
|
||||
- deprecate mpv_suspend() and mpv_resume(). They will be stubbed out
|
||||
in mpv 0.23.0.
|
||||
- make mpv_set_property() work to some degree before mpv_initialize().
|
||||
It can now be used instead of mpv_set_option().
|
||||
- semi-deprecate mpv_set_option()/mpv_set_option_string(). You should
|
||||
use mpv_set_property() instead. There are some deprecated properties
|
||||
which conflict with some options (see client.h remarks on
|
||||
mpv_set_option()), for which mpv_set_option() might still be required.
|
||||
In future mpv releases, the conflicting deprecated options/properties
|
||||
will be removed, and mpv_set_option() will internally translate API
|
||||
calls to mpv_set_property().
|
||||
- qthelper.hpp: deprecate get_property_variant, set_property_variant,
|
||||
set_option_variant, command_variant, and replace them with
|
||||
get_property, set_property, command.
|
||||
--- mpv 0.19.0 ---
|
||||
1.22 - add stream_cb API for custom protocols
|
||||
--- mpv 0.18.1 ---
|
||||
---- - remove "status" log level from mpv_request_log_messages() docs. This
|
||||
is 100% equivalent to "v". The behavior is still the same, thus no
|
||||
actual API change.
|
||||
--- mpv 0.18.0 ---
|
||||
1.21 - mpv_set_property() changes behavior with MPV_FORMAT_NODE. Before this
|
||||
change it rejected mpv_nodes with format==MPV_FORMAT_STRING if the
|
||||
property was not a string or did not have special mechanisms in place
|
||||
the function failed. Now it always invokes the option string parser,
|
||||
and mpv_node with a basic data type works exactly as if the function
|
||||
is invoked with that type directly. This new behavior is equivalent
|
||||
to mpv_set_option().
|
||||
This also affects the mp.set_property_native() Lua function.
|
||||
- generally, setting choice options/properties with "yes"/"no" options
|
||||
can now be set as MPV_FORMAT_FLAG
|
||||
- reading a choice property as MPV_FORMAT_NODE will now return a
|
||||
MPV_FORMAT_FLAG value if the choice is "yes" (true) or "no" (false)
|
||||
This implicitly affects Lua and JSON IPC interfaces as well.
|
||||
- big changes to vo-cmdline on vo_opengl and vo_opengl_hq (but not
|
||||
vo_opengl_cb): options are now normally not reset, but applied on top
|
||||
of the current options. The special undocumented value "-" still
|
||||
works, but now resets all options to before any vo-cmdline command
|
||||
has been called.
|
||||
--- mpv 0.12.0 ---
|
||||
1.20 - deprecate "GL_MP_D3D_interfaces"/"glMPGetD3DInterface", and introduce
|
||||
"GL_MP_MPGetNativeDisplay"/"glMPGetNativeDisplay" (this is a
|
||||
backwards-compatible rename)
|
||||
--- mpv 0.11.0 ---
|
||||
--- mpv 0.10.0 ---
|
||||
1.19 - add "GL_MP_D3D_interfaces" pseudo extension to make it possible to
|
||||
use DXVA2 in OpenGL fullscreen mode in some situations
|
||||
- mpv_request_log_messages() now accepts "terminal-default" as parameter
|
||||
1.18 - add MPV_END_FILE_REASON_REDIRECT, and change behavior of
|
||||
MPV_EVENT_END_FILE accordingly
|
||||
- a bunch of interface-changes.rst changes
|
||||
1.17 - mpv_initialize() now blocks SIGPIPE (details see client.h)
|
||||
--- mpv 0.9.0 ---
|
||||
1.16 - add mpv_opengl_cb_report_flip()
|
||||
- introduce mpv_opengl_cb_draw() and deprecate mpv_opengl_cb_render()
|
||||
- add MPV_FORMAT_BYTE_ARRAY
|
||||
1.15 - mpv_initialize() will now load config files. This requires setting
|
||||
the "config" and "config-dir" options. In particular, it will load
|
||||
mpv.conf.
|
||||
- minor backwards-compatible change to the "seek" and "screenshot"
|
||||
commands (new flag syntax, old additional args deprecated)
|
||||
--- mpv 0.8.0 ---
|
||||
1.14 - add mpv_wait_async_requests()
|
||||
- the --msg-level option changes its native type from a flat string to
|
||||
a key-value list (setting/reading the option as string still works)
|
||||
1.13 - add MPV_EVENT_QUEUE_OVERFLOW
|
||||
1.12 - add class Handle to qthelper.hpp
|
||||
- improve opengl_cb.h API uninitialization behavior, and fix the qml
|
||||
example
|
||||
- add mpv_create_client() function
|
||||
1.11 - add OpenGL rendering interop API - allows an application to combine
|
||||
its own and mpv's OpenGL rendering
|
||||
Warning: this API is not stable yet - anything in opengl_cb.h might
|
||||
be changed in completely incompatible ways in minor API bumps
|
||||
--- mpv 0.7.0 ---
|
||||
1.10 - deprecate/disable everything directly related to script_dispatch
|
||||
(most likely affects nobody)
|
||||
1.9 - add enum mpv_end_file_reason for mpv_event_end_file.reason
|
||||
- add MPV_END_FILE_REASON_ERROR and the mpv_event_end_file.error field
|
||||
for slightly better error reporting on playback failure
|
||||
- add --stop-playback-on-init-failure option, and make it the default
|
||||
behavior for libmpv only
|
||||
- add qthelper.hpp set_option_variant()
|
||||
- mark the following events as deprecated:
|
||||
MPV_EVENT_TRACKS_CHANGED
|
||||
MPV_EVENT_TRACK_SWITCHED
|
||||
MPV_EVENT_PAUSE
|
||||
MPV_EVENT_UNPAUSE
|
||||
MPV_EVENT_METADATA_UPDATE
|
||||
MPV_EVENT_CHAPTER_CHANGE
|
||||
They are handled better with mpv_observe_property() as mentioned in
|
||||
the documentation comments. They are not removed and still work.
|
||||
1.8 - add qthelper.hpp
|
||||
1.7 - add mpv_command_node(), mpv_command_node_async()
|
||||
1.6 - modify "core-idle" property behavior
|
||||
- MPV_EVENT_LOG_MESSAGE now always sends complete lines
|
||||
- introduce numeric log levels (mpv_log_level)
|
||||
--- mpv 0.6.0 ---
|
||||
1.5 - change in X11 and "--wid" behavior again. The previous change didn't
|
||||
work as expected, and now the behavior can be explicitly controlled
|
||||
with the "input-x11-keyboard" option. This is only a temporary
|
||||
measure until XEmbed is implemented and confirmed working.
|
||||
Note: in 1.6, "input-x11-keyboard" was renamed to "input-vo-keyboard",
|
||||
although the old option name still works.
|
||||
--- mpv 0.5.2 is released ---
|
||||
1.4 - subtle change in X11 and "--wid" behavior
|
||||
(this change was added to 0.5.2, and broke some things, see #1090)
|
||||
--- mpv 0.5.0 ---
|
||||
--- mpv 0.5.0 is released ---
|
||||
1.3 - add MPV_MAKE_VERSION()
|
||||
1.2 - remove "stream-time-pos" property (no replacement)
|
||||
1.1 - remap dvdnav:// to dvd://
|
||||
@@ -163,6 +39,6 @@ API changes
|
||||
insignificant is now significant
|
||||
- add "cache-free" and "cache-used" properties
|
||||
- OSX: the "coreaudio" AO spdif code is split into a separate AO
|
||||
--- mpv 0.4.0 ---
|
||||
--- mpv 0.4.0 is released ---
|
||||
1.0 - the API is declared stable
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
// License: pick one of: public domain, WTFPL, ISC, Ms-PL, AGPLv3
|
||||
|
||||
// This example can be built with: qmake && make
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QStatusBar>
|
||||
#include <QMenuBar>
|
||||
#include <QMenu>
|
||||
#include <QGridLayout>
|
||||
#include <QApplication>
|
||||
|
||||
#include "qtexample.h"
|
||||
|
||||
static void wakeup(void *ctx)
|
||||
{
|
||||
// This callback is invoked from any mpv thread (but possibly also
|
||||
// recursively from a thread that is calling the mpv API). Just notify
|
||||
// the Qt GUI thread to wake up (so that it can process events with
|
||||
// mpv_wait_event()), and return as quickly as possible.
|
||||
MainWindow *mainwindow = (MainWindow *)ctx;
|
||||
QCoreApplication::postEvent(mainwindow, new QEvent(QEvent::User));
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent)
|
||||
{
|
||||
QMenu *menu = menuBar()->addMenu(tr("&File"));
|
||||
QAction *on_open = new QAction(tr("&Open"), this);
|
||||
on_open->setShortcuts(QKeySequence::Open);
|
||||
on_open->setStatusTip(tr("Open a file"));
|
||||
connect(on_open, SIGNAL(triggered()), this, SLOT(on_file_open()));
|
||||
menu->addAction(on_open);
|
||||
|
||||
statusBar();
|
||||
|
||||
mpv = mpv_create();
|
||||
if (!mpv)
|
||||
throw "can't create mpv instance";
|
||||
|
||||
// Create a video child window. Force Qt to create a native window, and
|
||||
// pass the window ID to the mpv wid option. This doesn't work on OSX,
|
||||
// because Cocoa doesn't support this form of embedding.
|
||||
mpv_container = new QWidget(this);
|
||||
setCentralWidget(mpv_container);
|
||||
mpv_container->setAttribute(Qt::WA_NativeWindow);
|
||||
int64_t wid = mpv_container->winId();
|
||||
mpv_set_option(mpv, "wid", MPV_FORMAT_INT64, &wid);
|
||||
|
||||
// Enable default bindings, because we're lazy. Normally, a player using
|
||||
// mpv as backend would implement its own key bindings.
|
||||
mpv_set_option_string(mpv, "input-default-bindings", "yes");
|
||||
|
||||
// Let us receive property change events with MPV_EVENT_PROPERTY_CHANGE if
|
||||
// this property changes.
|
||||
mpv_observe_property(mpv, 0, "time-pos", MPV_FORMAT_DOUBLE);
|
||||
|
||||
// From this point on, the wakeup function will be called. The callback
|
||||
// can come from any thread, so we use the Qt QEvent mechanism to relay
|
||||
// the wakeup in a thread-safe way.
|
||||
mpv_set_wakeup_callback(mpv, wakeup, this);
|
||||
|
||||
if (mpv_initialize(mpv) < 0)
|
||||
throw "mpv failed to initialize";
|
||||
}
|
||||
|
||||
void MainWindow::handle_mpv_event(mpv_event *event)
|
||||
{
|
||||
switch (event->event_id) {
|
||||
case MPV_EVENT_PROPERTY_CHANGE: {
|
||||
mpv_event_property *prop = (mpv_event_property *)event->data;
|
||||
if (strcmp(prop->name, "time-pos") == 0) {
|
||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
||||
double time = *(double *)prop->data;
|
||||
std::stringstream ss;
|
||||
ss << "At: " << time;
|
||||
statusBar()->showMessage(QString::fromStdString(ss.str()));
|
||||
} else if (prop->format == MPV_FORMAT_NONE) {
|
||||
// The property is unavailable, which probably means playback
|
||||
// was stopped.
|
||||
statusBar()->showMessage("");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPV_EVENT_SHUTDOWN: {
|
||||
mpv_terminate_destroy(mpv);
|
||||
mpv = NULL;
|
||||
break;
|
||||
}
|
||||
default: ;
|
||||
// Ignore uninteresting or unknown events.
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::event(QEvent *event)
|
||||
{
|
||||
// QEvent::User is sent by wakeup().
|
||||
if (event->type() == QEvent::User) {
|
||||
// Process all events, until the event queue is empty.
|
||||
while (mpv) {
|
||||
mpv_event *event = mpv_wait_event(mpv, 0);
|
||||
if (event->event_id == MPV_EVENT_NONE)
|
||||
break;
|
||||
handle_mpv_event(event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return QMainWindow::event(event);
|
||||
}
|
||||
|
||||
void MainWindow::on_file_open()
|
||||
{
|
||||
QString filename = QFileDialog::getOpenFileName(this, "Open file");
|
||||
if (mpv) {
|
||||
const QByteArray c_filename = filename.toUtf8();
|
||||
const char *args[] = {"loadfile", c_filename.data(), NULL};
|
||||
mpv_command_async(mpv, 0, args);
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
if (mpv)
|
||||
mpv_terminate_destroy(mpv);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef QTEXAMPLE_H
|
||||
#define QTEXAMPLE_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#include <mpv/client.h>
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
protected:
|
||||
virtual bool event(QEvent *event);
|
||||
|
||||
private slots:
|
||||
void on_file_open();
|
||||
|
||||
private:
|
||||
QWidget *mpv_container;
|
||||
mpv_handle *mpv;
|
||||
|
||||
void create_player();
|
||||
void handle_mpv_event(mpv_event *event);
|
||||
};
|
||||
|
||||
#endif // QTEXAMPLE_H
|
||||
@@ -0,0 +1,12 @@
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = qtexample
|
||||
TEMPLATE = app
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG = mpv
|
||||
|
||||
SOURCES += qtexample.cpp
|
||||
HEADERS += qtexample.h
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline void check_error(int status)
|
||||
{
|
||||
if (status < 0) {
|
||||
printf("mpv API error: %s\n", mpv_error_string(status));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libmpv/client.h"
|
||||
#include "shared.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
printf("pass a single media file as argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
mpv_handle *ctx = mpv_create();
|
||||
if (!ctx) {
|
||||
printf("failed creating context\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Enable default key bindings, so the user can actually interact with
|
||||
// the player (and e.g. close the window).
|
||||
check_error(mpv_set_option_string(ctx, "input-default-bindings", "yes"));
|
||||
int val = 1;
|
||||
check_error(mpv_set_option(ctx, "osc", MPV_FORMAT_FLAG, &val));
|
||||
|
||||
// Done setting up options.
|
||||
check_error(mpv_initialize(ctx));
|
||||
|
||||
// Play this file.
|
||||
const char *cmd[] = {"loadfile", argv[1], NULL};
|
||||
check_error(mpv_command(ctx, cmd));
|
||||
|
||||
// Let it play, and wait until the user quits.
|
||||
while (1) {
|
||||
mpv_event *event = mpv_wait_event(ctx, 10000);
|
||||
printf("event: %s\n", mpv_event_name(event->event_id));
|
||||
if (event->event_id == MPV_EVENT_SHUTDOWN)
|
||||
break;
|
||||
}
|
||||
|
||||
mpv_terminate_destroy(ctx);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
Compiling for Windows
|
||||
=====================
|
||||
|
||||
Compiling for Windows is supported with MinGW-w64. This can be used to produce
|
||||
both 32-bit and 64-bit executables, and it works for building on Windows and
|
||||
cross-compiling from Linux and Cygwin. MinGW-w64 is available from:
|
||||
http://mingw-w64.sourceforge.net.
|
||||
|
||||
While building a complete MinGW-w64 toolchain yourself is possible, there are a
|
||||
few build environments and scripts to help ease the process, such as MSYS2 and
|
||||
MXE. Note that MinGW environments included in Linux distributions are often
|
||||
broken, outdated and useless, and usually don't use MinGW-w64.
|
||||
|
||||
**Warning**: the original MinGW (http://www.mingw.org) is unsupported.
|
||||
|
||||
Cross-compilation
|
||||
=================
|
||||
|
||||
When cross-compiling, you have to run mpv's configure with these arguments:
|
||||
|
||||
```bash
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
|
||||
```
|
||||
|
||||
[MXE](http://mxe.cc) makes it very easy to bootstrap a complete MingGW-w64
|
||||
environment from a Linux machine. See a working example below.
|
||||
|
||||
Alternatively, you can try [mingw-w64-cmake](https://github.com/lachs0r/mingw-w64-cmake),
|
||||
which bootstraps a MinGW-w64 environment and builds mpv and dependencies.
|
||||
|
||||
Example with MXE
|
||||
----------------
|
||||
|
||||
```bash
|
||||
# Before starting, make sure you install MXE prerequisites. MXE will download
|
||||
# and build all target dependencies, but no host dependencies. For example,
|
||||
# you need a working compiler, or MXE can't build the crosscompiler.
|
||||
#
|
||||
# Refer to
|
||||
#
|
||||
# http://mxe.cc/#requirements
|
||||
#
|
||||
# Scroll down for disto/OS-specific instructions to install them.
|
||||
|
||||
# Download MXE. Note that compiling the required packages requires about 1.4 GB
|
||||
# or more!
|
||||
|
||||
cd /opt
|
||||
git clone https://github.com/mxe/mxe mxe
|
||||
cd mxe
|
||||
|
||||
# Set build options.
|
||||
|
||||
# The JOBS environment variable controls threads to use when building. DO NOT
|
||||
# use the regular `make -j4` option with MXE as it will slow down the build.
|
||||
# Alternatively, you can set this in the make command by appending "JOBS=4"
|
||||
# to the end of command:
|
||||
echo "JOBS := 4" >> settings.mk
|
||||
|
||||
# The MXE_TARGET environment variable builds MinGW-w64 for 32 bit targets.
|
||||
# Alternatively, you can specify this in the make command by appending
|
||||
# "MXE_TARGETS=i686-w64-mingw32" to the end of command:
|
||||
echo "MXE_TARGETS := i686-w64-mingw32.static" >> settings.mk
|
||||
|
||||
# If you want to build 64 bit version, use this:
|
||||
# echo "MXE_TARGETS := x86_64-w64-mingw32.static" >> settings.mk
|
||||
|
||||
# Build required packages. The following provide a minimum required to build
|
||||
# a reasonable mpv binary (though not an absolute minimum).
|
||||
|
||||
make gcc ffmpeg libass jpeg lua
|
||||
|
||||
# Add MXE binaries to $PATH
|
||||
export PATH=/opt/mxe/usr/bin/:$PATH
|
||||
|
||||
# Build mpv. The target will be used to automatically select the name of the
|
||||
# build tools involved (e.g. it will use i686-w64-mingw32.static-gcc).
|
||||
|
||||
cd ..
|
||||
git clone https://github.com/mpv-player/mpv.git
|
||||
cd mpv
|
||||
python ./bootstrap.py
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32.static ./waf configure
|
||||
# Or, if 64 bit version,
|
||||
# DEST_OS=win32 TARGET=x86_64-w64-mingw32.static ./waf configure
|
||||
./waf build
|
||||
```
|
||||
|
||||
Native compilation with MSYS2
|
||||
=============================
|
||||
|
||||
For Windows developers looking to get started quickly, MSYS2 can be used to
|
||||
compile mpv natively on a Windows machine. The MSYS2 repositories have binary
|
||||
packages for most of mpv's dependencies, so the process should only involve
|
||||
building mpv itself.
|
||||
|
||||
To build 64-bit mpv on Windows:
|
||||
|
||||
Installing MSYS2
|
||||
----------------
|
||||
|
||||
1. Download an installer from https://msys2.github.io/
|
||||
|
||||
It doesn't matter whether the i686 or the x86_64 version is used. Both can
|
||||
build 32-bit and 64-bit binaries when running on a 64-bit version of Windows.
|
||||
|
||||
2. Start a MinGW-w64 shell (``mingw64.exe``). Note that this is different
|
||||
from the MSYS2 shell that is started from the final installation dialog.
|
||||
|
||||
For a 32-bit build, use ``mingw32.exe``.
|
||||
|
||||
Updating MSYS2
|
||||
--------------
|
||||
|
||||
To prevent errors during post-install, the MSYS2 core runtime must be updated
|
||||
separately.
|
||||
|
||||
```bash
|
||||
# Check for core updates. If instructed, close the shell window and reopen it
|
||||
# before continuing.
|
||||
pacman -Syu
|
||||
|
||||
# Update everything else
|
||||
pacman -Su
|
||||
```
|
||||
|
||||
Installing mpv dependencies
|
||||
---------------------------
|
||||
|
||||
```bash
|
||||
# Install MSYS2 build dependencies and a MinGW-w64 compiler
|
||||
pacman -S git mingw-w64-x86_64-pkg-config python mingw-w64-x86_64-gcc
|
||||
|
||||
# Install the most important MinGW-w64 dependencies. libass, libbluray and
|
||||
# lcms2 are also pulled in as dependencies of ffmpeg.
|
||||
pacman -S mingw-w64-x86_64-ffmpeg mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-lua51
|
||||
|
||||
# Install additional (optional) dependencies
|
||||
pacman -S mingw-w64-x86_64-libdvdnav mingw-w64-x86_64-libguess mingw-w64-x86_64-angleproject-git
|
||||
```
|
||||
|
||||
For a 32-bit build, install ``mingw-w64-i686-*`` packages instead.
|
||||
|
||||
Building mpv
|
||||
------------
|
||||
|
||||
Clone the latest mpv from git and install waf:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/mpv-player/mpv.git && cd mpv
|
||||
./bootstrap.py
|
||||
```
|
||||
|
||||
Finally, compile and install mpv. Binaries will be installed to
|
||||
``/mingw64/bin``.
|
||||
|
||||
```bash
|
||||
# For a 32-bit build, use --prefix=/mingw32 instead
|
||||
./waf configure CC=gcc.exe --check-c-compiler=gcc --prefix=/mingw64
|
||||
./waf install
|
||||
```
|
||||
|
||||
Or, compile and install both libmpv and mpv:
|
||||
|
||||
```bash
|
||||
./waf configure CC=gcc.exe --check-c-compiler=gcc --enable-libmpv-shared --prefix=/mingw64
|
||||
./waf install
|
||||
```
|
||||
|
||||
Linking libmpv with MSVC programs
|
||||
---------------------------------
|
||||
|
||||
You can build C++ programs in Visual Studio and link them with libmpv. To do
|
||||
this, you need a Visual Studio which supports ``stdint.h`` (recent ones do),
|
||||
and you need to create a import library for the mpv DLL:
|
||||
|
||||
```bash
|
||||
lib /def:mpv.def /name:mpv-1.dll /out:mpv.lib /MACHINE:X64
|
||||
```
|
||||
|
||||
The string in the ``/name:`` parameter must match the filename of the DLL (this
|
||||
is simply the filename the MSVC linker will use). The ``mpv.def`` can be
|
||||
retrieved from the mpv build directory, or can be produced by MingGW's
|
||||
gendef.exe helper from the mpv DLL.
|
||||
|
||||
Static linking is not possible.
|
||||
|
||||
Running mpv
|
||||
-----------
|
||||
|
||||
If you want to run mpv from the MinGW-w64 shell, you will find the experience
|
||||
much more pleasant if you use the ``winpty`` utility
|
||||
|
||||
```bash
|
||||
pacman -S winpty
|
||||
winpty mpv.com ToS-4k-1920.mov
|
||||
```
|
||||
|
||||
If you want to move / copy ``mpv.exe`` and ``mpv.com`` to somewhere other than
|
||||
``/mingw64/bin/`` for use outside the MinGW-w64 shell, they will still depend on
|
||||
DLLs in that folder. The simplest solution is to add ``C:\msys64\mingw64\bin``
|
||||
to the windows system ``%PATH%``. Beware though that this can cause problems or
|
||||
confusion in Cygwin if that is also installed on the machine.
|
||||
|
||||
Use of the ANGLE OpenGL backend requires a copy of the D3D compiler DLL that
|
||||
matches the version of the D3D SDK that ANGLE was built with
|
||||
(``d3dcompiler_43.dll`` in case of MinGW-built ANGLE) in the path or in the
|
||||
same folder as mpv. It must be of the same architecture (x86_64 / i686) as the
|
||||
mpv you compiled. You can find copies here:
|
||||
|
||||
https://mpv.srsfckn.biz/d3dcompiler.7z
|
||||
+20
-63
@@ -4,8 +4,8 @@ How to contribute
|
||||
General
|
||||
-------
|
||||
|
||||
The main contact for mpv development is IRC, specifically #mpv
|
||||
and #mpv-devel on Freenode.
|
||||
The main contact for mpv development is IRC, specifically #mpv-player and
|
||||
#mpv-player-dev on Freenode.
|
||||
|
||||
Sending patches
|
||||
---------------
|
||||
@@ -14,32 +14,18 @@ Sending patches
|
||||
``git format-patch``. diffs posted as pastebins (especially if the http link
|
||||
returns HTML) just cause extra work for everyone, because they lack commit
|
||||
message and authorship information.
|
||||
- All new code must be LGPLv2.1+ licensed, or come with the implicit agreement
|
||||
that it will be relicensed to LGPLv2.1+ later (see ``Copyright`` in the
|
||||
repository root directory).
|
||||
- You must be either the exclusive author of the patch, or acknowledge all
|
||||
authors involved in the commit message. If you take 3rd party code, authorship
|
||||
and copyright must be properly acknowledged. If the license of the code is not
|
||||
LGPLv2.1+, this must be mentioned.
|
||||
- Don't use fake names (something that looks like an actual names, and may be
|
||||
someone else's name, but is not your legal name). Using a pseudonyms is
|
||||
allowed if it can be used to identify or contact you, even if whatever
|
||||
account you used to submit the patch dies.
|
||||
- When creating pull requests, be sure to test your changes. If you didn't,
|
||||
please say so in the pull request message.
|
||||
- Write informative commit messages. Use present tense to describe the
|
||||
situation with the patch applied, and past tense for the situation before
|
||||
the change.
|
||||
- The subject line (the first line in a commit message) should contain a
|
||||
prefix identifying the sub system, followed by a short description what
|
||||
impact this commit has. This subject line and the commit message body
|
||||
shouldn't be longer than 72 characters per line, because it messes up the
|
||||
output of many git tools otherwise.
|
||||
impact this commit has. This subject line shouldn't be longer than 72
|
||||
characters, because it messes up the output of many git tools otherwise.
|
||||
|
||||
For example, you fixed a crash in af_volume.c:
|
||||
|
||||
- Bad: ``fixed the bug (wtf?)``
|
||||
- Good: ``af_volume: fix crash due to null pointer access``
|
||||
Bad: ``fixed the bug (wtf?)``
|
||||
Good: ``af_volume: fix crash due to null pointer access``
|
||||
|
||||
Having a prefix gives context, and is especially useful when trying to find
|
||||
a specific change by looking at the history, or when running ``git blame``.
|
||||
@@ -63,14 +49,8 @@ Sending patches
|
||||
additional cosmetic changes in the same file you're working on. But don't do
|
||||
something like reformatting a whole file, and hiding an actual functional
|
||||
change in the same commit.
|
||||
- Changes to command line options (addition/modification/removal) must be
|
||||
documented in options.rst. Changes to input properties or input commands must
|
||||
be documented in input.rst. All changes to the user interface (options,
|
||||
properties, commands) must be documented with a small note in
|
||||
interface-changes.rst (although documenting additions is optional, and
|
||||
obscure corner cases and potentially be skipped too). Changes to the libmpv
|
||||
API must be reflected in the libmpv's headers doxygen, and should be
|
||||
documented in client-api-changes.rst.
|
||||
- If you add a new command line option, document it in options.rst. If you
|
||||
add a new input property, document it in input.rst.
|
||||
|
||||
Code formatting
|
||||
---------------
|
||||
@@ -113,16 +93,18 @@ mpv uses C99 with K&R formatting, with some exceptions.
|
||||
do_something();
|
||||
}
|
||||
```
|
||||
- If the if has an else branch, both branches should use braces, even if they're
|
||||
technically redundant.
|
||||
- If the body of an if statement uses braces, the else branch should also
|
||||
use braces (and reverse).
|
||||
|
||||
Example:
|
||||
|
||||
```C
|
||||
if (a) {
|
||||
one_line();
|
||||
// do something
|
||||
something();
|
||||
something_else();
|
||||
} else {
|
||||
one_other_line();
|
||||
one_line();
|
||||
}
|
||||
```
|
||||
- If an if condition spans multiple physical lines, then put the opening brace
|
||||
@@ -136,11 +118,14 @@ mpv uses C99 with K&R formatting, with some exceptions.
|
||||
very_long_condition_b)
|
||||
{
|
||||
code();
|
||||
} else {
|
||||
...
|
||||
}
|
||||
```
|
||||
- Remove any trailing whitespace.
|
||||
- If the file you're editing uses formatting different from from what is
|
||||
described here, it's probably an old file from times when nobody followed a
|
||||
consistent style. You're free to use the existing style, or the new style, or
|
||||
to send a patch to reformat the file to the new style before making functional
|
||||
changes.
|
||||
|
||||
General coding
|
||||
--------------
|
||||
@@ -156,35 +141,7 @@ General coding
|
||||
- Prefer fusing declaration and initialization, rather than putting declarations
|
||||
on the top of a block. Obvious data flow is more important than avoiding
|
||||
mixing declarations and statements, which is just a C90 artifact.
|
||||
- tech-overview.txt might help to get an overview how mpv is structured.
|
||||
- If you add features that require intrusive changes, discuss them on the dev
|
||||
channel first. There might be a better way to add a feature and it can avoid
|
||||
wasted work.
|
||||
|
||||
Rules for git push access
|
||||
-------------------------
|
||||
|
||||
Push access to the main git repository is handed out on an arbitrary basis. If
|
||||
you got access, the following rules must be followed:
|
||||
|
||||
- You are expected to follow the general development rules as outlined in this
|
||||
whole document.
|
||||
- You must be present on the IRC dev channel when you push something.
|
||||
- Anyone can push small fixes: typo corrections, small/obvious/uncontroversial
|
||||
bug fixes, edits to the user documentation or code comments, and so on.
|
||||
- You can freely make changes to parts of the code which you maintain. For
|
||||
larger changes, it's recommended to let others review the changes first.
|
||||
- You automatically maintain code if you wrote or modified most of it before
|
||||
(e.g. you made larger changes to it before, did partial or full rewrites, did
|
||||
major bug fixes, or you're the original author of the code). If there is more
|
||||
than one maintainer, you may need to come to an agreement with the others how
|
||||
to handle this to avoid conflict.
|
||||
- As a maintainer, you can approve pushes by others to "your" code.
|
||||
- If you approve or merge 3rd party changes, make sure they follow the general
|
||||
development rules.
|
||||
- Changes to user interface and public API must always be approved by the
|
||||
project leader.
|
||||
- Seasoned project members are allowed to revert commits that broke the build,
|
||||
or broke basic functionality in a catastrophic way, and the developer who
|
||||
broke it is unavailable. (Depending on severity.)
|
||||
- Adhere to the CoC.
|
||||
- The project leader is not bound by these rules.
|
||||
@@ -0,0 +1,74 @@
|
||||
Cross Compiling to Windows
|
||||
==========================
|
||||
|
||||
Cross compiling mpv to Windows is supported with MinGW-w64. This can be used to
|
||||
produce both 32 bit and 64 bit executables. MinGW-w64 is available from
|
||||
http://mingw-w64.sourceforge.net.
|
||||
|
||||
You have to run mpv's configure with these arguments:
|
||||
|
||||
```bash
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
|
||||
```
|
||||
|
||||
While building a complete MinGW-w64 toolchain yourself is possible, people have
|
||||
created scripts to help ease the process. These are the two recommended methods:
|
||||
|
||||
- Using [mingw-w64-cmake](https://github.com/lachs0r/mingw-w64-cmake) to setup
|
||||
a MinGW-w64 environment. We recommend you to try this first before MXE.
|
||||
mingw-w64-cmake will also build mpv and its dependencies.
|
||||
- Alternatively, you can use MXE: http://mxe.cc. With MXE, you have to manually
|
||||
set the target to MinGW-w64 (even if you compile to 32 bit). A working example
|
||||
below.
|
||||
|
||||
**Warning**: the original MinGW (http://www.mingw.org) is unsupported.
|
||||
|
||||
Note that MinGW environments included in Linux distributions are often broken,
|
||||
outdated and useless, and usually don't use MinGW-w64.
|
||||
|
||||
Example with MXE
|
||||
----------------
|
||||
|
||||
```bash
|
||||
# Download MXE. Note that compiling the required packages requires about 1.4 GB
|
||||
# or more!
|
||||
|
||||
cd /opt
|
||||
git clone https://github.com/mxe/mxe mingw
|
||||
cd mingw
|
||||
|
||||
# Set build options.
|
||||
|
||||
# The JOBS environment variable controls threads to use when building. DO NOT
|
||||
# use the regular `make -j4` option with MXE as it will slow down the build.
|
||||
# Alternatively, you can set this in the make command by appending "JOBS=4"
|
||||
# to the end of command:
|
||||
echo "JOBS := 4" >> settings.mk
|
||||
|
||||
# The MXE_TARGET environment variable builds MinGW-w64 for 32 bit targets.
|
||||
# Alternatively, you can specify this in the make command by appending
|
||||
# "MXE_TARGETS=i686-w64-mingw32" to the end of command:
|
||||
echo "MXE_TARGETS := i686-w64-mingw32" >> settings.mk
|
||||
|
||||
# If you want to build 64 bit version, use this:
|
||||
# echo "MXE_TARGETS := x86_64-w64-mingw32" >> settings.mk
|
||||
|
||||
# Build required packages. The following provide a minimum required to build
|
||||
# mpv.
|
||||
|
||||
make gcc ffmpeg libass jpeg pthreads
|
||||
|
||||
# Add MXE binaries to $PATH
|
||||
export PATH=/opt/mingw/usr/bin/:$PATH
|
||||
|
||||
# Build mpv. The target will be used to automatically select the name of the
|
||||
# build tools involved (e.g. it will use i686-w64-mingw32-gcc).
|
||||
|
||||
cd ..
|
||||
git clone https://github.com/mpv-player/mpv.git
|
||||
cd mpv
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
|
||||
# Or, if 64 bit version,
|
||||
# DEST_OS=win32 TARGET=x86_64-w64-mingw32 ./waf configure
|
||||
./waf build
|
||||
```
|
||||
+7
-43
@@ -27,12 +27,13 @@ The general simplified syntax is::
|
||||
<filename>,<start in seconds>,<length in seconds>
|
||||
|
||||
If the start time is omitted, 0 is used. If the length is omitted, the
|
||||
estimated remaining duration of the source file is used.
|
||||
estimated duration of the source file is used.
|
||||
|
||||
Note::
|
||||
|
||||
Usage of relative or absolute paths as well as any protocol prefixes may be
|
||||
prevented for security reasons.
|
||||
mpv can't use ordered chapter files or libquvi-resolved URLs in EDL
|
||||
entries. Usage of relative or absolute paths as well as any protocol
|
||||
prefixes is prevented for security reasons.
|
||||
|
||||
|
||||
Syntax of mpv EDL files
|
||||
@@ -51,8 +52,7 @@ The rest of the lines belong to one of these classes:
|
||||
1) An empty or commented line. A comment starts with ``#``, which must be the
|
||||
first character in the line. The rest of the line (up until the next line
|
||||
break) is ignored. An empty line has 0 bytes between two line feed bytes.
|
||||
2) A header entry if the line starts with ``!``.
|
||||
3) A segment entry in all other cases.
|
||||
2) A segment entry in all other cases.
|
||||
|
||||
Each segment entry consists of a list of named or unnamed parameters.
|
||||
Parameters are separated with ``,``. Named parameters consist of a name,
|
||||
@@ -64,8 +64,8 @@ Syntax::
|
||||
segment_entry ::= <param> ( <param> ',' )*
|
||||
param ::= [ <name> '=' ] ( <value> | '%' <number> '%' <valuebytes> )
|
||||
|
||||
The ``name`` string can consist of any characters, except ``=%,;\n!``. The
|
||||
``value`` string can consist of any characters except of ``,;\n!``.
|
||||
The ``name`` string can consist of any characters, except ``=%,;\n``. The
|
||||
``value`` string can consist of any characters except of ``,;\n``.
|
||||
|
||||
The construct starting with ``%`` allows defining any value with arbitrary
|
||||
contents inline, where ``number`` is an integer giving the number of bytes in
|
||||
@@ -95,42 +95,6 @@ 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.
|
||||
|
||||
Header entries start with ``!`` as first character after a line break. Header
|
||||
entries affect all other file entries in the EDL file. Their format is highly
|
||||
implementation specific. They should generally follow the file header, and come
|
||||
before any file entries.
|
||||
|
||||
MP4 DASH
|
||||
========
|
||||
|
||||
This is a header that helps implementing DASH, although it only provides a low
|
||||
level mechanism.
|
||||
|
||||
If this header is set, the given url designates an mp4 init fragment. It's
|
||||
downloaded, and every URL in the EDL is prefixed with the init fragment on the
|
||||
byte stream level. This is mostly for use by mpv's internal ytdl support. The
|
||||
ytdl script will call youtube-dl, which in turn actually processes DASH
|
||||
manifests. It may work only for this very specific purpose and fail to be
|
||||
useful in other scenarios. It can be removed or changed in incompatible ways
|
||||
at any times.
|
||||
|
||||
Example::
|
||||
|
||||
!mp4_dash,init=url
|
||||
|
||||
The ``url`` is encoded as parameter value as defined in the general EDL syntax.
|
||||
It's expected to point to an "initialization fragment", which will be prefixed
|
||||
to every entry in the EDL on the byte stream level.
|
||||
|
||||
The current implementation will
|
||||
|
||||
- ignore stream start times
|
||||
- use durations as hint for seeking only
|
||||
- not adjust source timestamps
|
||||
- open and close segments (i.e. fragments) as needed
|
||||
- not add segment boundaries as chapter points
|
||||
- require full compatibility between all segments (same codec etc.)
|
||||
|
||||
Timestamp format
|
||||
================
|
||||
|
||||
|
||||
+2
-6
@@ -95,16 +95,12 @@ As the options for various devices can get complex, profiles can be used.
|
||||
|
||||
An example profile file for encoding is provided in
|
||||
etc/encoding-profiles.conf in the source tree. This file is installed and loaded
|
||||
by default. If you want to modify it, you can replace and it with your own copy
|
||||
by doing::
|
||||
by default (if libavfilter is enabled at compilation). If you want to modify
|
||||
it, you can replace and it with your own copy by doing::
|
||||
|
||||
mkdir -p ~/.mpv
|
||||
cp /etc/mpv/encoding-profiles.conf ~/.mpv/encoding-profiles.conf
|
||||
|
||||
Keep in mind that the default profile is the playback one. If you want to add
|
||||
options that apply only in encoding mode, put them into a ``[encoding]``
|
||||
section.
|
||||
|
||||
Refer to the top of that file for more comments - in a nutshell, the following
|
||||
options are added by it::
|
||||
|
||||
|
||||
@@ -1,386 +0,0 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
mpv provides access to its internals via the following means:
|
||||
|
||||
- options
|
||||
- commands
|
||||
- properties
|
||||
- events
|
||||
|
||||
All of these are important for interfacing both with end users and API users
|
||||
(which include Lua scripts, libmpv, and the JSON IPC). As such, they constitute
|
||||
a large part of the user interface and APIs.
|
||||
|
||||
This document lists changes to them. New changes are added to the top.
|
||||
|
||||
Interface changes
|
||||
=================
|
||||
|
||||
::
|
||||
|
||||
--- mpv 0.26.0 ---
|
||||
- remove remaining deprecated audio device options, like --alsa-device
|
||||
Some of them were removed in earlier releases.
|
||||
- introduce --replaygain... options, which replace the same functionality
|
||||
provided by the deprecated --af=volume:replaygain... mechanism.
|
||||
- drop the internal "mp-rawvideo" codec (used by --demuxer=rawvideo)
|
||||
- rename --sub-ass-style-override to --sub-ass-override, and rename the
|
||||
`--sub-ass-override=signfs` setting to `--sub-ass-override=scale`.
|
||||
- change default of --video-aspect-method to "bitstream". The "hybrid"
|
||||
method (old default) is deprecated.
|
||||
- remove property "video-params/nom-peak"
|
||||
- remove option --target-brightness
|
||||
- replace vf_format's `peak` suboption by `sig-peak`, which is relative to
|
||||
the reference white level instead of in cd/m^2
|
||||
- renamed the TRCs `st2084` and `std-b67` to `pq` and `hlg` respectively
|
||||
- the "osd" command is deprecated (use "cycle osd-level")
|
||||
- --field-dominance is deprecated (use --vf=setfield=bff or tff)
|
||||
- --really-quiet subtle behavior change
|
||||
- the deprecated handling of setting "no-" options via client API is dropped
|
||||
- the following options change to append-by-default (and possibly separator):
|
||||
--script
|
||||
also, the following options are deprecated:
|
||||
--sub-paths => --sub-file-paths
|
||||
the following options are deprecated for setting via API:
|
||||
"script" (use "scripts")
|
||||
"sub-file" (use "sub-files")
|
||||
"audio-file" (use "audio-files")
|
||||
"external-file" (use "external-files")
|
||||
(the compatibility hacks for this will be removed after this release)
|
||||
- remove property `vo-performance`, and add `vo-passes` as a more general
|
||||
replacement
|
||||
- deprecate passing multiple arguments to -add/-pre options (affects the
|
||||
vf/af commands too)
|
||||
- remove --demuxer-lavf-cryptokey. Use --demux-lavf-o=cryptokey=<hex> or
|
||||
--demux-lavf-o=decryption_key=<hex> instead (whatever fits your situation).
|
||||
- rename --opengl-dumb-mode=no to --opengl-dumb-mode=auto, and make `no`
|
||||
always disable it (unless forced on by hardware limitation).
|
||||
- generalize --scale-clamp, --cscale-clamp etc. to accept a float between
|
||||
0.0 and 1.0 instead of just being a flag. A value of 1.0 corresponds to
|
||||
the old `yes`, and a value of 0.0 corresponds to the old `no`.
|
||||
--- mpv 0.25.0 ---
|
||||
- remove opengl-cb dxva2 dummy hwdec interop
|
||||
(see git "vo_opengl: remove dxva2 dummy hwdec backend")
|
||||
- remove ppm, pgm, pgmyuv, tga choices from the --screenshot-format and
|
||||
--vo-image-format options
|
||||
- the "jpeg" choice in the option above now leads to a ".jpg" file extension
|
||||
- --af=drc is gone (you can use e.g. lavfi/acompressor instead)
|
||||
- remove image_size predefined uniform from OpenGL user shaders. Use
|
||||
input_size instead
|
||||
- add --sub-filter-sdh
|
||||
- add --sub-filter-sdh-harder
|
||||
- remove --input-app-events option (macOS)
|
||||
- deprecate most --vf and --af filters. Only some filters not in libavfilter
|
||||
will be kept.
|
||||
Also, you can use libavfilter filters directly (e.g. you can use
|
||||
--vf=name=opts instead of --vf=lavfi=[name=opts]), as long as the
|
||||
libavfilter filter's name doesn't clash with a mpv builtin filter.
|
||||
In the long term, --vf/--af syntax might change again, but if it does, it
|
||||
will switch to libavfilter's native syntax. (The above mentioned direct
|
||||
support for lavfi filters still has some differences, such as how strings
|
||||
are escaped.) If this happens, the non-deprecated builtin filters might be
|
||||
moved to "somewhere else" syntax-wise.
|
||||
- deprecate --loop - after a deprecation period, it will be undeprecated,
|
||||
but changed to alias --loop-file
|
||||
- add --keep-open-pause=no
|
||||
- deprecate --demuxer-max-packets
|
||||
- change --audio-file-auto default from "exact" to "no" (mpv won't load
|
||||
files with the same filename as the video, but different extension, as
|
||||
audio track anymore)
|
||||
--- mpv 0.24.0 ---
|
||||
- deprecate --hwdec-api and replace it with --opengl-hwdec-interop.
|
||||
The new option accepts both --hwdec values, as well as named backends.
|
||||
A minor difference is that --hwdec-api=no (which used to be the default)
|
||||
now actually does not preload any interop layer, while the new default
|
||||
("") uses the value of --hwdec.
|
||||
- drop deprecated --ad/--vd features
|
||||
- drop deprecated --sub-codepage syntax
|
||||
- rename properties:
|
||||
- "drop-frame-count" to "decoder-frame-drop-count"
|
||||
- "vo-drop-frame-count" to "frame-drop-count"
|
||||
The old names still work, but are deprecated.
|
||||
- remove the --stream-capture option and property. No replacement.
|
||||
(--record-file might serve as alternative)
|
||||
- add --sub-justify
|
||||
- add --sub-ass-justify
|
||||
- internally there's a different way to enable the demuxer cache now
|
||||
it can be auto-enabled even if the stream cache remains disabled
|
||||
--- mpv 0.23.0 ---
|
||||
- remove deprecated vf_vdpaurb (use "--hwdec=vdpau-copy" instead)
|
||||
- the following properties now have new semantics:
|
||||
- "demuxer" (use "current-demuxer")
|
||||
- "fps" (use "container-fps")
|
||||
- "idle" (use "idle-active")
|
||||
- "cache" (use "cache-percent")
|
||||
- "audio-samplerate" (use "audio-params/samplerate")
|
||||
- "audio-channels" (use "audio-params/channel-count")
|
||||
- "audio-format" (use "audio-codec-name")
|
||||
(the properties equivalent to the old semantics are in parentheses)
|
||||
- remove deprecated --vo and --ao sub-options (like --vo=opengl:...), and
|
||||
replace them with global options. A somewhat complete list can be found
|
||||
here: https://github.com/mpv-player/mpv/wiki/Option-replacement-list#mpv-0210
|
||||
- remove --vo-defaults and --ao-defaults as well
|
||||
- remove deprecated global sub-options (like -demuxer-rawaudio format=...),
|
||||
use flat options (like --demuxer-rawaudio-format=...)
|
||||
- the --sub-codepage option changes in incompatible ways:
|
||||
- detector-selection and fallback syntax is deprecated
|
||||
- enca/libguess are removed and deprecated (behaves as if they hadn't
|
||||
been compiled-in)
|
||||
- --sub-codepage=<codepage> does not force the codepage anymore
|
||||
(this requires different and new syntax)
|
||||
- remove --fs-black-out-screens option for macOS
|
||||
- change how spdif codecs are selected. You can't enable spdif passthrough
|
||||
with --ad anymore. This was deprecated; use --audio-spdif instead.
|
||||
- deprecate the "family" selection with --ad/--vd
|
||||
forcing/excluding codecs with "+", "-", "-" is deprecated as well
|
||||
- explicitly mark --ad-spdif-dtshd as deprecated (it was done so a long time
|
||||
ago, but it didn't complain when using the option)
|
||||
--- mpv 0.22.0 ---
|
||||
- the "audio-device-list" property now sets empty device description to the
|
||||
device name as a fallback
|
||||
- add --hidpi-window-scale option for macOS
|
||||
- add audiounit audio output for iOS
|
||||
- make --start-time work with --rebase-start-time=no
|
||||
- add --opengl-early-flush=auto mode
|
||||
- add --hwdec=vdpau-copy, deprecate vf_vdpaurb
|
||||
- add tct video output for true-color and 256-color terminals
|
||||
--- mpv 0.21.0 ---
|
||||
- unlike in older versions, setting options at runtime will now take effect
|
||||
immediately (see for example issue #3281). On the other hand, it will also
|
||||
do runtime verification and reject option changes that do not work
|
||||
(example: setting the "vf" option to a filter during playback, which fails
|
||||
to initialize - the option value will remain at its old value). In general,
|
||||
"set name value" should be mostly equivalent to "set options/name value"
|
||||
in cases where the "name" property is not deprecated and "options/name"
|
||||
exists - deviations from this are either bugs, or documented as caveats
|
||||
in the "Inconsistencies between options and properties" manpage section.
|
||||
- deprecate _all_ --vo and --ao suboptions. Generally, all suboptions are
|
||||
replaced by global options, which do exactly the same. For example,
|
||||
"--vo=opengl:scale=nearest" turns into "--scale=nearest". In some cases,
|
||||
the global option is prefixed, e.g. "--vo=opengl:pbo" turns into
|
||||
"--opengl-pbo".
|
||||
Most of the exact replacements are documented here:
|
||||
https://github.com/mpv-player/mpv/wiki/Option-replacement-list
|
||||
- remove --vo=opengl-hq. Set --profile=opengl-hq instead. Note that this
|
||||
profile does not force the VO. This means if you use the --vo option to
|
||||
set another VO, it won't work. But this also means it can be used with
|
||||
opengl-cb.
|
||||
- remove the --vo=opengl "pre-shaders", "post-shaders" and "scale-shader"
|
||||
sub-options: they were deprecated in favor of "user-shaders"
|
||||
- deprecate --vo-defaults (no replacement)
|
||||
- remove the vo-cmdline command. You can set OpenGL renderer options
|
||||
directly via properties instead.
|
||||
- deprecate the device/sink options on all AOs. Use --audio-device instead.
|
||||
- deprecate "--ao=wasapi:exclusive" and "--ao=coreaudio:exclusive",
|
||||
use --audio-exclusive instead.
|
||||
- subtle changes in how "--no-..." options are treated mean that they are
|
||||
not accessible under "options/..." anymore (instead, these are resolved
|
||||
at parsing time). This does not affect options which start with "--no-",
|
||||
but do not use the mechanism for negation options.
|
||||
(Also see client API change for API version 1.23.)
|
||||
- rename the following properties
|
||||
- "demuxer" -> "current-demuxer"
|
||||
- "fps" -> "container-fps"
|
||||
- "idle" -> "idle-active"
|
||||
- "cache" -> "cache-percent"
|
||||
the old names are deprecated and will change behavior in mpv 0.23.0.
|
||||
- remove deprecated "hwdec-active" and "hwdec-detected" properties
|
||||
- deprecate the ao and vo auto-profiles (they never made any sense)
|
||||
- deprecate "--vo=direct3d_shaders" - use "--vo=direct3d" instead.
|
||||
Change "--vo=direct3d" to always use shaders by default.
|
||||
- deprecate --playlist-pos option, renamed to --playlist-start
|
||||
- deprecate the --chapter option, as it is redundant with --start/--end,
|
||||
and conflicts with the semantics of the "chapter" property
|
||||
- rename --sub-text-* to --sub-* and --ass-* to --sub-ass-* (old options
|
||||
deprecated)
|
||||
- incompatible change to cdda:// protocol options: the part after cdda://
|
||||
now always sets the device, not the span or speed to be played. No
|
||||
separating extra "/" is needed. The hidden --cdda-device options is also
|
||||
deleted (it was redundant with the documented --cdrom-device).
|
||||
- deprecate --vo=rpi. It will be removed in mpv 0.23.0. Its functionality
|
||||
was folded into --vo=opengl, which now uses RPI hardware decoding by
|
||||
treating it as a hardware overlay (without applying GL filtering). Also
|
||||
to be changed in 0.23.0: the --fs flag will be reset to "no" by default
|
||||
(like on the other platforms).
|
||||
- deprecate --mute=auto (informally has been since 0.18.1)
|
||||
- deprecate "resume" and "suspend" IPC commands. They will be completely
|
||||
removed in 0.23.0.
|
||||
- deprecate mp.suspend(), mp.resume(), mp.resume_all() Lua scripting
|
||||
commands, as well as setting mp.use_suspend. They will be completely
|
||||
removed in 0.23.0.
|
||||
- the "seek" command's absolute seek mode will now interpret negative
|
||||
seek times as relative from the end of the file (and clamps seeks that
|
||||
still go before 0)
|
||||
- add almost all options to the property list, meaning you can change
|
||||
options without adding "options/" to the property name (a new section
|
||||
has been added to the manpage describing some conflicting behavior
|
||||
between options and properties)
|
||||
- implement changing sub-speed during playback
|
||||
- make many previously fixed options changeable at runtime (for example
|
||||
--terminal, --osc, --ytdl, can all be enable/disabled after
|
||||
mpv_initialize() - this can be extended to other still fixed options
|
||||
on user requests)
|
||||
--- mpv 0.20.0 ---
|
||||
- add --image-display-duration option - this also means that image duration
|
||||
is not influenced by --mf-fps anymore in the general case (this is an
|
||||
incompatible change)
|
||||
--- mpv 0.19.0 ---
|
||||
- deprecate "balance" option/property (no replacement)
|
||||
--- mpv 0.18.1 ---
|
||||
- deprecate --heartbeat-cmd
|
||||
- remove --softvol=no capability:
|
||||
- deprecate --softvol, it now does nothing
|
||||
- --volume, --mute, and the corresponding properties now always control
|
||||
softvol, and behave as expected without surprises (e.g. you can set
|
||||
them normally while no audio is initialized)
|
||||
- rename --softvol-max to --volume-max (deprecated alias is added)
|
||||
- the --volume-restore-data option and property are removed without
|
||||
replacement. They were _always_ internal, and used for watch-later
|
||||
resume/restore. Now --volume/--mute are saved directly instead.
|
||||
- the previous point means resuming files with older watch-later configs
|
||||
will print an error about missing --volume-restore-data (which you can
|
||||
ignore), and will not restore the previous value
|
||||
- as a consequence, volume controls will no longer control PulseAudio
|
||||
per-application value, or use the system mixer's per-application
|
||||
volume processing
|
||||
- system or per-application volume can still be controlled with the
|
||||
ao-volume and ao-mute properties (there are no command line options)
|
||||
--- mpv 0.18.0 ---
|
||||
- now ab-loops are active even if one of the "ab-loop-a"/"-b" properties is
|
||||
unset ("no"), in which case the start of the file is used if the A loop
|
||||
point is unset, and the end of the file for an unset B loop point
|
||||
- deprecate --sub-ass=no option by --ass-style-override=strip
|
||||
(also needs --embeddedfonts=no)
|
||||
- add "hwdec-interop" and "hwdec-current" properties
|
||||
- deprecated "hwdec-active" and "hwdec-detected" properties (to be removed
|
||||
in mpv 0.20.0)
|
||||
- choice option/property values that are "yes" or "no" will now be returned
|
||||
as booleans when using the mpv_node functions in the client API, the
|
||||
"native" property accessors in Lua, and the JSON API. They can be set as
|
||||
such as well.
|
||||
- the VO opengl fbo-format sub-option does not accept "rgb" or "rgba"
|
||||
anymore
|
||||
- all VO opengl prescalers have been removed (replaced by user scripts)
|
||||
--- mpv 0.17.0 ---
|
||||
- deprecate "track-list/N/audio-channels" property (use
|
||||
"track-list/N/demux-channel-count" instead)
|
||||
- remove write access to "stream-pos", and change semantics for read access
|
||||
- Lua scripts now don't suspend mpv by default while script code is run
|
||||
- add "cache-speed" property
|
||||
- rename --input-unix-socket to --input-ipc-server, and make it work on
|
||||
Windows too
|
||||
- change the exact behavior of the "video-zoom" property
|
||||
- --video-unscaled no longer disables --video-zoom and --video-aspect
|
||||
To force the old behavior, set --video-zoom=0 and --video-aspect=0
|
||||
--- mpv 0.16.0 ---
|
||||
- change --audio-channels default to stereo (use --audio-channels=auto to
|
||||
get the old default)
|
||||
- add --audio-normalize-downmix
|
||||
- change the default downmix behavior (--audio-normalize-downmix=yes to get
|
||||
the old default)
|
||||
- VO opengl custom shaders must now use "sample_pixel" as function name,
|
||||
instead of "sample"
|
||||
- change VO opengl scaler-resizes-only default to enabled
|
||||
- add VO opengl "interpolation-threshold" suboption (introduces new default
|
||||
behavior, which can change e.g. ``--video-sync=display-vdrop`` to the
|
||||
worse, but is usually what you want)
|
||||
- make "volume" and "mute" properties changeable even if no audio output is
|
||||
active (this gives not-ideal behavior if --softvol=no is used)
|
||||
- add "volume-max" and "mixer-active" properties
|
||||
- ignore --input-cursor option for events injected by input commands like
|
||||
"mouse", "keydown", etc.
|
||||
--- mpv 0.15.0 ---
|
||||
- change "yadif" video filter defaults
|
||||
--- mpv 0.14.0 ---
|
||||
- vo_opengl interpolation now requires --video-sync=display-... to be set
|
||||
- change some vo_opengl defaults (including changing tscale)
|
||||
- add "vsync-ratio", "estimated-display-fps" properties
|
||||
- add --rebase-start-time option
|
||||
This is a breaking change to start time handling. Instead of making start
|
||||
time handling an aspect of different options and properties (like
|
||||
"time-pos" vs. "playback-time"), make it dependent on the new option. For
|
||||
compatibility, the "time-start" property now always returns 0, so code
|
||||
which attempted to handle rebasing manually will not break.
|
||||
--- mpv 0.13.0 ---
|
||||
- remove VO opengl-cb frame queue suboptions (no replacement)
|
||||
--- mpv 0.12.0 ---
|
||||
- remove --use-text-osd (useless; fontconfig isn't a requirement anymore,
|
||||
and text rendering is also lazily initialized)
|
||||
- some time properties (at least "playback-time", "time-pos",
|
||||
"time-remaining", "playtime-remaining") now are unavailable if the time
|
||||
is unknown, instead of just assuming that the internal playback position
|
||||
is 0
|
||||
- add --audio-fallback-to-null option
|
||||
- replace vf_format outputlevels suboption with "video-output-levels" global
|
||||
property/option; also remove "colormatrix-output-range" property
|
||||
- vo_opengl: remove sharpen3/sharpen5 scale filters, add sharpen sub-option
|
||||
--- mpv 0.11.0 ---
|
||||
- add "af-metadata" property
|
||||
--- mpv 0.10.0 ---
|
||||
- add --video-aspect-method option
|
||||
- add --playlist-pos option
|
||||
- add --video-sync* options
|
||||
"display-sync-active" property
|
||||
"vo-missed-frame-count" property
|
||||
"audio-speed-correction" and "video-speed-correction" properties
|
||||
- remove --demuxer-readahead-packets and --demuxer-readahead-bytes
|
||||
add --demuxer-max-packets and --demuxer-max-bytes
|
||||
(the new options are not replacement and have very different semantics)
|
||||
- change "video-aspect" property: always settable, even if no video is
|
||||
running; always return the override - if no override is set, return
|
||||
the video's aspect ratio
|
||||
- remove disc-nav (DVD, BD) related properties and commands
|
||||
- add "option-info/<name>/set-locally" property
|
||||
- add --cache-backbuffer; change --cache-default default to 75MB
|
||||
the new total cache size is the sum of backbuffer and the cache size
|
||||
specified by --cache-default or --cache
|
||||
- add ``track-list/N/audio-channels`` property
|
||||
- change --screenshot-tag-colorspace default value
|
||||
- add --stretch-image-subs-to-screen
|
||||
- add "playlist/N/title" property
|
||||
- add --video-stereo-mode=no to disable auto-conversions
|
||||
- add --force-seekable, and change default seekability in some cases
|
||||
- add vf yadif/vavpp/vdpaupp interlaced-only suboptions
|
||||
Also, the option is enabled by default (Except vf_yadif, which has
|
||||
it enabled only if it's inserted by the deinterlace property.)
|
||||
- add --hwdec-preload
|
||||
- add ao coreaudio exclusive suboption
|
||||
- add ``track-list/N/forced`` property
|
||||
- add audio-params/channel-count and ``audio-params-out/channel-count props.
|
||||
- add af volume replaygain-fallback suboption
|
||||
- add video-params/stereo-in property
|
||||
- add "keypress", "keydown", and "keyup" commands
|
||||
- deprecate --ad-spdif-dtshd and enabling passthrough via --ad
|
||||
add --audio-spdif as replacement
|
||||
- remove "get_property" command
|
||||
- remove --slave-broken
|
||||
- add vo opengl custom shader suboptions (source-shader, scale-shader,
|
||||
pre-shaders, post-shaders)
|
||||
- completely change how the hwdec properties work:
|
||||
- "hwdec" now reflects the --hwdec option
|
||||
- "hwdec-detected" does partially what the old "hwdec" property did
|
||||
(and also, "detected-hwdec" is removed)
|
||||
- "hwdec-active" is added
|
||||
- add protocol-list property
|
||||
- deprecate audio-samplerate and audio-channels properties
|
||||
(audio-params sub-properties are the replacement)
|
||||
- add audio-params and audio-out-params properties
|
||||
- deprecate "audio-format" property, replaced with "audio-codec-name"
|
||||
- deprecate --media-title, replaced with --force-media-title
|
||||
- deprecate "length" property, replaced with "duration"
|
||||
- change volume property:
|
||||
- the value 100 is now always "unchanged volume" - with softvol, the
|
||||
range is 0 to --softvol-max, without it is 0-100
|
||||
- the minimum value of --softvol-max is raised to 100
|
||||
- remove vo opengl npot suboption
|
||||
- add relative seeking by percentage to "seek" command
|
||||
- add playlist_shuffle command
|
||||
- add --force-window=immediate
|
||||
- add ao coreaudio change-physical-format suboption
|
||||
- remove vo opengl icc-cache suboption, add icc-cache-dir suboption
|
||||
- add --screenshot-directory
|
||||
- add --screenshot-high-bit-depth
|
||||
- add --screenshot-jpeg-source-chroma
|
||||
- default action for "rescan_external_files" command changes
|
||||
--- mpv 0.9.0 ---
|
||||
+285
-80
@@ -4,22 +4,34 @@ AUDIO FILTERS
|
||||
Audio filters allow you to modify the audio stream and its properties. The
|
||||
syntax is:
|
||||
|
||||
``--af=...``
|
||||
Setup a chain of audio filters. See ``--vf`` for the syntax.
|
||||
``--af=<filter1[=parameter1:parameter2:...],filter2,...>``
|
||||
Setup a chain of audio filters.
|
||||
|
||||
.. note::
|
||||
|
||||
To get a full list of available audio filters, see ``--af=help``.
|
||||
|
||||
Also, keep in mind that most actual filters are available via the ``lavfi``
|
||||
wrapper, which gives you access to most of libavfilter's filters. This
|
||||
includes all filters that have been ported from MPlayer to libavfilter.
|
||||
You can also set defaults for each filter. The defaults are applied before the
|
||||
normal filter parameters.
|
||||
|
||||
The ``--vf`` description describes how libavfilter can be used and how to
|
||||
workaround deprecated mpv filters.
|
||||
``--af-defaults=<filter1[=parameter1:parameter2:...],filter2,...>``
|
||||
Set defaults for each filter.
|
||||
|
||||
See ``--vf`` group of options for info on how ``--af-defaults``, ``--af-add``,
|
||||
``--af-pre``, ``--af-del``, ``--af-clr``, and possibly others work.
|
||||
Audio filters are managed in lists. There are a few commands to manage the
|
||||
filter list:
|
||||
|
||||
``--af-add=<filter1[,filter2,...]>``
|
||||
Appends the filters given as arguments to the filter list.
|
||||
|
||||
``--af-pre=<filter1[,filter2,...]>``
|
||||
Prepends the filters given as arguments to the filter list.
|
||||
|
||||
``--af-del=<index1[,index2,...]>``
|
||||
Deletes the filters at the given indexes. Index numbers start at 0,
|
||||
negative numbers address the end of the list (-1 is the last).
|
||||
|
||||
``--af-clr``
|
||||
Completely empties the filter list.
|
||||
|
||||
Available filters are:
|
||||
|
||||
@@ -47,14 +59,11 @@ Available filters are:
|
||||
(If you just want to set defaults for this filter that will be used
|
||||
even by automatically inserted lavrresample instances, you should
|
||||
prefer setting them with ``--af-defaults=lavrresample:...``.)
|
||||
``normalize=<yes|no|auto>``
|
||||
Whether to normalize when remixing channel layouts (default: auto).
|
||||
``auto`` uses the value set by ``--audio-normalize-downmix``.
|
||||
``o=<string>``
|
||||
Set AVOptions on the SwrContext or AVAudioResampleContext. These should
|
||||
be documented by FFmpeg or Libav.
|
||||
|
||||
``lavcac3enc[=options]``
|
||||
``lavcac3enc[=tospdif[:bitrate[:minchn]]]``
|
||||
Encode multi-channel audio to AC-3 at runtime using libavcodec. Supports
|
||||
16-bit native-endian input format, maximum 6 channels. The output is
|
||||
big-endian when outputting a raw AC-3 stream, native-endian when
|
||||
@@ -68,12 +77,10 @@ Available filters are:
|
||||
``bitrate=<rate>``
|
||||
The bitrate use for the AC-3 stream. Set it to 384 to get 384 kbps.
|
||||
|
||||
The default is 640. Some receivers might not be able to handle this.
|
||||
|
||||
Valid values: 32, 40, 48, 56, 64, 80, 96, 112, 128,
|
||||
160, 192, 224, 256, 320, 384, 448, 512, 576, 640.
|
||||
|
||||
The special value ``auto`` selects a default bitrate based on the
|
||||
The special value ``default`` selects a default bitrate based on the
|
||||
input channel number:
|
||||
|
||||
:1ch: 96
|
||||
@@ -83,13 +90,62 @@ Available filters are:
|
||||
:5ch: 448
|
||||
:6ch: 448
|
||||
|
||||
``minch=<n>``
|
||||
If the input channel number is less than ``<minch>``, the filter will
|
||||
detach itself (default: 3).
|
||||
``minchn=<n>``
|
||||
If the input channel number is less than ``<minchn>``, the filter will
|
||||
detach itself (default: 5).
|
||||
|
||||
``encoder=<name>``
|
||||
Select the libavcodec encoder used. Currently, this should be an AC-3
|
||||
encoder, and using another codec will fail horribly.
|
||||
``sweep[=speed]``
|
||||
Produces a sine sweep.
|
||||
|
||||
``<0.0-1.0>``
|
||||
Sine function delta, use very low values to hear the sweep.
|
||||
|
||||
``sinesuppress[=freq:decay]``
|
||||
Remove a sine at the specified frequency. Useful to get rid of the 50/60 Hz
|
||||
noise on low quality audio equipment. It only works on mono input.
|
||||
|
||||
``<freq>``
|
||||
The frequency of the sine which should be removed (in Hz) (default:
|
||||
50)
|
||||
``<decay>``
|
||||
Controls the adaptivity (a larger value will make the filter adapt to
|
||||
amplitude and phase changes quicker, a smaller value will make the
|
||||
adaptation slower) (default: 0.0001). Reasonable values are around
|
||||
0.001.
|
||||
|
||||
``bs2b[=option1:option2:...]``
|
||||
Bauer stereophonic to binaural transformation using libbs2b. Improves the
|
||||
headphone listening experience by making the sound similar to that from
|
||||
loudspeakers, allowing each ear to hear both channels and taking into
|
||||
account the distance difference and the head shadowing effect. It is
|
||||
applicable only to 2-channel audio.
|
||||
|
||||
``fcut=<300-1000>``
|
||||
Set cut frequency in Hz.
|
||||
``feed=<10-150>``
|
||||
Set feed level for low frequencies in 0.1*dB.
|
||||
``profile=<value>``
|
||||
Several profiles are available for convenience:
|
||||
|
||||
:default: will be used if nothing else was specified (fcut=700,
|
||||
feed=45)
|
||||
:cmoy: Chu Moy circuit implementation (fcut=700, feed=60)
|
||||
:jmeier: Jan Meier circuit implementation (fcut=650, feed=95)
|
||||
|
||||
If ``fcut`` or ``feed`` options are specified together with a profile, they
|
||||
will be applied on top of the selected profile.
|
||||
|
||||
``hrtf[=flag]``
|
||||
Head-related transfer function: Converts multichannel audio to 2-channel
|
||||
output for headphones, preserving the spatiality of the sound.
|
||||
|
||||
==== ===================================
|
||||
Flag Meaning
|
||||
==== ===================================
|
||||
m matrix decoding of the rear channel
|
||||
s 2-channel matrix decoding
|
||||
0 no matrix decoding (default)
|
||||
==== ===================================
|
||||
|
||||
``equalizer=g1:g2:g3:...:g10``
|
||||
10 octave band graphic equalizer, implemented using 10 IIR band-pass
|
||||
@@ -148,7 +204,7 @@ Available filters are:
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
``mpv --af=channels=4:[0-1,1-0,2-2,3-3] media.avi``
|
||||
``mpv --af=channels=4:[0-1,1-0,0-2,1-3] media.avi``
|
||||
Would change the number of channels to 4 and set up 4 routes that
|
||||
swap channel 0 and channel 1 and leave channel 2 and 3 intact.
|
||||
Observe that if media containing two channels were played back,
|
||||
@@ -167,21 +223,14 @@ Available filters are:
|
||||
automatically up- and downmix standard channel layouts.
|
||||
|
||||
``format=format:srate:channels:out-format:out-srate:out-channels``
|
||||
Does not do any format conversion itself. Rather, it may cause the
|
||||
filter system to insert necessary conversion filters before or after this
|
||||
filter if needed. It is primarily useful for controlling the audio format
|
||||
going into other filters. To specify the format for audio output, see
|
||||
``--audio-format``, ``--audio-samplerate``, and ``--audio-channels``. This
|
||||
filter is able to force a particular format, whereas ``--audio-*``
|
||||
may be overridden by the ao based on output compatibility.
|
||||
Force a specific audio format/configuration without actually changing the
|
||||
audio data. Keep in mind that the filter system might auto-insert actual
|
||||
conversion filters before or after this filter if needed.
|
||||
|
||||
All parameters are optional. The first 3 parameters restrict what the filter
|
||||
accepts as input. They will therefore cause conversion filters to be
|
||||
inserted before this one. The ``out-`` parameters tell the filters or audio
|
||||
outputs following this filter how to interpret the data without actually
|
||||
doing a conversion. Setting these will probably just break things unless you
|
||||
really know you want this for some reason, such as testing or dealing with
|
||||
broken media.
|
||||
accepts as input. The ``out-`` parameters change the audio format, without
|
||||
actually doing a conversion. The data will be 'reinterpreted' by the
|
||||
filters or audio outputs following this filter.
|
||||
|
||||
``<format>``
|
||||
Force conversion to this format. Use ``--af=format=format=help`` to get
|
||||
@@ -201,9 +250,22 @@ Available filters are:
|
||||
|
||||
``<out-channels>``
|
||||
|
||||
*NOTE*: this filter used to be named ``force``. The old ``format`` filter
|
||||
used to do conversion itself, unlike this one which lets the filter system
|
||||
handle the conversion.
|
||||
See also ``--audio-format``, ``--audio-samplerate``, and
|
||||
``--audio-channels`` for related options. Keep in mind that
|
||||
``--audio-channels`` does not actually force the number of
|
||||
channels in most cases, while this filter can do this.
|
||||
|
||||
*NOTE*: this filter used to be named ``force``. Also, unlike the old
|
||||
``format`` filter, this does not do any actual conversion anymore.
|
||||
Conversion is done by other, automatically inserted filters.
|
||||
|
||||
``convert24``
|
||||
Filter for internal use only. Converts between 24-bit and 32-bit sample
|
||||
formats.
|
||||
|
||||
``convertsignendian``
|
||||
Filter for internal use only. Converts between signed/unsigned formats
|
||||
and formats with different endian.
|
||||
|
||||
``volume[=<volumedb>[:...]]``
|
||||
Implements software volume control. Use this filter with caution since it
|
||||
@@ -211,9 +273,6 @@ Available filters are:
|
||||
best to use the *Master* volume control of your sound card or the volume
|
||||
knob on your amplifier.
|
||||
|
||||
*WARNING*: This filter is deprecated. Use the top-level options like
|
||||
``--volume`` and ``--replaygain...`` instead.
|
||||
|
||||
*NOTE*: This filter is not reentrant and can therefore only be enabled
|
||||
once for every audio stream.
|
||||
|
||||
@@ -232,10 +291,6 @@ Available filters are:
|
||||
``replaygain-clip=yes|no``
|
||||
Prevent clipping caused by replaygain by automatically lowering the
|
||||
gain (default). Use ``replaygain-clip=no`` to disable this.
|
||||
``replaygain-fallback``
|
||||
Gain in dB to apply if the file has no replay gain tags. This option
|
||||
is always applied if the replaygain logic is somehow inactive. If this
|
||||
is applied, no other replaygain options are applied.
|
||||
``softclip``
|
||||
Turns soft clipping on. Soft-clipping can make the
|
||||
sound more smooth if very high volume levels are used. Enable this
|
||||
@@ -299,12 +354,183 @@ Available filters are:
|
||||
``mpv '--af=format=channels=5.1' '--audio-channels=5.1'`` would always force
|
||||
remixing audio to 5.1 and output it like this.
|
||||
|
||||
This filter supports the following ``af-command`` commands:
|
||||
``sub[=fc:ch]``
|
||||
Adds a subwoofer channel to the audio stream. The audio data used for
|
||||
creating the subwoofer channel is an average of the sound in channel 0 and
|
||||
channel 1. The resulting sound is then low-pass filtered by a 4th order
|
||||
Butterworth filter with a default cutoff frequency of 60Hz and added to a
|
||||
separate channel in the audio stream.
|
||||
|
||||
``set-matrix``
|
||||
Set the ``<matrix>`` argument dynamically. This can be used to change
|
||||
the mixing matrix at runtime, without reinitializing the entire filter
|
||||
chain.
|
||||
.. warning::
|
||||
|
||||
Disable this filter when you are playing media with an LFE channel
|
||||
(e.g. 5.1 surround sound), otherwise this filter will disrupt the sound
|
||||
to the subwoofer.
|
||||
|
||||
``<fc>``
|
||||
cutoff frequency in Hz for the low-pass filter (20 Hz to 300 Hz)
|
||||
(default: 60 Hz) For the best result try setting the cutoff frequency
|
||||
as low as possible. This will improve the stereo or surround sound
|
||||
experience.
|
||||
``<ch>``
|
||||
Determines the channel number in which to insert the sub-channel
|
||||
audio. Channel number can be between 0 and 7 (default: 5). Observe
|
||||
that the number of channels will automatically be increased to <ch> if
|
||||
necessary.
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``mpv --af=sub=100:4 --audio-channels=5 media.avi``
|
||||
Would add a subwoofer channel with a cutoff frequency of 100 Hz to
|
||||
output channel 4.
|
||||
|
||||
``center``
|
||||
Creates a center channel from the front channels. May currently be low
|
||||
quality as it does not implement a high-pass filter for proper extraction
|
||||
yet, but averages and halves the channels instead.
|
||||
|
||||
``<ch>``
|
||||
Determines the channel number in which to insert the center channel.
|
||||
Channel number can be between 0 and 7 (default: 5). Observe that the
|
||||
number of channels will automatically be increased to ``<ch>`` if
|
||||
necessary.
|
||||
|
||||
``surround[=delay]``
|
||||
Decoder for matrix encoded surround sound like Dolby Surround. Some files
|
||||
with 2-channel audio actually contain matrix encoded surround sound.
|
||||
|
||||
``<delay>``
|
||||
delay time in ms for the rear speakers (0 to 1000) (default: 20) This
|
||||
delay should be set as follows: If d1 is the distance from the
|
||||
listening position to the front speakers and d2 is the distance from
|
||||
the listening position to the rear speakers, then the delay should be
|
||||
set to 15ms if d1 <= d2 and to 15 + 5*(d1-d2) if d1 > d2.
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``mpv --af=surround=15 --audio-channels=4 media.avi``
|
||||
Would add surround sound decoding with 15 ms delay for the sound to
|
||||
the rear speakers.
|
||||
|
||||
``delay[=[ch1,ch2,...]]``
|
||||
Delays the sound to the loudspeakers such that the sound from the
|
||||
different channels arrives at the listening position simultaneously. It is
|
||||
only useful if you have more than 2 loudspeakers.
|
||||
|
||||
``[ch1,ch2,...]``
|
||||
The delay in ms that should be imposed on each channel (floating point
|
||||
number between 0 and 1000).
|
||||
|
||||
To calculate the required delay for the different channels, do as follows:
|
||||
|
||||
1. Measure the distance to the loudspeakers in meters in relation to your
|
||||
listening position, giving you the distances s1 to s5 (for a 5.1
|
||||
system). There is no point in compensating for the subwoofer (you will
|
||||
not hear the difference anyway).
|
||||
|
||||
2. Subtract the distances s1 to s5 from the maximum distance, i.e.
|
||||
``s[i] = max(s) - s[i]; i = 1...5``.
|
||||
|
||||
3. Calculate the required delays in ms as ``d[i] = 1000*s[i]/342; i =
|
||||
1...5``.
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``mpv --af=delay=[10.5,10.5,0,0,7,0] media.avi``
|
||||
Would delay front left and right by 10.5 ms, the two rear channels
|
||||
and the subwoofer by 0 ms and the center channel by 7 ms.
|
||||
|
||||
``export=mmapped_file:nsamples]``
|
||||
Exports the incoming signal to other processes using memory mapping
|
||||
(``mmap()``). Memory mapped areas contain a header::
|
||||
|
||||
int nch /* number of channels */
|
||||
int size /* buffer size */
|
||||
unsigned long long counter /* Used to keep sync, updated every time
|
||||
new data is exported. */
|
||||
|
||||
The rest is payload (non-interleaved) 16-bit data.
|
||||
|
||||
``<mmapped_file>``
|
||||
File to map data to (required)
|
||||
``<nsamples>``
|
||||
number of samples per channel (default: 512).
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``mpv --af=export=/tmp/mpv-af_export:1024 media.avi``
|
||||
Would export 1024 samples per channel to ``/tmp/mpv-af_export``.
|
||||
|
||||
``extrastereo[=mul]``
|
||||
(Linearly) increases the difference between left and right channels which
|
||||
adds some sort of "live" effect to playback.
|
||||
|
||||
``<mul>``
|
||||
Sets the difference coefficient (default: 2.5). 0.0 means mono sound
|
||||
(average of both channels), with 1.0 sound will be unchanged, with
|
||||
-1.0 left and right channels will be swapped.
|
||||
|
||||
``drc[=method:target]``
|
||||
Applies dynamic range compression. This maximizes the volume by compressing
|
||||
the audio signal's dynamic range. (Formerly called ``volnorm``.)
|
||||
|
||||
``<method>``
|
||||
Sets the used method.
|
||||
|
||||
1
|
||||
Use a single sample to smooth the variations via the standard
|
||||
weighted mean over past samples (default).
|
||||
2
|
||||
Use several samples to smooth the variations via the standard
|
||||
weighted mean over past samples.
|
||||
|
||||
``<target>``
|
||||
Sets the target amplitude as a fraction of the maximum for the sample
|
||||
type (default: 0.25).
|
||||
|
||||
.. note::
|
||||
|
||||
This filter can cause distortion with audio signals that have a very
|
||||
large dynamic range.
|
||||
|
||||
``ladspa=file:label:[<control0>,<control1>,...]``
|
||||
Load a LADSPA (Linux Audio Developer's Simple Plugin API) plugin. This
|
||||
filter is reentrant, so multiple LADSPA plugins can be used at once.
|
||||
|
||||
``<file>``
|
||||
Specifies the LADSPA plugin library file.
|
||||
|
||||
.. note::
|
||||
|
||||
See also the note about the ``LADSPA_PATH`` variable in the
|
||||
`ENVIRONMENT VARIABLES`_ section.
|
||||
``<label>``
|
||||
Specifies the filter within the library. Some libraries contain only
|
||||
one filter, but others contain many of them. Entering 'help' here
|
||||
will list all available filters within the specified library, which
|
||||
eliminates the use of 'listplugins' from the LADSPA SDK.
|
||||
``[<control0>,<control1>,...]``
|
||||
Controls are zero or more ``,`` separated floating point values that
|
||||
determine the behavior of the loaded plugin (for example delay,
|
||||
threshold or gain).
|
||||
In verbose mode (add ``-v`` to the mpv command line), all
|
||||
available controls and their valid ranges are printed. This eliminates
|
||||
the use of 'analyseplugin' from the LADSPA SDK.
|
||||
Note that ``,`` is already used by the option parser to separate
|
||||
filters, so you must quote the list of values with ``[...]`` or
|
||||
similar.
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``mpv --af=ladspa='/usr/lib/ladspa/delay.so':delay_5s:[0.5,0.2] media.avi``
|
||||
Does something.
|
||||
|
||||
``karaoke``
|
||||
Simple voice removal filter exploiting the fact that voice is usually
|
||||
recorded with mono gear and later 'center' mixed onto the final audio
|
||||
stream. Beware that this filter will turn your signal into mono. Works
|
||||
well for 2 channel tracks; do not bother trying it on anything but 2
|
||||
channel stereo.
|
||||
|
||||
``scaletempo[=option1:option2:...]``
|
||||
Scales audio tempo without altering pitch, optionally synced to playback
|
||||
@@ -338,10 +564,9 @@ Available filters are:
|
||||
Scale tempo in sync with speed (default).
|
||||
pitch
|
||||
Reverses effect of filter. Scales pitch without altering tempo.
|
||||
Add this to your ``input.conf`` to step by musical semi-tones::
|
||||
|
||||
[ multiply speed 0.9438743126816935
|
||||
] multiply speed 1.059463094352953
|
||||
Add ``[ speed_mult 0.9438743126816935`` and ``] speed_mult
|
||||
1.059463094352953`` to your ``input.conf`` to step by musical
|
||||
semi-tones.
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -365,36 +590,15 @@ Available filters are:
|
||||
``mpv --af=scaletempo=stride=30:overlap=.50:search=10 media.ogg``
|
||||
Would tweak the quality and performance parameters.
|
||||
|
||||
``mpv --af=format=float,scaletempo media.ogg``
|
||||
Would make scaletempo use float code. Maybe faster on some
|
||||
platforms.
|
||||
|
||||
``mpv --af=scaletempo=scale=1.2:speed=pitch audio.ogg``
|
||||
Would play media at 1.2x normal speed, with audio at normal pitch.
|
||||
Changing playback speed would change pitch, leaving audio tempo at
|
||||
1.2x.
|
||||
|
||||
``rubberband``
|
||||
High quality pitch correction with librubberband. This can be used in place
|
||||
of ``scaletempo``, and will be used to adjust audio pitch when playing
|
||||
at speed different from normal. It can also be used to adjust audio pitch
|
||||
without changing playback speed.
|
||||
|
||||
``<pitch-scale>``
|
||||
Sets the pitch scaling factor. Frequencies are multiplied by this value.
|
||||
|
||||
This filter has a number of additional sub-options. You can list them with
|
||||
``mpv --af=rubberband=help``. This will also show the default values
|
||||
for each option. The options are not documented here, because they are
|
||||
merely passed to librubberband. Look at the librubberband documentation
|
||||
to learn what each option does:
|
||||
http://breakfastquay.com/rubberband/code-doc/classRubberBand_1_1RubberBandStretcher.html
|
||||
(The mapping of the mpv rubberband filter sub-option names and values to
|
||||
those of librubberband follows a simple pattern: ``"Option" + Name + Value``.)
|
||||
|
||||
This filter supports the following ``af-command`` commands:
|
||||
|
||||
``set-pitch``
|
||||
Set the ``<pitch-scale>`` argument dynamically. This can be used to
|
||||
change the playback pitch at runtime. Note that speed is controlled
|
||||
using the standard ``speed`` property, not ``af-command``.
|
||||
|
||||
``lavfi=graph``
|
||||
Filter audio using FFmpeg's libavfilter.
|
||||
|
||||
@@ -409,3 +613,4 @@ Available filters are:
|
||||
|
||||
``o=<string>``
|
||||
AVOptions.
|
||||
|
||||
+146
-95
@@ -4,74 +4,109 @@ AUDIO OUTPUT DRIVERS
|
||||
Audio output drivers are interfaces to different audio output facilities. The
|
||||
syntax is:
|
||||
|
||||
``--ao=<driver1,driver2,...[,]>``
|
||||
``--ao=<driver1[:suboption1[=value]:...],driver2,...[,]>``
|
||||
Specify a priority list of audio output drivers to be used.
|
||||
|
||||
If the list has a trailing ',', mpv will fall back on drivers not contained
|
||||
in the list.
|
||||
in the list. Suboptions are optional and can mostly be omitted.
|
||||
|
||||
You can also set defaults for each driver. The defaults are applied before the
|
||||
normal driver parameters.
|
||||
|
||||
``--ao-defaults=<driver1[:parameter1:parameter2:...],driver2,...>``
|
||||
Set defaults for each driver.
|
||||
|
||||
.. note::
|
||||
|
||||
See ``--ao=help`` for a list of compiled-in audio output drivers. The
|
||||
driver ``--ao=alsa`` is preferred. ``--ao=pulse`` is preferred on systems
|
||||
where PulseAudio is used. On BSD systems, ``--ao=oss`` or ``--ao=sndio``
|
||||
may work (the latter being experimental).
|
||||
where PulseAudio is used. On Windows, ``--ao=wasapi`` is preferred,
|
||||
though it might cause trouble sometimes, in which case ``--ao=dsound``
|
||||
should be used. On BSD systems, ``--ao=oss`` or `--ao=sndio`` may work
|
||||
(the latter being experimental). On OS X systems, use ``--ao=coreaudio``.
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
- ``--ao=alsa,oss,`` Try the ALSA driver, then the OSS driver, then others.
|
||||
- ``--ao=alsa:no-block:device=[hw:0,3]`` Sets noblock-mode and the
|
||||
device-name as first card, fourth device.
|
||||
|
||||
Available audio output drivers are:
|
||||
|
||||
``alsa`` (Linux only)
|
||||
ALSA audio output driver
|
||||
|
||||
See `ALSA audio output options`_ for options specific to this AO.
|
||||
``device=<device>``
|
||||
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
|
||||
"spdif" device, unless you really know how to set it correctly.
|
||||
``no-block``
|
||||
Sets noblock-mode.
|
||||
``resample=yes``
|
||||
Enable ALSA resampling plugin. (This is disabled by default, because
|
||||
some drivers report incorrect audio delay in some cases.)
|
||||
``mixer-device=<device>``
|
||||
Set the mixer device used with ``--no-softvol`` (default: ``default``).
|
||||
``mixer-name=<name>``
|
||||
Set the name of the mixer element (default: ``Master``). This is for
|
||||
example ``PCM`` or ``Master``.
|
||||
``mixer-index=<number>``
|
||||
Set the index of the mixer channel (default: 0). Consider the output of
|
||||
"``amixer scontrols``", then the index is the number that follows the
|
||||
name of the element.
|
||||
``non-interleaved``
|
||||
Allow output of non-interleaved formats (if the audio decoder uses
|
||||
this format). Currently disabled by default, because some popular
|
||||
ALSA plugins are utterly broken with non-interleaved formats.
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
To get multichannel/surround audio, use ``--audio-channels=auto``. The
|
||||
default for this option is ``auto-safe``, which makes this audio otuput
|
||||
explicitly reject multichannel output, as there is no way to detect
|
||||
whether a certain channel layout is actually supported.
|
||||
MPlayer and mplayer2 required you to replace any ',' with '.' and
|
||||
any ':' with '=' in the ALSA device name. mpv does not do this anymore.
|
||||
Instead, quote the device name:
|
||||
|
||||
You can also try `using the upmix plugin <http://git.io/vfuAy>`_.
|
||||
This setup enables multichannel audio on the ``default`` device
|
||||
with automatic upmixing with shared access, so playing stereo
|
||||
and multichannel audio at the same time will work as expected.
|
||||
``--ao=alsa:device=[plug:surround50]``
|
||||
|
||||
Note that the ``[`` and ``]`` simply quote the device name. With some
|
||||
shells (like zsh), you have to quote the option string to prevent the
|
||||
shell from interpreting the brackets instead of passing them to mpv.
|
||||
|
||||
``oss``
|
||||
OSS audio output driver
|
||||
|
||||
The following global options are supported by this audio output:
|
||||
|
||||
``--oss-mixer-device``
|
||||
``<dsp-device>``
|
||||
Sets the audio output device (default: ``/dev/dsp``).
|
||||
``<mixer-device>``
|
||||
Sets the audio mixer device (default: ``/dev/mixer``).
|
||||
``--oss-mixer-channel``
|
||||
``<mixer-channel>``
|
||||
Sets the audio mixer channel (default: ``pcm``). Other valid values
|
||||
include **vol, pcm, line**. For a complete list of options look for
|
||||
``SOUND_DEVICE_NAMES`` in ``/usr/include/linux/soundcard.h``.
|
||||
|
||||
``jack``
|
||||
JACK (Jack Audio Connection Kit) audio output driver.
|
||||
JACK (Jack Audio Connection Kit) audio output driver
|
||||
|
||||
The following global options are supported by this audio output:
|
||||
|
||||
``--jack-port=<name>``
|
||||
``port=<name>``
|
||||
Connects to the ports with the given name (default: physical ports).
|
||||
``--jack-name=<client>``
|
||||
``name=<client>``
|
||||
Client name that is passed to JACK (default: ``mpv``). Useful
|
||||
if you want to have certain connections established automatically.
|
||||
``--jack-autostart=<yes|no>``
|
||||
``(no-)autostart``
|
||||
Automatically start jackd if necessary (default: disabled). Note that
|
||||
this tends to be unreliable and will flood stdout with server messages.
|
||||
``--jack-connect=<yes|no>``
|
||||
``(no-)connect``
|
||||
Automatically create connections to output ports (default: enabled).
|
||||
When enabled, the maximum number of output channels will be limited to
|
||||
the number of available output ports.
|
||||
``--jack-std-channel-layout=<waveext|any>``
|
||||
Select the standard channel layout (default: waveext). JACK itself has no
|
||||
``std-channel-layout=alsa|waveext|any``
|
||||
Select the standard channel layout (default: alsa). JACK itself has no
|
||||
notion of channel layouts (i.e. assigning which speaker a given
|
||||
channel is supposed to map to) - it just takes whatever the application
|
||||
outputs, and reroutes it to whatever the user defines. This means the
|
||||
user and the application are in charge of dealing with the channel
|
||||
layout. ``waveext`` uses WAVE_FORMAT_EXTENSIBLE order, which, even
|
||||
layout. ``alsa`` uses the old MPlayer layout, which is inspired by
|
||||
ALSA's standard layouts. In this mode, ao_jack will refuse to play 3
|
||||
or 7 channels (because these do not really have a defined meaning in
|
||||
MPlayer). ``waveext`` uses WAVE_FORMAT_EXTENSIBLE order, which, even
|
||||
though it was defined by Microsoft, is the standard on many systems.
|
||||
The value ``any`` makes JACK accept whatever comes from the audio
|
||||
filter chain, regardless of channel layout and without reordering. This
|
||||
@@ -79,36 +114,25 @@ Available audio output drivers are:
|
||||
with fixed setups.
|
||||
|
||||
``coreaudio`` (Mac OS X only)
|
||||
Native Mac OS X audio output driver using AudioUnits and the CoreAudio
|
||||
Native Mac OS X audio output driver using the AudioUnits and the CoreAudio
|
||||
sound server.
|
||||
|
||||
Automatically redirects to ``coreaudio_exclusive`` when playing compressed
|
||||
formats.
|
||||
``device_id=<id>``
|
||||
ID of output device to use (0 = default device)
|
||||
``help``
|
||||
List all available output devices with their IDs.
|
||||
|
||||
The following global options are supported by this audio output:
|
||||
|
||||
``--coreaudio-change-physical-format=<yes|no>``
|
||||
Change the physical format to one similar to the requested audio format
|
||||
(default: no). This has the advantage that multichannel audio output
|
||||
will actually work. The disadvantage is that it will change the
|
||||
system-wide audio settings. This is equivalent to changing the ``Format``
|
||||
setting in the ``Audio Devices`` dialog in the ``Audio MIDI Setup``
|
||||
utility. Note that this does not affect the selected speaker setup.
|
||||
|
||||
``--coreaudio-spdif-hack=<yes|no>``
|
||||
Try to pass through AC3/DTS data as PCM. This is useful for drivers
|
||||
which do not report AC3 support. It converts the AC3 data to float,
|
||||
and assumes the driver will do the inverse conversion, which means
|
||||
a typical A/V receiver will pick it up as compressed IEC framed AC3
|
||||
stream, ignoring that it's marked as PCM. This disables normal AC3
|
||||
passthrough (even if the device reports it as supported). Use with
|
||||
extreme care.
|
||||
|
||||
|
||||
``coreaudio_exclusive`` (Mac OS X only)
|
||||
``coreaudio_device`` (Mac OS X only)
|
||||
Native Mac OS X audio output driver using direct device access and
|
||||
exclusive mode (bypasses the sound server).
|
||||
|
||||
Supports only compressed formats (AC3 and DTS).
|
||||
|
||||
``device_id=<id>``
|
||||
ID of output device to use (0 = default device)
|
||||
``help``
|
||||
List all available output devices with their IDs.
|
||||
|
||||
``openal``
|
||||
Experimental OpenAL audio output driver
|
||||
|
||||
@@ -118,28 +142,44 @@ Available audio output drivers are:
|
||||
``pulse``
|
||||
PulseAudio audio output driver
|
||||
|
||||
The following global options are supported by this audio output:
|
||||
``[<host>][:<output sink>]``
|
||||
Specify the host and optionally output sink to use. An empty <host>
|
||||
string uses a local connection, "localhost" uses network transfer
|
||||
(most likely not what you want).
|
||||
|
||||
``--pulse-host=<host>``
|
||||
Specify the host to use. An empty <host> string uses a local connection,
|
||||
"localhost" uses network transfer (most likely not what you want).
|
||||
|
||||
``--pulse-buffer=<1-2000|native>``
|
||||
``buffer=<1-2000|native>``
|
||||
Set the audio buffer size in milliseconds. A higher value buffers
|
||||
more data, and has a lower probability of buffer underruns. A smaller
|
||||
value makes the audio stream react faster, e.g. to playback speed
|
||||
changes. Default: 250.
|
||||
|
||||
``--pulse-latency-hacks=<yes|no>``
|
||||
Enable hacks to workaround PulseAudio timing bugs (default: no). If
|
||||
``latency-hacks=<yes|no>``
|
||||
Enable hacks to workaround PulseAudio timing bugs (default: yes). If
|
||||
enabled, mpv will do elaborate latency calculations on its own. If
|
||||
disabled, it will use PulseAudio automatically updated timing
|
||||
information. Disabling this might help with e.g. networked audio or
|
||||
some plugins, while enabling it might help in some unknown situations
|
||||
(it used to be required to get good behavior on old PulseAudio versions).
|
||||
information. Disabling this might help with e.g. networked audio.
|
||||
|
||||
If you have stuttering video when using pulse, try to enable this
|
||||
option. (Or try to update PulseAudio.)
|
||||
``portaudio``
|
||||
PortAudio audio output driver. This works on all platforms, and has
|
||||
extensive MS Windows support.
|
||||
|
||||
.. note:: This driver is not very useful. It was added in the hope of
|
||||
providing portable audio API across all platforms, but turned
|
||||
out semi-broken and underfeatured.
|
||||
|
||||
``device``
|
||||
Specify the subdevice to use. Giving ``help`` as device name lists all
|
||||
devices found by PortAudio. Devices can be given as numeric values,
|
||||
starting from ``1``.
|
||||
|
||||
``dsound`` (Windows only)
|
||||
DirectX DirectSound audio output driver
|
||||
|
||||
.. note:: This driver is for compatibility with old systems.
|
||||
|
||||
``device=<devicenum>``
|
||||
Sets the device number to use. Playing a file with ``-v`` will show a
|
||||
list of available devices.
|
||||
|
||||
``sdl``
|
||||
SDL 1.2+ audio output driver. Should work on any platform supported by SDL
|
||||
@@ -150,70 +190,53 @@ Available audio output drivers are:
|
||||
environments, such as systems where none of the other drivers
|
||||
are available.
|
||||
|
||||
The following global options are supported by this audio output:
|
||||
|
||||
``--sdl-buflen=<length>``
|
||||
``buflen=<length>``
|
||||
Sets the audio buffer length in seconds. Is used only as a hint by the
|
||||
sound system. Playing a file with ``-v`` will show the requested and
|
||||
obtained exact buffer size. A value of 0 selects the sound system
|
||||
default.
|
||||
|
||||
``--sdl-bufcnt=<count>``
|
||||
``bufcnt=<count>``
|
||||
Sets the number of extra audio buffers in mpv. Usually needs not be
|
||||
changed.
|
||||
|
||||
``null``
|
||||
Produces no audio output but maintains video playback speed. You can use
|
||||
``--ao=null --ao-null-untimed`` for benchmarking.
|
||||
Produces no audio output but maintains video playback speed. Use
|
||||
``--ao=null:untimed`` for benchmarking.
|
||||
|
||||
The following global options are supported by this audio output:
|
||||
|
||||
``--ao-null-untimed``
|
||||
``untimed``
|
||||
Do not simulate timing of a perfect audio device. This means audio
|
||||
decoding will go as fast as possible, instead of timing it to the
|
||||
system clock.
|
||||
|
||||
``--ao-null-buffer``
|
||||
``buffer``
|
||||
Simulated buffer length in seconds.
|
||||
|
||||
``--ao-null-outburst``
|
||||
``outburst``
|
||||
Simulated chunk size in samples.
|
||||
|
||||
``--ao-null-speed``
|
||||
``speed``
|
||||
Simulated audio playback speed as a multiplier. Usually, a real audio
|
||||
device will not go exactly as fast as the system clock. It will deviate
|
||||
just a little, and this option helps to simulate this.
|
||||
just a little, and this option helps simulating this.
|
||||
|
||||
``--ao-null-latency``
|
||||
``latency``
|
||||
Simulated device latency. This is additional to EOF.
|
||||
|
||||
``--ao-null-broken-eof``
|
||||
``broken-eof``
|
||||
Simulate broken audio drivers, which always add the fixed device
|
||||
latency to the reported audio playback position.
|
||||
|
||||
``--ao-null-broken-delay``
|
||||
Simulate broken audio drivers, which don't report latency correctly.
|
||||
|
||||
``--ao-null-channel-layouts``
|
||||
If not empty, this is a ``,`` separated list of channel layouts the
|
||||
AO allows. This can be used to test channel layout selection.
|
||||
|
||||
``pcm``
|
||||
Raw PCM/WAVE file writer audio output
|
||||
|
||||
The following global options are supported by this audio output:
|
||||
|
||||
``--ao-pcm-waveheader=<yes|no>``
|
||||
``(no-)waveheader``
|
||||
Include or do not include the WAVE header (default: included). When
|
||||
not included, raw PCM will be generated.
|
||||
``--ao-pcm-file=<filename>``
|
||||
``file=<filename>``
|
||||
Write the sound to ``<filename>`` instead of the default
|
||||
``audiodump.wav``. If ``no-waveheader`` is specified, the default is
|
||||
``audiodump.pcm``.
|
||||
``--ao-pcm-append=<yes|no>``
|
||||
Append to the file, instead of overwriting it. Always use this with the
|
||||
``no-waveheader`` option - with ``waveheader`` it's broken, because
|
||||
it will write a WAVE header every time the file is opened.
|
||||
|
||||
``rsound``
|
||||
Audio output to an RSound daemon
|
||||
@@ -222,6 +245,14 @@ Available audio output drivers are:
|
||||
confused with RoarAudio, which is something completely
|
||||
different.
|
||||
|
||||
``host=<name/path>``
|
||||
Set the address of the server (default: localhost). Can be either a
|
||||
network hostname for TCP connections or a Unix domain socket path
|
||||
starting with '/'.
|
||||
``port=<number>``
|
||||
Set the TCP port used for connecting to the server (default: 12345).
|
||||
Not used if connecting to a Unix domain socket.
|
||||
|
||||
``sndio``
|
||||
Audio output to the OpenBSD sndio sound system
|
||||
|
||||
@@ -230,5 +261,25 @@ Available audio output drivers are:
|
||||
(Note: only supports mono, stereo, 4.0, 5.1 and 7.1 channel
|
||||
layouts.)
|
||||
|
||||
``device=<device>``
|
||||
sndio device to use (default: ``$AUDIODEVICE``, resp. ``snd0``).
|
||||
|
||||
``wasapi``
|
||||
Audio output to the Windows Audio Session API.
|
||||
|
||||
``device=<id>``
|
||||
Uses the requested endpoint instead of the system's default audio
|
||||
endpoint. Both the number and the ID String are valid; the ID String
|
||||
is guaranteed to not change unless the driver is uninstalled.
|
||||
|
||||
Also supports searching active devices by name. If more than one
|
||||
device matches the name, refuses loading it.
|
||||
|
||||
To get a list of the valid devices, give ``help`` as the id. The
|
||||
list is the same as the ``list`` suboption, but stops the player
|
||||
initialization.
|
||||
``exclusive``
|
||||
Requests exclusive, direct hardware access. By definition prevents
|
||||
sound playback of any other program until mpv exits.
|
||||
``list``
|
||||
Lists all audio endpoints (output devices) present in the system.
|
||||
+380
-15
@@ -1,18 +1,383 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
CHANGES FROM OTHER VERSIONS OF MPLAYER
|
||||
======================================
|
||||
|
||||
There is no real changelog, but you can look at the following things:
|
||||
**mpv** is based on mplayer2, which in turn is based on the original MPlayer
|
||||
(also called mplayer, mplayer-svn, mplayer1). Many changes have been made, a
|
||||
large part of which is incompatible or completely changes how the player
|
||||
behaves. Although there are still many similarities to its ancestors, **mpv**
|
||||
should generally be treated as a completely different program.
|
||||
|
||||
* The release changelog, which should contain most user-visible changes,
|
||||
including new features and bug fixes:
|
||||
.. note::
|
||||
These lists are incomplete.
|
||||
|
||||
https://github.com/mpv-player/mpv/releases
|
||||
* The git log, which is the "real" changelog
|
||||
* The files ``client-api-changes.rst`` and ``interface-changes.rst`` in the
|
||||
``DOCS`` sub directoryon the git repository, which document API and user
|
||||
interface changes (the latter usually documents breaking changes only, rather
|
||||
than additions).
|
||||
* The file ``mplayer-changes.rst`` in the ``DOCS`` sub directory on the git
|
||||
repository, which used to be in place of this section. It documents some
|
||||
changes that happened since mplayer2 forked off MPlayer. (Not updated
|
||||
anymore.)
|
||||
General Changes for MPlayer to mpv
|
||||
----------------------------------
|
||||
|
||||
* Switch to GPLv2+. (Technically speaking, MPlayer as a whole seems to be
|
||||
GPLv2-only, while mplayer2 is GPLv3+ - see ``Copyright`` file for details.)
|
||||
* Removal of the internal GUI, MEncoder, OSD menu, video kernel drivers for
|
||||
Linux 2.4 (including VIDIX)
|
||||
* Large internal cleanups
|
||||
* Removal of support for dead platforms
|
||||
* New build system
|
||||
* No embedded copy of FFmpeg and other libraries
|
||||
* Better pause handling (do not unpause on a command)
|
||||
* Better MKV support (such as ordered chapters)
|
||||
* vo_vdpau improvements
|
||||
* Precise seeking support
|
||||
* Native OpenGL backend for OS X
|
||||
* General OS X improvements
|
||||
* Improvements in audio/video sync handling
|
||||
* Cleaned up terminal output
|
||||
* Gapless audio support (``--gapless-audio``)
|
||||
* Improved responsiveness on user input
|
||||
* Support for modifier keys (alt, shift, ctrl) in input.conf
|
||||
* OSS4 volume control
|
||||
* More correct color reproduction (color matrix generation)
|
||||
* Use libass for subtitle rendering by default (better quality)
|
||||
* Generally preferring FFmpeg/Libav over internal demuxers and decoders
|
||||
* Improvements when playing multiple files (``--fixed-vo``)
|
||||
* Screenshot improvements (instant screenshots without 1-frame delay, allow
|
||||
taking screenshots even with hardware decoding)
|
||||
* Improved support for PulseAudio
|
||||
* Generally improved MS Windows support (dealing with Unicode file names,
|
||||
improved ``--vo=direct3d``, improved window handling)
|
||||
* Better OSD rendering (using libass). This has full Unicode support, and
|
||||
languages like Arabic should be better supported.
|
||||
* Cleaned up terminal output (nicer status line, less useless noise)
|
||||
* Support for playing URLs of popular streaming sites directly
|
||||
(e.g. ``mpv https://www.youtube.com/watch?v=...``)
|
||||
* Improved OpenGL output (``--vo=opengl-hq``)
|
||||
* Make ``--softvol`` default (**mpv** is not a mixer control panel)
|
||||
* Improved support for .cue files
|
||||
* Screenshot improvements (can save screenshots as JPEG or PNG, configurable
|
||||
file names, support for taking screenshots with or without subtitles - the
|
||||
``screenshot`` video filter is not needed anymore, and should not be put
|
||||
into the mpv config file)
|
||||
* Removal of teletext support
|
||||
* Removal of most built-in demuxers, using libavformat instead
|
||||
* Removal of built-in network support, using libavformat instead (also,
|
||||
support https via libavformat)
|
||||
* Replace image VOs (``--vo=jpeg`` etc.) with ``--vo=image``
|
||||
* Do not lose settings when playing a new file in the same player instance
|
||||
* New location for config files, new name for the binary.
|
||||
* Slave mode compatibility broken (see below)
|
||||
* Encoding functionality (replacement for MEncoder, see ``DOCS/encoding.rst``)
|
||||
* Remove ``--vo=gif89a``, ``--vo=md5sum``, ``--vo=yuv4mpeg``, as encoding can
|
||||
handle these use cases. For yuv4mpeg, for example, use:
|
||||
``mpv input.mkv -o output.y4m --no-audio --oautofps --oneverdrop``.
|
||||
* Image subtitles (DVDs etc.) are rendered in color and use more correct
|
||||
positioning (color can be disabled with ``--sub-gray``)
|
||||
* Wayland support
|
||||
* Support for precise scrolling which scales the parameter of commands. If the
|
||||
input doesn't support precise scrolling the scale factor stays 1.
|
||||
* OS X: Cocoa event loop is independent from MPlayer's event loop, so user
|
||||
actions like accessing menus and live resizing do not block the playback.
|
||||
* OS X: Apple Remote support.
|
||||
* OS X: Media Keys support.
|
||||
* Windows: Added WASAPI audio output.
|
||||
* New OSD bar with chapter marks and not positioned in the middle of the video
|
||||
(though this can be customized with the ``--osd-bar-align-y`` option).
|
||||
* Allow customizing whether a key binding for seeking shows the video time, the
|
||||
OSD bar, or nothing (see section `Input Command Prefixes`_).
|
||||
* Display list of chapters and audio/subtitle tracks on OSD (see section
|
||||
`Properties`_).
|
||||
* ``--keep-open`` option to stop the player from closing the window and
|
||||
exiting after playback ends.
|
||||
* Re-enable screensaver while the player is paused.
|
||||
* Matroska edition switching at runtime.
|
||||
* Support for libavfilter (for video->video and audio->audio). This allows
|
||||
using most of FFmpeg's filters, which improve greatly on the old MPlayer
|
||||
filters in features, performance, and correctness.
|
||||
* Improved downmixing and output of surround audio. Instead of using hardcoded
|
||||
pan filters to do remixing, use libavresample. Channel maps are used to
|
||||
identify the channel layout, so e.g. ``3.0`` and ``2.1`` audio can be
|
||||
distinguished.
|
||||
* Allow resuming playback at a later point with ``Shift+q``, also see
|
||||
``quit_watch_later`` input command.
|
||||
* Support mapping multiple commands to one key.
|
||||
* Allow changing/adjusting video filters at runtime. (This is also used to make
|
||||
the ``D`` key insert vf_yadif if deinterlacing is not supported otherwise.)
|
||||
* Native VAAPI support
|
||||
* OS X: VDA support using libavcodec hwaccel API instead of FFmpeg's decoder. Up
|
||||
to 2-2.5x reduction in CPU usage.
|
||||
* Make hardware decoding in general work with the ``opengl`` video output.
|
||||
* Lua scripting (see `LUA SCRIPTING`_)
|
||||
* A client API, that allows embedding **mpv** into applications
|
||||
(see ``libmpv/client.h`` in the sources)
|
||||
* General bug fixes and removal of long-standing issues
|
||||
* General code cleanups (including refactoring or rewrites of many parts)
|
||||
* Many more changes
|
||||
|
||||
Detailed Listing of User-visible Changes
|
||||
----------------------------------------
|
||||
|
||||
This listing is about changed command line switches, slave commands, and similar
|
||||
things. Completely removed features are not listed.
|
||||
|
||||
Command Line Switches
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* There is a new command line syntax, which is generally preferred over the old
|
||||
syntax. ``-optname optvalue`` becomes ``--optname=optvalue``.
|
||||
|
||||
The old syntax will not be removed. However, the new syntax is mentioned in
|
||||
all documentation and so on, and unlike the old syntax is not ambiguous,
|
||||
so it is a good thing to know about this change.
|
||||
* In general, negating switches like ``-noopt`` now have to be written as
|
||||
``-no-opt`` or ``--no-opt``.
|
||||
* Per-file options are not the default anymore. You can explicitly specify
|
||||
file-local options. See ``Usage`` section.
|
||||
* Many options have been renamed, removed or changed semantics. Some options
|
||||
that are required for a good playback experience with MPlayer are now
|
||||
superfluous or even worse than the defaults, so make sure to read the manual
|
||||
before trying to use your existing configuration with **mpv**.
|
||||
* Table of renamed/replaced switches:
|
||||
|
||||
=========================== ========================================
|
||||
Old New
|
||||
=========================== ========================================
|
||||
``-no<opt>`` ``--no-<opt>`` (add a dash)
|
||||
``-a52drc level`` ``--ad-lavc-ac3drc=level``
|
||||
``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)
|
||||
``-af volnorm`` ``--af=drc`` (renamed)
|
||||
``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``
|
||||
``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
|
||||
``-aspect`` ``--video-aspect``
|
||||
``-ass-bottom-margin`` ``--vf=sub=bottom:top``
|
||||
``-ass`` ``--sub-ass``
|
||||
``-audiofile-cache`` (removed; the main cache settings are used)
|
||||
``-audiofile`` ``--audio-file``
|
||||
``-benchmark`` ``--untimed`` (no stats)
|
||||
``-capture`` ``--stream-capture=<filename>``
|
||||
``-channels`` ``--audio-channels`` (changed semantics)
|
||||
``-cursor-autohide-delay`` ``--cursor-autohide``
|
||||
``-delay`` ``--audio-delay``
|
||||
``-dumpstream`` ``--stream-dump=<filename>``
|
||||
``-dvdangle`` ``--dvd-angle``
|
||||
``-endpos`` ``--length``
|
||||
``-font`` ``--osd-font``
|
||||
``-forcedsubsonly`` ``--sub-forced-only``
|
||||
``-forceidx`` ``--index``
|
||||
``-format`` ``--audio-format``
|
||||
``-fsmode-dontuse`` (removed)
|
||||
``-fstype`` ``--x11-netwm`` (changed semantics)
|
||||
``-hardframedrop`` ``--framedrop=hard``
|
||||
``-identify`` (removed; use TOOLS/mpv_identify.sh)
|
||||
``-idx`` ``--index``
|
||||
``-lavdopts ...`` ``--vd-lavc-...``
|
||||
``-lavfdopts`` ``--demuxer-lavf-...``
|
||||
``-lircconf`` ``--input-lirc-conf``
|
||||
``-loop 0`` ``--loop=inf``
|
||||
``-mixer-channel`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mixer`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mouse-movements`` ``--input-cursor``
|
||||
``-msgcolor`` ``--msg-color``
|
||||
``-msglevel`` ``--msg-level`` (changed semantics)
|
||||
``-msgmodule`` ``--msg-module``
|
||||
``-name`` ``--x11-name``
|
||||
``-noar`` ``--no-input-appleremote``
|
||||
``-noautosub`` ``--no-sub-auto``
|
||||
``-noconsolecontrols`` ``--no-input-terminal``
|
||||
``-nojoystick`` ``--no-input-joystick``
|
||||
``-nosound`` ``--no-audio``
|
||||
``-osdlevel`` ``--osd-level``
|
||||
``-panscanrange`` ``--video-zoom``, ``--video-pan-x/y``
|
||||
``-playing-msg`` ``--term-playing-msg``
|
||||
``-pp ...`` ``'--vf=pp=[...]'``
|
||||
``-pphelp`` ``--vf=pp:help``
|
||||
``-rawaudio ...`` ``--demuxer-rawaudio-...``
|
||||
``-rawvideo ...`` ``--demuxer-rawvideo-...``
|
||||
``-spugauss`` ``--sub-gauss``
|
||||
``-srate`` ``--audio-samplerate``
|
||||
``-ss`` ``--start``
|
||||
``-ssf <sub>`` ``--sws-...``
|
||||
``-stop-xscreensaver`` ``--stop-screensaver``
|
||||
``-sub-fuzziness`` ``--sub-auto``
|
||||
``-sub`` ``--sub-file``
|
||||
``-subcp`` ``--sub-codepage``
|
||||
``-subdelay`` ``--sub-delay``
|
||||
``-subfile`` ``--sub-file``
|
||||
``-subfont-*`` ``--sub-text-*``, ``--osd-*``
|
||||
``-subfont-text-scale`` ``--sub-scale``
|
||||
``-subfont`` ``--sub-text-font``
|
||||
``-subfps`` ``--sub-fps``
|
||||
``-subpos`` ``--sub-pos``
|
||||
``-sws`` ``--sws-scaler``
|
||||
``-tvscan`` ``--tv-scan``
|
||||
``-use-filename-title`` ``--title='${filename}'``
|
||||
``-vc ffh264vdpau`` (etc.) ``--hwdec=vdpau``
|
||||
``-vobsub`` ``--sub-file`` (pass the .idx file)
|
||||
``-x W``, ``-y H`` ``--geometry=WxH`` + ``--no-keepaspect``
|
||||
``-xineramascreen`` ``--screen`` (different values)
|
||||
``-xy W`` ``--autofit=W``
|
||||
``-zoom`` Inverse available as ``--video-unscaled``
|
||||
``dvdnav://`` ``dvdnav://menu``
|
||||
``dvd://1`` ``dvd://0`` (0-based offset)
|
||||
=========================== ========================================
|
||||
|
||||
.. note::
|
||||
|
||||
``-opt val`` becomes ``--opt=val``.
|
||||
|
||||
.. note::
|
||||
|
||||
Quite some video filters, video outputs, audio filters, audio outputs, had
|
||||
changes in their option parsing. These aren't mentioned in the table above.
|
||||
|
||||
Also, some video and audio filters have been removed, and you have to use
|
||||
libavfilter (using ``--vf=lavfi=[...]`` or ``--af=lavfi=[...]``) to get
|
||||
them back.
|
||||
|
||||
input.conf and Slave Commands
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Table of renamed input commands:
|
||||
|
||||
This lists only commands that are not always gracefully handled by the
|
||||
internal legacy translation layer. If an input.conf contains any legacy
|
||||
commands, a warning will be printed when starting the player. The warnings
|
||||
also show the replacement commands.
|
||||
|
||||
Properties containing ``_`` to separate words use ``-`` instead.
|
||||
|
||||
+--------------------------------+----------------------------------------+
|
||||
| Old | New |
|
||||
+================================+========================================+
|
||||
| ``pt_step 1 [0|1]`` | ``playlist_next [weak|force]`` |
|
||||
| | (translation layer cannot deal with |
|
||||
| | whitespace) |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``pt_step -1 [0|1]`` | ``playlist_prev [weak|force] (same)`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``switch_ratio [<ratio>]`` | ``set video-aspect <ratio>`` |
|
||||
| | |
|
||||
| | ``set video-aspect 0`` (reset aspect) |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``step_property_osd <prop>`` | ``cycle <prop> <step>`` (wraps), |
|
||||
| ``<step> <dir>`` | ``add <prop> <step>`` (clamps). |
|
||||
| | ``<dir>`` parameter unsupported. Use |
|
||||
| | a negative ``<step>`` instead. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``step_property <prop>`` | Prefix ``cycle`` or ``add`` with |
|
||||
| ``<step> <dir>`` | ``no-osd``: ``no-osd cycle <prop>`` |
|
||||
| | ``<step>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``osd_show_property_text`` | ``show_text <text>`` |
|
||||
| ``<text>`` | The property expansion format string |
|
||||
| | syntax slightly changed. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``osd_show_text`` | Now does the same as |
|
||||
| | ``osd_show_property_text``. Use the |
|
||||
| | ``raw`` prefix to disable property |
|
||||
| | expansion. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``show_tracks`` | ``show_text ${track-list}`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``show_chapters`` | ``show_text ${chapter-list}`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_start_scan`` | ``set tv-scan yes`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_channel <val>`` | ``set tv-channel <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_channel`` | ``cycle tv-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_set_channel <v1> <v2>`` | ``set dvb-channel <v1>-<v2>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_step_channel`` | ``cycle dvb-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_freq <val>`` | ``set tv-freq <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_freq`` | ``cycle tv-freq`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_norm <norm>`` | ``set tv-norm <norm>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_norm`` | ``cycle tv-norm`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
Due to lack of hardware and users using the TV/DVB/PVR features, and
|
||||
due to the need to cleanup the related command code, it's possible
|
||||
that the new commands are buggy or behave worse. This can be improved
|
||||
if testers are available. Otherwise, some of the TV code will be
|
||||
removed at some point.
|
||||
|
||||
Slave mode
|
||||
~~~~~~~~~~
|
||||
|
||||
* Slave mode was removed. A proper slave mode application needed tons of code
|
||||
and hacks to get
|
||||
it right. The main problem is that slave mode is a bad and incomplete
|
||||
interface, and to get around that, applications parsed output messages
|
||||
intended for users. It is hard to know which messages exactly are parsed by
|
||||
slave mode applications. This makes it virtually impossible to improve
|
||||
terminal output intended for users without possibly breaking something.
|
||||
|
||||
This is absolutely insane, and since initial improvements to **mpv** quickly
|
||||
made slave mode incompatible to most applications, it was removed as useless
|
||||
cruft. The client API (see below) is provided instead.
|
||||
|
||||
``--identify`` was replaced by the ``TOOLS/mpv_identify.sh`` wrapper script.
|
||||
|
||||
* For some time (until including release 0.4.x), mpv supported a
|
||||
``--slave-broken`` option. The following options are equivalent:
|
||||
|
||||
::
|
||||
|
||||
--input-file=/dev/stdin --input-terminal=no
|
||||
|
||||
|
||||
Assuming the system supports ``/dev/stdin``.
|
||||
|
||||
(The option was readded in 0.5.1 and sets exactly these options.)
|
||||
|
||||
* A JSON RPC protocol giving access to the client API is planned, but nothing
|
||||
has emerged yet.
|
||||
|
||||
* **mpv** also provides a client API, which can be used to embed the player
|
||||
by loading it as shared library. (See ``libmpv/client.h`` in the sources.)
|
||||
It might also be possible to implement a custom slave mode-like protocol
|
||||
using Lua scripting.
|
||||
|
||||
Policy for Removed Features
|
||||
---------------------------
|
||||
|
||||
**mpv** is in active development. If something is in the way of more important
|
||||
development (such as fixing bugs or implementing new features), we sometimes
|
||||
remove features. Usually this happens only with old features that either seem
|
||||
to be useless, or are not used by anyone. Often these are obscure, or
|
||||
"inherited", or were marked experimental, but never received any particular
|
||||
praise by any users.
|
||||
|
||||
Sometimes, features are replaced by something new. The new code will be either
|
||||
simpler or more powerful, but doesn't necessarily provide everything the old
|
||||
feature did.
|
||||
|
||||
We can not exclude that we accidentally remove features that are actually
|
||||
popular. Generally, we do not know how much a specific functionality is used.
|
||||
If you miss a feature and think it should be re-added, please open an issue
|
||||
on the mpv bug tracker. Hopefully, a solution can be found. Often, it turns
|
||||
out that re-adding something is not much of a problem, or that there are
|
||||
better alternatives.
|
||||
|
||||
Why this Fork?
|
||||
--------------
|
||||
|
||||
mplayer2 is practically dead, and mpv started out as a branch containing
|
||||
new/experimental development. (Some of it was merged right *after* the fork
|
||||
was made public, seemingly as an acknowledgment that development, or at
|
||||
least merging, should have been more active.)
|
||||
|
||||
MPlayer is focused on not breaking anything, but is stuck with a horrible
|
||||
codebase resistant to cleanup. (Unless you do what mpv did - merciless and
|
||||
consequent pruning of bad, old code.) Cleanup and keeping broken things
|
||||
conflict, so the kind of development mpv strives for can't be done within
|
||||
MPlayer due to clashing development policies.
|
||||
|
||||
Additionally, mplayer2 already had lots of changes over MPlayer, which would
|
||||
have needed to be backported to the MPlayer codebase. This would not only
|
||||
have been hard (several years of diverging development), but also would have
|
||||
been impossible due to the aforementioned MPlayer development policy.
|
||||
+5
-5
@@ -93,8 +93,8 @@ You can encode files from one format/codec to another using this facility.
|
||||
Completely empties the options list.
|
||||
|
||||
``--oafirst``
|
||||
Force the audio stream to become the first stream in the output.
|
||||
By default, the order is unspecified.
|
||||
Force the audio stream to become the first stream in the output. By default
|
||||
the order is unspecified.
|
||||
|
||||
``--ovc=<codec>``
|
||||
Specifies the output video codec. This can be a comma separated list of
|
||||
@@ -111,7 +111,7 @@ You can encode files from one format/codec to another using this facility.
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
``"--ovc=mpeg4 --ovcopts=qscale=5"``
|
||||
``"--ovc=mpeg4 --oacopts=qscale=5"``
|
||||
selects constant quantizer scale 5 for MPEG-4 encoding.
|
||||
|
||||
``"--ovc=libx264 --ovcopts=crf=23"``
|
||||
@@ -134,8 +134,8 @@ You can encode files from one format/codec to another using this facility.
|
||||
Completely empties the options list.
|
||||
|
||||
``--ovfirst``
|
||||
Force the video stream to become the first stream in the output.
|
||||
By default, the order is unspecified.
|
||||
Force the video stream to become the first stream in the output. By default
|
||||
the order is unspecified.
|
||||
|
||||
``--ocopyts``
|
||||
Copies input pts to the output video (not supported by some output
|
||||
|
||||
+320
-1288
File diff suppressed because it is too large.
Load diff
@@ -1,268 +0,0 @@
|
||||
JSON IPC
|
||||
========
|
||||
|
||||
mpv can be controlled by external programs using the JSON-based IPC protocol.
|
||||
It can be enabled by specifying the path to a unix socket or a named pipe using
|
||||
the option ``--input-ipc-server``. Clients can connect to this socket and send
|
||||
commands to the player or receive events from it.
|
||||
|
||||
.. warning::
|
||||
|
||||
This is not intended to be a secure network protocol. It is explicitly
|
||||
insecure: there is no authentication, no encryption, and the commands
|
||||
themselves are insecure too. For example, the ``run`` command is exposed,
|
||||
which can run arbitrary system commands. The use-case is controlling the
|
||||
player locally. This is not different from the MPlayer slave protocol.
|
||||
|
||||
Socat example
|
||||
-------------
|
||||
|
||||
You can use the ``socat`` tool to send commands (and receive replies) from the
|
||||
shell. Assuming mpv was started with:
|
||||
|
||||
::
|
||||
|
||||
mpv file.mkv --input-ipc-server=/tmp/mpvsocket
|
||||
|
||||
Then you can control it using socat:
|
||||
|
||||
::
|
||||
|
||||
> echo '{ "command": ["get_property", "playback-time"] }' | socat - /tmp/mpvsocket
|
||||
{"data":190.482000,"error":"success"}
|
||||
|
||||
In this case, socat copies data between stdin/stdout and the mpv socket
|
||||
connection.
|
||||
|
||||
See the ``--idle`` option how to make mpv start without exiting immediately or
|
||||
playing a file.
|
||||
|
||||
It's also possible to send input.conf style text-only commands:
|
||||
|
||||
::
|
||||
|
||||
> echo 'show-text ${playback-time}' | socat - /tmp/mpvsocket
|
||||
|
||||
But you won't get a reply over the socket. (This particular command shows the
|
||||
playback time on the player's OSD.)
|
||||
|
||||
Command Prompt example
|
||||
----------------------
|
||||
|
||||
Unfortunately, it's not as easy to test the IPC protocol on Windows, since
|
||||
Windows ports of socat (in Cygwin and MSYS2) don't understand named pipes. In
|
||||
the absence of a simple tool to send and receive from bidirectional pipes, the
|
||||
``echo`` command can be used to send commands, but not receive replies from the
|
||||
command prompt.
|
||||
|
||||
Assuming mpv was started with:
|
||||
|
||||
::
|
||||
|
||||
mpv file.mkv --input-ipc-server=\\.\pipe\mpvsocket
|
||||
|
||||
You can send commands from a command prompt:
|
||||
|
||||
::
|
||||
|
||||
echo show-text ${playback-time} >\\.\pipe\mpvsocket
|
||||
|
||||
To be able to simultaneously read and write from the IPC pipe, like on Linux,
|
||||
it's necessary to write an external program that uses overlapped file I/O (or
|
||||
some wrapper like .NET's NamedPipeClientStream.)
|
||||
|
||||
Protocol
|
||||
--------
|
||||
|
||||
Clients can execute commands on the player by sending JSON messages of the
|
||||
following form:
|
||||
|
||||
::
|
||||
|
||||
{ "command": ["command_name", "param1", "param2", ...] }
|
||||
|
||||
where ``command_name`` is the name of the command to be executed, followed by a
|
||||
list of parameters. Parameters must be formatted as native JSON values
|
||||
(integers, strings, booleans, ...). Every message **must** be terminated with
|
||||
``\n``. Additionally, ``\n`` must not appear anywhere inside the message. In
|
||||
practice this means that messages should be minified before being sent to mpv.
|
||||
|
||||
mpv will then send back a reply indicating whether the command was run
|
||||
correctly, and an additional field holding the command-specific return data (it
|
||||
can also be null).
|
||||
|
||||
::
|
||||
|
||||
{ "error": "success", "data": null }
|
||||
|
||||
mpv will also send events to clients with JSON messages of the following form:
|
||||
|
||||
::
|
||||
|
||||
{ "event": "event_name" }
|
||||
|
||||
where ``event_name`` is the name of the event. Additional event-specific fields
|
||||
can also be present. See `List of events`_ for a list of all supported events.
|
||||
|
||||
Because events can occur at any time, it may be difficult at times to determine
|
||||
which response goes with which command. Commands may optionally include a
|
||||
``request_id`` which, if provided in the command request, will be copied
|
||||
verbatim into the response. mpv does not intrepret the ``request_id`` in any
|
||||
way; it is solely for the use of the requester.
|
||||
|
||||
For example, this request:
|
||||
|
||||
::
|
||||
|
||||
{ "command": ["get_property", "time-pos"], "request_id": 100 }
|
||||
|
||||
Would generate this response:
|
||||
|
||||
::
|
||||
|
||||
{ "error": "success", "data": 1.468135, "request_id": 100 }
|
||||
|
||||
All commands, replies, and events are separated from each other with a line
|
||||
break character (``\n``).
|
||||
|
||||
If the first character (after skipping whitespace) is not ``{``, the command
|
||||
will be interpreted as non-JSON text command, as they are used in input.conf
|
||||
(or ``mpv_command_string()`` in the client API). Additionally, lines starting
|
||||
with ``#`` and empty lines are ignored.
|
||||
|
||||
Currently, embedded 0 bytes terminate the current line, but you should not
|
||||
rely on this.
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
In addition to the commands described in `List of Input Commands`_, a few
|
||||
extra commands can also be used as part of the protocol:
|
||||
|
||||
``client_name``
|
||||
Return the name of the client as string. This is the string ``ipc-N`` with
|
||||
N being an integer number.
|
||||
|
||||
``get_time_us``
|
||||
Return the current mpv internal time in microseconds as a number. This is
|
||||
basically the system time, with an arbitrary offset.
|
||||
|
||||
``get_property``
|
||||
Return the value of the given property. The value will be sent in the data
|
||||
field of the replay message.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
{ "command": ["get_property", "volume"] }
|
||||
{ "data": 50.0, "error": "success" }
|
||||
|
||||
``get_property_string``
|
||||
Like ``get_property``, but the resulting data will always be a string.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
{ "command": ["get_property_string", "volume"] }
|
||||
{ "data": "50.000000", "error": "success" }
|
||||
|
||||
``set_property``
|
||||
Set the given property to the given value. See `Properties`_ for more
|
||||
information about properties.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
{ "command": ["set_property", "pause", true] }
|
||||
{ "error": "success" }
|
||||
|
||||
``set_property_string``
|
||||
Like ``set_property``, but the argument value must be passed as string.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
{ "command": ["set_property_string", "pause", "yes"] }
|
||||
{ "error": "success" }
|
||||
|
||||
``observe_property``
|
||||
Watch a property for changes. If the given property is changed, then an
|
||||
event of type ``property-change`` will be generated
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
{ "command": ["observe_property", 1, "volume"] }
|
||||
{ "error": "success" }
|
||||
{ "event": "property-change", "id": 1, "data": 52.0, "name": "volume" }
|
||||
|
||||
.. warning::
|
||||
|
||||
If the connection is closed, the IPC client is destroyed internally,
|
||||
and the observed properties are unregistered. This happens for example
|
||||
when sending commands to a socket with separate ``socat`` invocations.
|
||||
This can make it seem like property observation does not work. You must
|
||||
keep the IPC connection open to make it work.
|
||||
|
||||
``observe_property_string``
|
||||
Like ``observe_property``, but the resulting data will always be a string.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
{ "command": ["observe_property_string", 1, "volume"] }
|
||||
{ "error": "success" }
|
||||
{ "event": "property-change", "id": 1, "data": "52.000000", "name": "volume" }
|
||||
|
||||
``unobserve_property``
|
||||
Undo ``observe_property`` or ``observe_property_string``. This requires the
|
||||
numeric id passed to the observed command as argument.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
{ "command": ["unobserve_property", 1] }
|
||||
{ "error": "success" }
|
||||
|
||||
``request_log_messages``
|
||||
Enable output of mpv log messages. They will be received as events. The
|
||||
parameter to this command is the log-level (see ``mpv_request_log_messages``
|
||||
C API function).
|
||||
|
||||
Log message output is meant for humans only (mostly for debugging).
|
||||
Attempting to retrieve information by parsing these messages will just
|
||||
lead to breakages with future mpv releases. Instead, make a feature request,
|
||||
and ask for a proper event that returns the information you need.
|
||||
|
||||
``enable_event``, ``disable_event``
|
||||
Enables or disables the named event. Mirrors the ``mpv_request_event`` C
|
||||
API function. If the string ``all`` is used instead of an event name, all
|
||||
events are enabled or disabled.
|
||||
|
||||
By default, most events are enabled, and there is not much use for this
|
||||
command.
|
||||
|
||||
``get_version``
|
||||
Returns the client API version the C API of the remote mpv instance
|
||||
provides.
|
||||
|
||||
See also: ``DOCS/client-api-changes.rst``.
|
||||
|
||||
UTF-8
|
||||
-----
|
||||
|
||||
Normally, all strings are in UTF-8. Sometimes it can happen that strings are
|
||||
in some broken encoding (often happens with file tags and such, and filenames
|
||||
on many Unixes are not required to be in UTF-8 either). This means that mpv
|
||||
sometimes sends invalid JSON. If that is a problem for the client application's
|
||||
parser, it should filter the raw data for invalid UTF-8 sequences and perform
|
||||
the desired replacement, before feeding the data to its JSON parser.
|
||||
|
||||
mpv will not attempt to construct invalid UTF-8 with broken escape sequences.
|
||||
@@ -1,337 +0,0 @@
|
||||
JAVASCRIPT
|
||||
==========
|
||||
|
||||
JavaScript support in mpv is near identical to its Lua support. Use this section
|
||||
as reference on differences and availability of APIs, but otherwise you should
|
||||
refer to the Lua documentation for API details and general scripting in mpv.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
JavaScript code which leaves fullscreen mode when the player is paused:
|
||||
|
||||
::
|
||||
|
||||
function on_pause_change(name, value) {
|
||||
if (value == true)
|
||||
mp.set_property("fullscreen", "no");
|
||||
}
|
||||
mp.observe_property("pause", "bool", on_pause_change);
|
||||
|
||||
|
||||
Similarities with Lua
|
||||
---------------------
|
||||
|
||||
mpv tries to load a script file as JavaScript if it has a ``.js`` extension, but
|
||||
otherwise, the documented Lua options, script directories, loading, etc apply to
|
||||
JavaScript files too.
|
||||
|
||||
Script initialization and lifecycle is the same as with Lua, and most of the Lua
|
||||
functions at the modules ``mp``, ``mp.utils`` and ``mp.msg`` are available to
|
||||
JavaScript with identical APIs - including running commands, getting/setting
|
||||
properties, registering events/key-bindings/property-changes/hooks, etc.
|
||||
|
||||
Differences from Lua
|
||||
--------------------
|
||||
|
||||
No need to load modules. ``mp``, ``mp.utils`` and ``mp.msg`` are preloaded, and
|
||||
you can use e.g. ``var cwd = mp.utils.getcwd();`` without prior setup.
|
||||
``mp.options`` is currently not implemented, but ``mp.get_opt(...)`` is.
|
||||
|
||||
Errors are slightly different. Where the Lua APIs return ``nil`` for error,
|
||||
the JavaScript ones return ``undefined``. Where Lua returns ``something, error``
|
||||
JavaScript returns only ``something`` - and makes ``error`` available via
|
||||
``mp.last_error()``. Note that only some of the functions have this additional
|
||||
``error`` value - typically the same ones which have it in Lua.
|
||||
|
||||
Standard APIs are preferred. For instance ``setTimeout`` and ``JSON.stringify``
|
||||
are available, but ``mp.add_timeout`` and ``mp.utils.format_json`` are not.
|
||||
|
||||
No standard library. This means that interaction with anything outside of mpv is
|
||||
limited to the available APIs, typically via ``mp.utils``. However, some file
|
||||
functions were added, and CommonJS ``require`` is available too - where the
|
||||
loaded modules have the same privileges as normal scripts.
|
||||
|
||||
Language features - ECMAScript 5
|
||||
--------------------------------
|
||||
|
||||
The scripting backend which mpv currently uses is MuJS - a compatible minimal
|
||||
ES5 interpreter. As such, ``String.substring`` is implemented for instance,
|
||||
while the common but non-standard ``String.substr`` is not. Please consult the
|
||||
MuJS pages on language features and platform support - http://mujs.com .
|
||||
|
||||
Unsupported Lua APIs and their JS alternatives
|
||||
----------------------------------------------
|
||||
|
||||
``mp.add_timeout(seconds, fn)`` JS: ``id = setTimeout(fn, ms)``
|
||||
|
||||
``mp.add_periodic_timer(seconds, fn)`` JS: ``id = setInterval(fn, ms)``
|
||||
|
||||
``mp.register_idle(fn)`` JS: ``id = setTimeout(fn)``
|
||||
|
||||
``mp.unregister_idle(fn)`` JS: ``clearTimeout(id)``
|
||||
|
||||
``utils.parse_json(str [, trail])`` JS: ``JSON.parse(str)``
|
||||
|
||||
``utils.format_json(v)`` JS: ``JSON.stringify(v)``
|
||||
|
||||
``utils.to_string(v)`` see ``dump`` below.
|
||||
|
||||
``mp.suspend()`` JS: none (deprecated).
|
||||
|
||||
``mp.resume()`` JS: none (deprecated).
|
||||
|
||||
``mp.resume_all()`` JS: none (deprecated).
|
||||
|
||||
``mp.get_next_timeout()`` see event loop below.
|
||||
|
||||
``mp.dispatch_events([allow_wait])`` see event loop below.
|
||||
|
||||
``mp.options`` module is not implemented currently for JS.
|
||||
|
||||
Scripting APIs - identical to Lua
|
||||
---------------------------------
|
||||
|
||||
(LE) - Last-Error, indicates that ``mp.last_error()`` can be used after the
|
||||
call to test for success (empty string) or failure (non empty reason string).
|
||||
Otherwise, where the Lua APIs return ``nil`` on error, JS returns ``undefined``.
|
||||
|
||||
``mp.command(string)`` (LE)
|
||||
|
||||
``mp.commandv(arg1, arg2, ...)`` (LE)
|
||||
|
||||
``mp.command_native(table [,def])`` (LE)
|
||||
|
||||
``mp.get_property(name [,def])`` (LE)
|
||||
|
||||
``mp.get_property_osd(name [,def])`` (LE)
|
||||
|
||||
``mp.get_property_bool(name [,def])`` (LE)
|
||||
|
||||
``mp.get_property_number(name [,def])`` (LE)
|
||||
|
||||
``mp.get_property_native(name [,def])`` (LE)
|
||||
|
||||
``mp.set_property(name, value)`` (LE)
|
||||
|
||||
``mp.set_property_bool(name, value)`` (LE)
|
||||
|
||||
``mp.set_property_number(name, value)`` (LE)
|
||||
|
||||
``mp.set_property_native(name, value)`` (LE)
|
||||
|
||||
``mp.get_time()``
|
||||
|
||||
``mp.add_key_binding(key, name|fn [,fn [,flags]])``
|
||||
|
||||
``mp.add_forced_key_binding(...)``
|
||||
|
||||
``mp.remove_key_binding(name)``
|
||||
|
||||
``mp.register_event(name, fn)``
|
||||
|
||||
``mp.unregister_event(fn)``
|
||||
|
||||
``mp.observe_property(name, type, fn)``
|
||||
|
||||
``mp.unobserve_property(fn)``
|
||||
|
||||
``mp.get_opt(key)``
|
||||
|
||||
``mp.get_script_name()``
|
||||
|
||||
``mp.osd_message(text [,duration])``
|
||||
|
||||
``mp.get_wakeup_pipe()``
|
||||
|
||||
``mp.enable_messages(level)``
|
||||
|
||||
``mp.register_script_message(name, fn)``
|
||||
|
||||
``mp.unregister_script_message(name)``
|
||||
|
||||
``mp.msg.log(level, ...)``
|
||||
|
||||
``mp.msg.fatal(...)``
|
||||
|
||||
``mp.msg.error(...)``
|
||||
|
||||
``mp.msg.warn(...)``
|
||||
|
||||
``mp.msg.info(...)``
|
||||
|
||||
``mp.msg.verbose(...)``
|
||||
|
||||
``mp.msg.debug(...)``
|
||||
|
||||
``mp.utils.getcwd()`` (LE)
|
||||
|
||||
``mp.utils.readdir(path [, filter])`` (LE)
|
||||
|
||||
``mp.utils.split_path(path)``
|
||||
|
||||
``mp.utils.join_path(p1, p2)``
|
||||
|
||||
``mp.utils.subprocess(t)``
|
||||
|
||||
``mp.utils.subprocess_detached(t)``
|
||||
|
||||
``mp.add_hook(type, priority, fn)``
|
||||
|
||||
Additional utilities
|
||||
--------------------
|
||||
|
||||
``mp.last_error()``
|
||||
If used after an API call which updates last error, returns an empty string
|
||||
if the API call succeeded, or a non-empty error reason string otherwise.
|
||||
|
||||
``Error.stack`` (string)
|
||||
When using ``try { ... } catch(e) { ... }``, then ``e.stack`` is the stack
|
||||
trace of the error - if it was created using the ``Error(...)`` constructor.
|
||||
|
||||
``print`` (global)
|
||||
A convenient alias to ``mp.msg.info``.
|
||||
|
||||
``dump`` (global)
|
||||
Like ``print`` but also expands objects and arrays recursively.
|
||||
|
||||
``mp.utils.getenv(name)``
|
||||
Returns the value of the host environment variable ``name``, or
|
||||
``undefined`` if the variable is not defined.
|
||||
|
||||
``mp.utils.get_user_path(path)``
|
||||
Expands (mpv) meta paths like ``~/x``, ``~~/y``, ``~~desktop/z`` etc.
|
||||
``read_file``, ``write_file`` and ``require`` already use this internaly.
|
||||
|
||||
``mp.utils.read_file(fname [,max])``
|
||||
Returns the content of file ``fname`` as string. If ``max`` is provided and
|
||||
not negative, limit the read to ``max`` bytes.
|
||||
|
||||
``mp.utils.write_file(fname, str)``
|
||||
(Over)write file ``fname`` with text content ``str``. ``fname`` must be
|
||||
prefixed with ``file://`` as simple protection against accidental arguments
|
||||
switch, e.g. ``mp.utils.write_file("file://~/abc.txt", "hello world")``.
|
||||
|
||||
Note: ``read_file`` and ``write_file`` throw on errors, allow text content only.
|
||||
|
||||
``mp.get_time_ms()``
|
||||
Same as ``mp.get_time()`` but in ms instead of seconds.
|
||||
|
||||
``mp.get_script_file()``
|
||||
Returns the file name of the current script.
|
||||
|
||||
``exit()`` (global)
|
||||
Make the script exit at the end of the current event loop iteration.
|
||||
Note: please reomve added key bindings before calling ``exit()``.
|
||||
|
||||
``mp.utils.compile_js(fname, content_str)``
|
||||
Compiles the JS code ``content_str`` as file name ``fname`` (without loading
|
||||
anything from the filesystem), and returns it as a function. Very similar
|
||||
to a ``Function`` constructor, but shows at stack traces as ``fname``.
|
||||
|
||||
Timers (global)
|
||||
---------------
|
||||
|
||||
The standard HTML/node.js timers are available:
|
||||
|
||||
``id = setTimeout(fn [,duration [,arg1 [,arg2...]]])``
|
||||
|
||||
``id = setTimeout(code_string [,duration])``
|
||||
|
||||
``clearTimeout(id)``
|
||||
|
||||
``id = setInterval(fn [,duration [,arg1 [,arg2...]]])``
|
||||
|
||||
``id = setInterval(code_string [,duration])``
|
||||
|
||||
``clearInterval(id)``
|
||||
|
||||
``setTimeout`` and ``setInterval`` return id, and later call ``fn`` (or execute
|
||||
``code_string``) after ``duration`` ms. Interval also repeat every ``duration``.
|
||||
|
||||
``duration`` has a minimum and default value of 0, ``code_string`` is
|
||||
a plain string which is evaluated as JS code, and ``[,arg1 [,arg2..]]`` are used
|
||||
as arguments (if provided) when calling back ``fn``.
|
||||
|
||||
The ``clear...(id)`` functions cancel timer ``id``, and are irreversible.
|
||||
|
||||
Note: timers always call back asynchronously, e.g. ``setTimeout(fn)`` will never
|
||||
call ``fn`` before returning. ``fn`` will be called either at the end of this
|
||||
event loop iteration or at a later event loop iteration. This is true also for
|
||||
intervals - which also never call back twice at the same event loop iteration.
|
||||
|
||||
Additionally, timers are processed after the event queue is empty, so it's valid
|
||||
to use ``setTimeout(fn)`` instead of Lua's ``mp.register_idle(fn)``.
|
||||
|
||||
CommonJS modules and ``require(id)``
|
||||
------------------------------------
|
||||
|
||||
CommonJS Modules are a standard system where scripts can export common functions
|
||||
for use by other scripts. A module is a script which adds properties (functions,
|
||||
etc) to its invisible ``exports`` object, which another script can access by
|
||||
loading it with ``require(module-id)`` - which returns that ``exports`` object.
|
||||
|
||||
Modules and ``require`` are supported, standard compliant, and generally similar
|
||||
to node.js. However, most node.js modules won't run due to missing modules such
|
||||
as ``fs``, ``process``, etc, but some node.js modules with minimal dependencies
|
||||
do work. In general, this is for mpv modules and not a node.js replacement.
|
||||
|
||||
A ``.js`` file extension is always added to ``id``, e.g. ``require("./foo")``
|
||||
will load the file ``./foo.js`` and return its ``exports`` object.
|
||||
|
||||
An id is relative (to the script which ``require``'d it) if it starts with
|
||||
``./`` or ``../``. Otherwise, it's considered a "top-level id" (CommonJS term).
|
||||
|
||||
Top level id is evaluated as absolute filesystem path if possible (e.g. ``/x/y``
|
||||
or ``~/x``). Otherwise, it's searched at ``scripts/modules.js/`` in mpv config
|
||||
dirs - in normal config search order. E.g. ``require("x")`` is searched as file
|
||||
``x.js`` at those dirs, and id ``foo/x`` is searched as file ``foo/x.js``.
|
||||
|
||||
No ``global`` variable, but a module's ``this`` at its top lexical scope is the
|
||||
global object - also in strict mode. If you have a module which needs ``global``
|
||||
as the global object, you could do ``this.global = this;`` before ``require``.
|
||||
|
||||
Functions and variables declared at a module don't pollute the global object.
|
||||
|
||||
The event loop
|
||||
--------------
|
||||
|
||||
The event loop poll/dispatch mpv events as long as the queue is not empty, then
|
||||
processes the timers, then waits for the next event, and repeats this forever.
|
||||
|
||||
You could put this code at your script to replace the built-in event loop, and
|
||||
also print every event which mpv sends to your script:
|
||||
|
||||
::
|
||||
|
||||
function mp_event_loop() {
|
||||
var wait = 0;
|
||||
do {
|
||||
var e = mp.wait_event(wait);
|
||||
dump(e); // there could be a lot of prints...
|
||||
if (e.event != "none") {
|
||||
mp.dispatch_event(e);
|
||||
wait = 0;
|
||||
} else {
|
||||
wait = mp.process_timers() / 1000;
|
||||
}
|
||||
} while (mp.keep_running);
|
||||
}
|
||||
|
||||
|
||||
``mp_event_loop`` is a name which mpv tries to call after the script loads.
|
||||
The internal implementation is similar to this (without ``dump`` though..).
|
||||
|
||||
``e = mp.wait_event(wait)`` returns when the next mpv event arrives, or after
|
||||
``wait`` seconds if positive and no mpv events arrived. ``wait`` value of 0
|
||||
returns immediately (with ``e.event == "none"`` if the queue is empty).
|
||||
|
||||
``mp.dispatch_event(e)`` calls back the handlers registered for ``e.event``,
|
||||
if there are such (event handlers, property observers, script messages, etc).
|
||||
|
||||
``mp.process_timers()`` calls back the already-added, non-canceled due timers,
|
||||
and returns the duration in ms till the next due timer (possibly 0), or -1 if
|
||||
there are no pending timers. Must not be called recursively.
|
||||
|
||||
Note: ``exit()`` is also registered for the ``shutdown`` event, and its
|
||||
implementation is a simple ``mp.keep_running = false``.
|
||||
@@ -1,75 +0,0 @@
|
||||
EMBEDDING INTO OTHER PROGRAMS (LIBMPV)
|
||||
======================================
|
||||
|
||||
mpv can be embedded into other programs as video/audio playback backend. The
|
||||
recommended way to do so is using libmpv. See ``libmpv/client.h`` in the mpv
|
||||
source code repository. This provides a C API. Bindings for other languages
|
||||
might be available (see wiki).
|
||||
|
||||
Since libmpv merely allows access to underlying mechanisms that can control
|
||||
mpv, further documentation is spread over a few places:
|
||||
|
||||
- https://github.com/mpv-player/mpv/blob/master/libmpv/client.h
|
||||
- http://mpv.io/manual/master/#options
|
||||
- http://mpv.io/manual/master/#list-of-input-commands
|
||||
- http://mpv.io/manual/master/#properties
|
||||
- https://github.com/mpv-player/mpv-examples/tree/master/libmpv
|
||||
|
||||
C PLUGINS
|
||||
=========
|
||||
|
||||
You can write C plugins for mpv. These use the libmpv API, although they do not
|
||||
use the libmpv library itself.
|
||||
|
||||
Currently, they must be explicitly enabled at build time with
|
||||
``--enable-cplugins``. They are available on Linux/BSD platforms only.
|
||||
|
||||
C plugins location
|
||||
------------------
|
||||
|
||||
C plugins are put into the mpv scripts directory in its config directory
|
||||
(see the `FILES`_ section for details). They must have a ``.so`` file extension.
|
||||
They can also be explicitly loaded with the ``--script`` option.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
A C plugin must export the following function::
|
||||
|
||||
int mpv_open_cplugin(mpv_handle *handle)
|
||||
|
||||
The plugin function will be called on loading time. This function does not
|
||||
return as long as your plugin is loaded (it runs in its own thread). The
|
||||
``handle`` will be deallocated as soon as the plugin function returns.
|
||||
|
||||
The return value is interpreted as error status. A value of ``0`` is
|
||||
interpreted as success, while ``-1`` signals an error. In the latter case,
|
||||
the player prints an uninformative error message that loading failed.
|
||||
|
||||
Return values other than ``0`` and ``-1`` are reserved, and trigger undefined
|
||||
behavior.
|
||||
|
||||
Within the plugin function, you can call libmpv API functions. The ``handle``
|
||||
is created by ``mpv_create_client()`` (or actually an internal equivalent),
|
||||
and belongs to you. You can call ``mpv_wait_event()`` to wait for things
|
||||
happening, and so on.
|
||||
|
||||
Note that the player might block until your plugin calls ``mpv_wait_event()``
|
||||
for the first time. This gives you a chance to install initial hooks etc.
|
||||
before playback begins.
|
||||
|
||||
The details are quite similar to Lua scripts.
|
||||
|
||||
Linkage to libmpv
|
||||
-----------------
|
||||
|
||||
The current implementation requires that your plugins are **not** linked against
|
||||
libmpv. What your plugins uses are not symbols from a libmpv binary, but
|
||||
symbols from the mpv host binary.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
See:
|
||||
|
||||
- https://github.com/mpv-player/mpv-examples/tree/master/cplugins
|
||||
+92
-267
@@ -1,16 +1,10 @@
|
||||
LUA SCRIPTING
|
||||
=============
|
||||
|
||||
mpv can load Lua scripts. Scripts passed to the ``--script`` option, or found in
|
||||
the ``scripts`` subdirectory of the mpv configuration directory (usually
|
||||
``~/.config/mpv/scripts/``) will be loaded on program start. mpv also appends the
|
||||
``scripts`` subdirectory to the end of Lua's path so you can import scripts from
|
||||
there too. Since it's added to the end, don't name scripts you want to import
|
||||
the same as Lua libraries because they will be overshadowed by them.
|
||||
|
||||
mpv provides the built-in module ``mp``, which contains functions to send
|
||||
commands to the mpv core and to retrieve information about playback state, user
|
||||
settings, file information, and so on.
|
||||
mpv can load Lua scripts. Scripts in ``~/.mpv/lua/`` will be loaded on program
|
||||
start, or if passed to ``--lua``. mpv provides the built-in module ``mp``, which
|
||||
provides functions to send commands to the mpv core and to retrieve information
|
||||
about playback state, user settings, file information, and so on.
|
||||
|
||||
These scripts can be used to control mpv in a similar way to slave mode.
|
||||
Technically, the Lua code uses the client API internally.
|
||||
@@ -22,29 +16,29 @@ A script which leaves fullscreen mode when the player is paused:
|
||||
|
||||
::
|
||||
|
||||
function on_pause_change(name, value)
|
||||
if value == true then
|
||||
mp.set_property("fullscreen", "no")
|
||||
end
|
||||
function on_pause()
|
||||
mp.set_property("fullscreen", "no")
|
||||
end
|
||||
mp.observe_property("pause", "bool", on_pause_change)
|
||||
mp.register_event("pause", on_pause)
|
||||
|
||||
This script provides a pretty weird feature, but Lua scripting was made to
|
||||
allow users implement features which are not going to be added to the mpv core.
|
||||
|
||||
Details on the script initialization and lifecycle
|
||||
--------------------------------------------------
|
||||
Mode of operation
|
||||
-----------------
|
||||
|
||||
Your script will be loaded by the player at program start from the ``scripts``
|
||||
configuration subdirectory, or from a path specified with the ``--script``
|
||||
option. Some scripts are loaded internally (like ``--osc``). Each script runs in
|
||||
its own thread. Your script is first run "as is", and once that is done, the event loop
|
||||
is entered. This event loop will dispatch events received by mpv and call your
|
||||
own event handlers which you have registered with ``mp.register_event``, or
|
||||
timers added with ``mp.add_timeout`` or similar.
|
||||
Your script will be loaded by the player at program start from ``~/.mpv/lua/``,
|
||||
or ``--lua``, or in some cases, internally (like ``--osc``). Each script runs
|
||||
in its own thread. Your script is first run "as is", and once that is done,
|
||||
the event loop is entered. This event loop will dispatch events received by mpv
|
||||
and call your own event handlers which you have registered with
|
||||
``mp.register_event``, or timers added with ``mp.add_timeout`` or similar.
|
||||
|
||||
When the player quits, all scripts will be asked to terminate. This happens via
|
||||
a ``shutdown`` event, which by default will make the event loop return. If your
|
||||
script got into an endless loop, mpv will probably behave fine during playback,
|
||||
but it won't terminate when quitting, because it's waiting on your script.
|
||||
script got into an endless loop, mpv will probably behave fine during playback
|
||||
(unless the player is suspended, see ``mp.suspend``), but it won't terminate
|
||||
when quitting, because it's waiting on your script.
|
||||
|
||||
Internally, the C code will call the Lua function ``mp_event_loop`` after
|
||||
loading a Lua script. This function is normally defined by the default prelude
|
||||
@@ -53,15 +47,6 @@ The event loop will wait for events and dispatch events registered with
|
||||
``mp.register_event``. It will also handle timers added with ``mp.add_timeout``
|
||||
and similar (by waiting with a timeout).
|
||||
|
||||
Since mpv 0.6.0, the player will wait until the script is fully loaded before
|
||||
continuing normal operation. The player considers a script as fully loaded as
|
||||
soon as it starts waiting for mpv events (or it exits). In practice this means
|
||||
the player will more or less hang until the script returns from the main chunk
|
||||
(and ``mp_event_loop`` is called), or the script calls ``mp_event_loop`` or
|
||||
``mp.dispatch_events`` directly. This is done to make it possible for a script
|
||||
to fully setup event handlers etc. before playback actually starts. In older
|
||||
mpv versions, this happened asynchronously.
|
||||
|
||||
mp functions
|
||||
------------
|
||||
|
||||
@@ -72,10 +57,6 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
Run the given command. This is similar to the commands used in input.conf.
|
||||
See `List of Input Commands`_.
|
||||
|
||||
By default, this will show something on the OSD (depending on the command),
|
||||
as if it was used in ``input.conf``. See `Input Command Prefixes`_ how
|
||||
to influence OSD usage per command.
|
||||
|
||||
Returns ``true`` on success, or ``nil, error`` on error.
|
||||
|
||||
``mp.commandv(arg1, arg2, ...)``
|
||||
@@ -97,18 +78,6 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
the ``expand-properties`` prefix, or the ``mp.get_property`` family of
|
||||
functions.
|
||||
|
||||
Unlike ``mp.command``, this will not use OSD by default either (except
|
||||
for some OSD-specific commands).
|
||||
|
||||
``mp.command_native(table [,def])``
|
||||
Similar to ``mp.commandv``, but pass the argument list as table. This has
|
||||
the advantage that in at least some cases, arguments can be passed as
|
||||
native types.
|
||||
|
||||
Returns a result table on success (usually empty), or ``def, error`` on
|
||||
error. ``def`` is the second parameter provided to the function, and is
|
||||
nil if it's missing.
|
||||
|
||||
``mp.get_property(name [,def])``
|
||||
Return the value of the given property as string. These are the same
|
||||
properties as used in input.conf. See `Properties`_ for a list of
|
||||
@@ -174,7 +143,7 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
Similar to ``mp.set_property``, but set the given property using its native
|
||||
type.
|
||||
|
||||
Since there are several data types which cannot represented natively in
|
||||
Since there are several data types which can not represented natively in
|
||||
Lua, this might not always work as expected. For example, while the Lua
|
||||
wrapper can do some guesswork to decide whether a Lua table is an array
|
||||
or a map, this would fail with empty tables. Also, there are not many
|
||||
@@ -187,41 +156,25 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
Return the current mpv internal time in seconds as a number. This is
|
||||
basically the system time, with an arbitrary offset.
|
||||
|
||||
``mp.add_key_binding(key, name|fn [,fn [,flags]])``
|
||||
``mp.add_key_binding(key, name|fn [,fn])``
|
||||
Register callback to be run on a key binding. The binding will be mapped to
|
||||
the given ``key``, which is a string describing the physical key. This uses
|
||||
the same key names as in input.conf, and also allows combinations
|
||||
(e.g. ``ctrl+a``). If the key is empty or ``nil``, no physical key is
|
||||
registered, but the user still can create own bindings (see below).
|
||||
(e.g. ``ctrl+a``).
|
||||
|
||||
After calling this function, key presses will cause the function ``fn`` to
|
||||
be called (unless the user remapped the key with another binding).
|
||||
|
||||
The ``name`` argument should be a short symbolic string. It allows the user
|
||||
to remap the key binding via input.conf using the ``script-message``
|
||||
to remap the key binding via input.conf using the ``script_message``
|
||||
command, and the name of the key binding (see below for
|
||||
an example). The name should be unique across other bindings in the same
|
||||
script - if not, the previous binding with the same name will be
|
||||
overwritten. You can omit the name, in which case a random name is generated
|
||||
internally.
|
||||
|
||||
The last argument is used for optional flags. This is a table, which can
|
||||
have the following entries:
|
||||
|
||||
``repeatable``
|
||||
If set to ``true``, enables key repeat for this specific binding.
|
||||
|
||||
``complex``
|
||||
If set to ``true``, then ``fn`` is called on both key up and down
|
||||
events (as well as key repeat, if enabled), with the first
|
||||
argument being a table. This table has an ``event`` entry, which
|
||||
is set to one of the strings ``down``, ``repeat``, ``up`` or
|
||||
``press`` (the latter if key up/down can't be tracked). It further
|
||||
has an ``is_mouse`` entry, which tells whether the event was caused
|
||||
by a mouse button.
|
||||
|
||||
Internally, key bindings are dispatched via the ``script-message-to`` or
|
||||
``script-binding`` input commands and ``mp.register_script_message``.
|
||||
Internally, key bindings are dispatched via the ``script_message_to`` input
|
||||
command and ``mp.register_script_message``.
|
||||
|
||||
Trying to map multiple commands to a key will essentially prefer a random
|
||||
binding, while the other bindings are not called. It is guaranteed that
|
||||
@@ -240,11 +193,11 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
This will print the message ``the key was pressed`` when ``x`` was pressed.
|
||||
|
||||
The user can remap these key bindings. Then the user has to put the
|
||||
following into their input.conf to remap the command to the ``y`` key:
|
||||
following into his input.conf to remap the command to the ``y`` key:
|
||||
|
||||
::
|
||||
|
||||
y script-binding something
|
||||
y script_message something
|
||||
|
||||
|
||||
This will print the message when the key ``y`` is pressed. (``x`` will
|
||||
@@ -255,11 +208,11 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
|
||||
::
|
||||
|
||||
y script-binding fooscript/something
|
||||
y script_message_to fooscript something
|
||||
|
||||
``mp.add_forced_key_binding(...)``
|
||||
This works almost the same as ``mp.add_key_binding``, but registers the
|
||||
key binding in a way that will overwrite the user's custom bindings in their
|
||||
key binding in a way that will overwrite the user's custom bindings in his
|
||||
input.conf. (``mp.add_key_binding`` overwrites default key bindings only,
|
||||
but not those by the user's input.conf.)
|
||||
|
||||
@@ -333,6 +286,7 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
the timer is re-added after the function fn is run.
|
||||
|
||||
Returns a timer object. The timer object provides the following methods:
|
||||
|
||||
``stop()``
|
||||
Disable the timer. Does nothing if the timer is already disabled.
|
||||
This will remember the current elapsed time when stopping, so that
|
||||
@@ -349,10 +303,6 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
with ``add_timeout()``), this starts the timer from the beginning,
|
||||
using the initially configured timeout.
|
||||
|
||||
``is_enabled()``
|
||||
Whether the timer is currently enabled or was previously disabled
|
||||
(e.g. by ``stop()`` or ``kill()``).
|
||||
|
||||
``timeout`` (RW)
|
||||
This field contains the current timeout period. This value is not
|
||||
updated as time progresses. It's only used to calculate when the
|
||||
@@ -367,33 +317,16 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
(``true``). This value is used when the timer expires (but before
|
||||
the timer callback function fn is run).
|
||||
|
||||
Note that these are method, and you have to call them using ``:`` instead
|
||||
of ``.`` (Refer to http://www.lua.org/manual/5.2/manual.html#3.4.9 .)
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
seconds = 0
|
||||
timer = mp.add_periodic_timer(1, function()
|
||||
print("called every second")
|
||||
# stop it after 10 seconds
|
||||
seconds = seconds + 1
|
||||
if seconds >= 10 then
|
||||
timer:kill()
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
``mp.get_opt(key)``
|
||||
Return a setting from the ``--script-opts`` option. It's up to the user and
|
||||
Return a setting from the ``--lua-opts`` option. It's up to the user and
|
||||
the script how this mechanism is used. Currently, all scripts can access
|
||||
this equally, so you should be careful about collisions.
|
||||
|
||||
``mp.get_script_name()``
|
||||
Return the name of the current script. The name is usually made of the
|
||||
filename of the script, with directory and file extension removed. If
|
||||
there are several scripts which would have the same name, it's made unique
|
||||
there are several script which would have the same name, it's made unique
|
||||
by appending a number.
|
||||
|
||||
.. admonition:: Example
|
||||
@@ -411,16 +344,25 @@ These also live in the ``mp`` module, but are documented separately as they
|
||||
are useful only in special situations.
|
||||
|
||||
``mp.suspend()``
|
||||
This function has been deprecated in mpv 0.21.0 and does nothing starting
|
||||
with mpv 0.23.0 (no replacement).
|
||||
Suspend the mpv main loop. There is a long-winded explanation of this in
|
||||
the C API function ``mpv_suspend()``. In short, this prevents the player
|
||||
from displaying the next video frame, so that you don't get blocked when
|
||||
trying to access the player.
|
||||
|
||||
This is automatically called by the event handler.
|
||||
|
||||
``mp.resume()``
|
||||
This function has been deprecated in mpv 0.21.0 and does nothing starting
|
||||
with mpv 0.23.0 (no replacement).
|
||||
Undo one ``mp.suspend()`` call. ``mp.suspend()`` increments an internal
|
||||
counter, and ``mp.resume()`` decrements it. When 0 is reached, the player
|
||||
is actually resumed.
|
||||
|
||||
``mp.resume_all()``
|
||||
This function has been deprecated in mpv 0.21.0 and does nothing starting
|
||||
with mpv 0.23.0 (no replacement).
|
||||
This resets the internal suspend counter and resumes the player. (It's
|
||||
like calling ``mp.resume()`` until the player is actually resumed.)
|
||||
|
||||
You might want to call this if you're about to do something that takes a
|
||||
long time, but doesn't really need access to the player (like a network
|
||||
operation). Note that you still can access the player at any time.
|
||||
|
||||
``mp.get_wakeup_pipe()``
|
||||
Calls ``mpv_get_wakeup_pipe()`` and returns the read end of the wakeup
|
||||
@@ -444,17 +386,7 @@ are useful only in special situations.
|
||||
``mp.get_wakeup_pipe()`` if you're interested in properly working
|
||||
notification of new events and working timers.
|
||||
|
||||
``mp.register_idle(fn)``
|
||||
Register an event loop idle handler. Idle handlers are called before the
|
||||
script goes to sleep after handling all new events. This can be used for
|
||||
example to delay processing of property change events: if you're observing
|
||||
multiple properties at once, you might not want to act on each property
|
||||
change, but only when all change notifications have been received.
|
||||
|
||||
``mp.unregister_idle(fn)``
|
||||
Undo ``mp.register_idle(fn)``. This removes all idle handlers that
|
||||
are equal to the ``fn`` parameter. This uses normal Lua ``==`` comparison,
|
||||
so be careful when dealing with closures.
|
||||
This function calls ``mp.suspend()`` and ``mp.resume_all()`` on its own.
|
||||
|
||||
``mp.enable_messages(level)``
|
||||
Set the minimum log level of which mpv message output to receive. These
|
||||
@@ -464,9 +396,9 @@ are useful only in special situations.
|
||||
The level is a string, see ``msg.log`` for allowed log levels.
|
||||
|
||||
``mp.register_script_message(name, fn)``
|
||||
This is a helper to dispatch ``script-message`` or ``script-message-to``
|
||||
invocations to Lua functions. ``fn`` is called if ``script-message`` or
|
||||
``script-message-to`` (with this script as destination) is run
|
||||
This is a helper to dispatch ``script_message`` or ``script_message_to``
|
||||
invocations to Lua functions. ``fn`` is called if ``script_message`` or
|
||||
``script_message_to`` (with this script as destination) is run
|
||||
with ``name`` as first parameter. The other parameters are passed to ``fn``.
|
||||
If a message with the given name is already registered, it's overwritten.
|
||||
|
||||
@@ -523,8 +455,8 @@ Example implementation::
|
||||
optionB = -0.5,
|
||||
optionC = true,
|
||||
}
|
||||
read_options(options, "myscript")
|
||||
print(options.optionA)
|
||||
options.read_options(options, "myscript")
|
||||
print(option.optionA)
|
||||
|
||||
|
||||
The config file will be stored in ``lua-settings/identifier.conf`` in mpv's user
|
||||
@@ -539,28 +471,21 @@ Example config::
|
||||
optionC=no
|
||||
|
||||
|
||||
Command-line options are read from the ``--script-opts`` parameter. To avoid
|
||||
Command-line options are read from the ``--lua-opts`` parameter. To avoid
|
||||
collisions, all keys have to be prefixed with ``identifier-``.
|
||||
|
||||
Example command-line::
|
||||
|
||||
--script-opts=myscript-optionA=TEST,myscript-optionB=0,myscript-optionC=yes
|
||||
--lua-opts=myscript-optionA=TEST:myscript-optionB=0:myscript-optionC=yes
|
||||
|
||||
|
||||
mp.utils functions
|
||||
------------------
|
||||
mp.utils options
|
||||
----------------
|
||||
|
||||
This built-in module provides generic helper functions for Lua, and have
|
||||
strictly speaking nothing to do with mpv or video/audio playback. They are
|
||||
provided for convenience. Most compensate for Lua's scarce standard library.
|
||||
|
||||
Be warned that any of these functions might disappear any time. They are not
|
||||
strictly part of the guaranteed API.
|
||||
|
||||
``utils.getcwd()``
|
||||
Returns the directory that mpv was launched from. On error, ``nil, error``
|
||||
is returned.
|
||||
|
||||
``utils.readdir(path [, filter])``
|
||||
Enumerate all entries at the given path on the filesystem, and return them
|
||||
as array. Each entry is a directory entry (without the path).
|
||||
@@ -597,85 +522,6 @@ strictly part of the guaranteed API.
|
||||
Return the concatenation of the 2 paths. Tries to be clever. For example,
|
||||
if ```p2`` is an absolute path, p2 is returned without change.
|
||||
|
||||
``utils.subprocess(t)``
|
||||
Runs an external process and waits until it exits. Returns process status
|
||||
and the captured output.
|
||||
|
||||
The parameter ``t`` is a table. The function reads the following entries:
|
||||
|
||||
``args``
|
||||
Array of strings. The first array entry is the executable. This
|
||||
can be either an absolute path, or a filename with no path
|
||||
components, in which case the ``PATH`` environment variable is
|
||||
used to resolve the executable. The other array elements are
|
||||
passed as command line arguments.
|
||||
|
||||
``cancellable``
|
||||
Optional. If set to ``true`` (default), then if the user stops
|
||||
playback or goes to the next file while the process is running,
|
||||
the process will be killed.
|
||||
|
||||
``max_size``
|
||||
Optional. The maximum size in bytes of the data that can be captured
|
||||
from stdout. (Default: 16 MB.)
|
||||
|
||||
The function returns a table as result with the following entries:
|
||||
|
||||
``status``
|
||||
The raw exit status of the process. It will be negative on error.
|
||||
|
||||
``stdout``
|
||||
Captured output stream as string, limited to ``max_size``.
|
||||
|
||||
``error``
|
||||
``nil`` on success. The string ``killed`` if the process was
|
||||
terminated in an unusual way. The string ``init`` if the process
|
||||
could not be started.
|
||||
|
||||
On Windows, ``killed`` is only returned when the process has been
|
||||
killed by mpv as a result of ``cancellable`` being set to ``true``.
|
||||
|
||||
``killed_by_us``
|
||||
Set to ``true`` if the process has been killed by mpv as a result
|
||||
of ``cancellable`` being set to ``true``.
|
||||
|
||||
``utils.subprocess_detached(t)``
|
||||
Runs an external process and detaches it from mpv's control.
|
||||
|
||||
The parameter ``t`` is a table. The function reads the following entries:
|
||||
|
||||
``args``
|
||||
Array of strings of the same semantics as the ``args`` used in the
|
||||
``subprocess`` function.
|
||||
|
||||
The function returns ``nil``.
|
||||
|
||||
``utils.parse_json(str [, trail])``
|
||||
Parses the given string argument as JSON, and returns it as a Lua table. On
|
||||
error, returns ``nil, error``. (Currently, ``error`` is just a string
|
||||
reading ``error``, because there is no fine-grained error reporting of any
|
||||
kind.)
|
||||
|
||||
The returned value uses similar conventions as ``mp.get_property_native()``
|
||||
to distinguish empty objects and arrays.
|
||||
|
||||
If the ``trail`` parameter is ``true`` (or any value equal to ``true``),
|
||||
then trailing non-whitespace text is tolerated by the function, and the
|
||||
trailing text is returned as 3rd return value. (The 3rd return value is
|
||||
always there, but with ``trail`` set, no error is raised.)
|
||||
|
||||
``utils.format_json(v)``
|
||||
Format the given Lua table (or value) as a JSON string and return it. On
|
||||
error, returns ``nil, error``. (Errors usually only happen on value types
|
||||
incompatible with JSON.)
|
||||
|
||||
The argument value uses similar conventions as ``mp.set_property_native()``
|
||||
to distinguish empty objects and arrays.
|
||||
|
||||
``utils.to_string(v)``
|
||||
Turn the given value into a string. Formats tables and their contents. This
|
||||
doesn't do anything special; it is only needed because Lua is terrible.
|
||||
|
||||
Events
|
||||
------
|
||||
|
||||
@@ -693,7 +539,7 @@ Example:
|
||||
print("start of playback!")
|
||||
end
|
||||
|
||||
mp.register_event("file-loaded", my_fn)
|
||||
mp.register_event("playback-start", my_fn)
|
||||
|
||||
|
||||
|
||||
@@ -708,49 +554,37 @@ List of events
|
||||
Happens after a file was unloaded. Typically, the player will load the
|
||||
next file right away, or quit if this was the last file.
|
||||
|
||||
The event has the ``reason`` field, which takes one of these values:
|
||||
|
||||
``eof``
|
||||
The file has ended. This can (but doesn't have to) include
|
||||
incomplete files or broken network connections under
|
||||
circumstances.
|
||||
|
||||
``stop``
|
||||
Playback was ended by a command.
|
||||
|
||||
``quit``
|
||||
Playback was ended by sending the quit command.
|
||||
|
||||
``error``
|
||||
An error happened. In this case, an ``error`` field is present with
|
||||
the error string.
|
||||
|
||||
``redirect``
|
||||
Happens with playlists and similar. Details see
|
||||
``MPV_END_FILE_REASON_REDIRECT`` in the C API.
|
||||
|
||||
``unknown``
|
||||
Unknown. Normally doesn't happen, unless the Lua API is out of sync
|
||||
with the C API. (Likewise, it could happen that your script gets
|
||||
reason strings that did not exist yet at the time your script was
|
||||
written.)
|
||||
|
||||
``file-loaded``
|
||||
Happens after a file was loaded and begins playback.
|
||||
|
||||
``seek``
|
||||
Happens on seeking. (This might include cases when the player seeks
|
||||
internally, even without user interaction. This includes e.g. segment
|
||||
changes when playing ordered chapters Matroska files.)
|
||||
Happens on seeking (including ordered chapter segment changes).
|
||||
|
||||
``playback-restart``
|
||||
Start of playback after seek or after file was loaded.
|
||||
|
||||
``tracks-changed``
|
||||
The list of video/audio/sub tracks was updated. (This happens on playback
|
||||
start, and very rarely during playback.)
|
||||
|
||||
``track-switched``
|
||||
A video/audio/subtitle track was switched on or off. This usually happens
|
||||
when the user (or a script) changes the subtitle track and so on.
|
||||
|
||||
``idle``
|
||||
Idle mode is entered. This happens when playback ended, and the player was
|
||||
started with ``--idle`` or ``--force-window``. This mode is implicitly ended
|
||||
when the ``start-file`` or ``shutdown`` events happen.
|
||||
|
||||
``pause``
|
||||
Playback was paused. This also happens when for example the player is
|
||||
paused on low network cache. Then the event type indicates the pause state
|
||||
(like the property "pause" as opposed to the "core-idle" property), and you
|
||||
might receive multiple ``pause`` events in a row.
|
||||
|
||||
``unpause``
|
||||
Playback was unpaused. See above for details.
|
||||
|
||||
``tick``
|
||||
Called after a video frame was displayed. This is a hack, and you should
|
||||
avoid using it. Use timers instead and maybe watch pausing/unpausing events
|
||||
@@ -758,7 +592,7 @@ List of events
|
||||
|
||||
``shutdown``
|
||||
Sent when the player quits, and the script should terminate. Normally
|
||||
handled automatically. See `Details on the script initialization and lifecycle`_.
|
||||
handled automatically. See `Mode of operation`_.
|
||||
|
||||
``log-message``
|
||||
Receives messages enabled with ``mp.enable_messages``. The message data
|
||||
@@ -777,8 +611,13 @@ List of events
|
||||
(undocumented) existing ones.
|
||||
|
||||
``text``
|
||||
The log message. The text will end with a newline character. Sometimes
|
||||
it can contain multiple lines.
|
||||
The log message. Note that this is the direct output of a printf()
|
||||
style output API. The text will contain embedded newlines, and it's
|
||||
possible that a single message contains multiple lines, or that a
|
||||
message contains a partial line.
|
||||
|
||||
It's safe to display messages only if they end with a newline character,
|
||||
and to buffer them otherwise.
|
||||
|
||||
Keep in mind that these messages are meant to be hints for humans. You
|
||||
should not parse them, and prefix/level/text of messages might change
|
||||
@@ -793,6 +632,9 @@ List of events
|
||||
``command-reply``
|
||||
Undocumented (not useful for Lua scripts).
|
||||
|
||||
``script-input-dispatch``
|
||||
Undocumented (used internally).
|
||||
|
||||
``client-message``
|
||||
Undocumented (used internally).
|
||||
|
||||
@@ -802,25 +644,8 @@ List of events
|
||||
``audio-reconfig``
|
||||
Happens on audio output or filter reconfig.
|
||||
|
||||
The following events also happen, but are deprecated: ``tracks-changed``,
|
||||
``track-switched``, ``pause``, ``unpause``, ``metadata-update``,
|
||||
``chapter-change``. Use ``mp.observe_property()`` instead.
|
||||
``metadata-update``
|
||||
Metadata (like file tags) was updated.
|
||||
|
||||
Extras
|
||||
------
|
||||
|
||||
This documents experimental features, or features that are "too special" to
|
||||
guarantee a stable interface.
|
||||
|
||||
``mp.add_hook(type, priority, fn)``
|
||||
Add a hook callback for ``type`` (a string identifying a certain kind of
|
||||
hook). These hooks allow the player to call script functions and wait for
|
||||
their result (normally, the Lua scripting interface is asynchronous from
|
||||
the point of view of the player core). ``priority`` is an arbitrary integer
|
||||
that allows ordering among hooks of the same kind. Using the value 50 is
|
||||
recommended as neutral default value. ``fn`` is the function that will be
|
||||
called during execution of the hook.
|
||||
|
||||
See `Hooks`_ for currently existing hooks and what they do - only the hook
|
||||
list is interesting; handling hook execution is done by the Lua script
|
||||
function automatically.
|
||||
``chapter-change``
|
||||
The current chapter possibly changed.
|
||||
+121
-532
@@ -9,12 +9,11 @@ a media player
|
||||
:Manual section: 1
|
||||
:Manual group: multimedia
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
| **mpv** [options] [file|URL|PLAYLIST|-]
|
||||
| **mpv** [options] [file|URL|-]
|
||||
| **mpv** [options] --playlist=PLAYLIST
|
||||
| **mpv** [options] files
|
||||
|
||||
DESCRIPTION
|
||||
@@ -34,14 +33,8 @@ INTERACTIVE CONTROL
|
||||
===================
|
||||
|
||||
mpv has a fully configurable, command-driven control layer which allows you
|
||||
to control mpv using keyboard, mouse, or remote control (there is no
|
||||
LIRC support - configure remotes as input devices instead).
|
||||
|
||||
See the ``--input-`` options for ways to customize it.
|
||||
|
||||
The following listings are not necessarily complete. See ``etc/input.conf`` for
|
||||
a list of default bindings. User ``input.conf`` files and Lua scripts can
|
||||
define additional key bindings.
|
||||
to control mpv using keyboard, mouse, joystick or remote control (with
|
||||
LIRC). See the ``--input-`` options for ways to customize it.
|
||||
|
||||
Keyboard Control
|
||||
----------------
|
||||
@@ -54,10 +47,6 @@ UP and DOWN
|
||||
Seek forward/backward 1 minute. Shift+arrow does a 5 second exact seek (see
|
||||
``--hr-seek``).
|
||||
|
||||
Ctrl+LEFT and Ctrl+RIGHT
|
||||
Seek to the previous/next subtitle. Subject to some restrictions and
|
||||
might not always work; see ``sub-seek`` command.
|
||||
|
||||
[ and ]
|
||||
Decrease/increase current playback speed by 10%.
|
||||
|
||||
@@ -71,7 +60,7 @@ BACKSPACE
|
||||
Go backward/forward in the playlist.
|
||||
|
||||
ENTER
|
||||
Go forward in the playlist.
|
||||
Go forward in the playlist, even over the end.
|
||||
|
||||
p / SPACE
|
||||
Pause (pressing again unpauses).
|
||||
@@ -84,7 +73,7 @@ p / SPACE
|
||||
Step backward. Pressing once will pause, every consecutive press will
|
||||
play one frame in reverse and then go into pause mode again.
|
||||
|
||||
q
|
||||
q / ESC
|
||||
Stop playing and quit.
|
||||
|
||||
Q
|
||||
@@ -109,9 +98,6 @@ m
|
||||
f
|
||||
Toggle fullscreen (see also ``--fs``).
|
||||
|
||||
ESC
|
||||
Exit fullscreen mode.
|
||||
|
||||
T
|
||||
Toggle stay-on-top (see also ``--ontop``).
|
||||
|
||||
@@ -122,7 +108,11 @@ o (also P)
|
||||
Show progression bar, elapsed time and total duration on the OSD.
|
||||
|
||||
O
|
||||
Toggle OSD states between normal and playback time/duration.
|
||||
Toggle OSD states: none / seek / seek + timer / seek + timer + total time.
|
||||
|
||||
d
|
||||
Toggle frame dropping states: none / skip display / skip decoding (see
|
||||
``--framedrop``).
|
||||
|
||||
v
|
||||
Toggle subtitle visibility.
|
||||
@@ -133,23 +123,9 @@ j and J
|
||||
x and z
|
||||
Adjust subtitle delay by +/- 0.1 seconds.
|
||||
|
||||
l
|
||||
Set/clear A-B loop points. See ``ab-loop`` command for details.
|
||||
|
||||
L
|
||||
Toggle infinite looping.
|
||||
|
||||
Ctrl + and Ctrl -
|
||||
Adjust audio delay (A/V sync) by +/- 0.1 seconds.
|
||||
|
||||
u
|
||||
Switch between applying no style overrides to SSA/ASS subtitles, and
|
||||
overriding them almost completely with the normal subtitle style. See
|
||||
``--sub-ass-override`` for more info.
|
||||
|
||||
V
|
||||
Toggle subtitle VSFilter aspect compatibility mode. See
|
||||
``--sub-ass-vsfilter-aspect-compat`` for more info.
|
||||
``--ass-vsfilter-aspect-compat`` for more info.
|
||||
|
||||
r and t
|
||||
Move subtitles up/down.
|
||||
@@ -161,25 +137,17 @@ S
|
||||
Take a screenshot, without subtitles. (Whether this works depends on VO
|
||||
driver support.)
|
||||
|
||||
Ctrl s
|
||||
Take a screenshot, as the window shows it (with subtitles, OSD, and scaled
|
||||
video).
|
||||
I
|
||||
Show filename on the OSD.
|
||||
|
||||
PGUP and PGDWN
|
||||
Seek to the beginning of the previous/next chapter. In most cases,
|
||||
"previous" will actually go to the beginning of the current chapter; see
|
||||
``--chapter-seek-threshold``.
|
||||
|
||||
Shift+PGUP and Shift+PGDWN
|
||||
Seek backward or forward by 10 minutes. (This used to be mapped to
|
||||
PGUP/PGDWN without Shift.)
|
||||
|
||||
d
|
||||
D
|
||||
Activate/deactivate deinterlacer.
|
||||
|
||||
A
|
||||
Cycle aspect ratio override.
|
||||
|
||||
(The following keys are valid only when using a video output that supports the
|
||||
corresponding adjustment, or the software equalizer (``--vf=eq``).)
|
||||
|
||||
@@ -195,18 +163,25 @@ corresponding adjustment, or the software equalizer (``--vf=eq``).)
|
||||
7 and 8
|
||||
Adjust saturation.
|
||||
|
||||
Alt+0 (and command+0 on OSX)
|
||||
Resize video window to half its original size.
|
||||
(The following keys are valid only on OS X.)
|
||||
|
||||
Alt+1 (and command+1 on OSX)
|
||||
command + 0
|
||||
Resize video window to half its original size.
|
||||
(On other platforms, you can bind keys to change the ``window-scale``
|
||||
property.)
|
||||
|
||||
command + 1
|
||||
Resize video window to its original size.
|
||||
|
||||
Alt+2 (and command+2 on OSX)
|
||||
command + 2
|
||||
Resize video window to double its original size.
|
||||
|
||||
command + f (OSX only)
|
||||
command + f
|
||||
Toggle fullscreen (see also ``--fs``).
|
||||
|
||||
command + [ and command + ]
|
||||
Set video window alpha.
|
||||
|
||||
(The following keys are valid if you have a keyboard with multimedia keys.)
|
||||
|
||||
PAUSE
|
||||
@@ -218,9 +193,11 @@ STOP
|
||||
PREVIOUS and NEXT
|
||||
Seek backward/forward 1 minute.
|
||||
|
||||
(The following keys are only valid if you compiled with TV or DVB input
|
||||
support.)
|
||||
|
||||
If you miss some older key bindings, look at ``etc/restore-old-bindings.conf``
|
||||
in the mpv git repository.
|
||||
h and k
|
||||
Select previous/next channel.
|
||||
|
||||
Mouse Control
|
||||
-------------
|
||||
@@ -235,16 +212,6 @@ button 5 and button 6
|
||||
USAGE
|
||||
=====
|
||||
|
||||
Command line arguments starting with ``-`` are interpreted as options,
|
||||
everything else as filenames or URLs. All options except *flag* options (or
|
||||
choice options which include ``yes``) require a parameter in the form
|
||||
``--option=value``.
|
||||
|
||||
One exception is the lone ``-`` (without anything else), which means media data
|
||||
will be read from stdin. Also, ``--`` (without anything else) will make the
|
||||
player interpret all following arguments as filenames, even if they start with
|
||||
``-``. (To play a file named ``-``, you need to use ``./-``.)
|
||||
|
||||
Every *flag* option has a *no-flag* counterpart, e.g. the opposite of the
|
||||
``--fs`` option is ``--no-fs``. ``--fs=yes`` is same as ``--fs``, ``--fs=no``
|
||||
is the same as ``--no-fs``.
|
||||
@@ -252,84 +219,23 @@ is the same as ``--no-fs``.
|
||||
If an option is marked as *(XXX only)*, it will only work in combination with
|
||||
the *XXX* option or if *XXX* is compiled in.
|
||||
|
||||
Legacy option syntax
|
||||
--------------------
|
||||
.. note::
|
||||
|
||||
The ``--option=value`` syntax is not strictly enforced, and the alternative
|
||||
legacy syntax ``-option value`` and ``--option value`` will also work. This is
|
||||
mostly for compatibility with MPlayer. Using these should be avoided. Their
|
||||
semantics can change any time in the future.
|
||||
The suboption parser (used for example for ``--ao=pcm`` suboptions)
|
||||
supports a special kind of string-escaping intended for use with external
|
||||
GUIs.
|
||||
|
||||
For example, the alternative syntax will consider an argument following the
|
||||
option a filename. ``mpv -fs no`` will attempt to play a file named ``no``,
|
||||
because ``--fs`` is a flag option that requires no parameter. If an option
|
||||
changes and its parameter becomes optional, then a command line using the
|
||||
alternative syntax will break.
|
||||
|
||||
Currently, the parser makes no difference whether an option starts with ``--``
|
||||
or a single ``-``. This might also change in the future, and ``--option value``
|
||||
might always interpret ``value`` as filename in order to reduce ambiguities.
|
||||
|
||||
Escaping spaces and other special characters
|
||||
--------------------------------------------
|
||||
|
||||
Keep in mind that the shell will partially parse and mangle the arguments you
|
||||
pass to mpv. For example, you might need to quote or escape options and
|
||||
filenames:
|
||||
|
||||
``mpv "filename with spaces.mkv" --title="window title"``
|
||||
|
||||
It gets more complicated if the suboption parser is involved. The suboption
|
||||
parser puts several options into a single string, and passes them to a
|
||||
component at once, instead of using multiple options on the level of the
|
||||
command line.
|
||||
|
||||
The suboption parser can quote strings with ``"`` and ``[...]``.
|
||||
Additionally, there is a special form of quoting with ``%n%`` described below.
|
||||
|
||||
For example, assume the hypothetical ``foo`` filter can take multiple options:
|
||||
|
||||
``mpv test.mkv --vf=foo:option1=value1:option2:option3=value3,bar``
|
||||
|
||||
This passes ``option1`` and ``option3`` to the ``foo`` filter, with ``option2``
|
||||
as flag (implicitly ``option2=yes``), and adds a ``bar`` filter after that. If
|
||||
an option contains spaces or characters like ``,`` or ``:``, you need to quote
|
||||
them:
|
||||
|
||||
``mpv '--vf=foo:option1="option value with spaces",bar'``
|
||||
|
||||
Shells may actually strip some quotes from the string passed to the commandline,
|
||||
so the example quotes the string twice, ensuring that mpv receives the ``"``
|
||||
quotes.
|
||||
|
||||
The ``[...]`` form of quotes wraps everything between ``[`` and ``]``. It's
|
||||
useful with shells that don't interpret these characters in the middle of
|
||||
an argument (like bash). These quotes are balanced (since mpv 0.9.0): the ``[``
|
||||
and ``]`` nest, and the quote terminates on the last ``]`` that has no matching
|
||||
``[`` within the string. (For example, ``[a[b]c]`` results in ``a[b]c``.)
|
||||
|
||||
The fixed-length quoting syntax is intended for use with external
|
||||
scripts and programs.
|
||||
|
||||
It is started with ``%`` and has the following format::
|
||||
It has the following format::
|
||||
|
||||
%n%string_of_length_n
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
``mpv '--vf=foo:option1=%11%quoted text' test.avi``
|
||||
``mpv --ao=pcm:file=%10%C:test.wav test.avi``
|
||||
|
||||
Or in a script:
|
||||
|
||||
``mpv --vf=foo:option1=%`expr length "$NAME"`%"$NAME" test.avi``
|
||||
|
||||
Suboptions passed to the client API are also subject to escaping. Using
|
||||
``mpv_set_option_string()`` is exactly like passing ``--name=data`` to the
|
||||
command line (but without shell processing of the string). Some options
|
||||
support passing values in a more structured way instead of flat strings, and
|
||||
can avoid the suboption parsing mess. For example, ``--vf`` supports
|
||||
``MPV_FORMAT_NODE``, which lets you pass suboptions as a nested data structure
|
||||
of maps and arrays.
|
||||
``mpv --ao=pcm:file=%`expr length "$NAME"`%"$NAME" test.avi``
|
||||
|
||||
Paths
|
||||
-----
|
||||
@@ -339,41 +245,19 @@ example, paths starting with ``-`` will be interpreted as options. Likewise,
|
||||
if a path contains the sequence ``://``, the string before that might be
|
||||
interpreted as protocol prefix, even though ``://`` can be part of a legal
|
||||
UNIX path. To avoid problems with arbitrary paths, you should be sure that
|
||||
absolute paths passed to mpv start with ``/``, and prefix relative paths with
|
||||
``./``.
|
||||
|
||||
Using the ``file://`` pseudo-protocol is discouraged, because it involves
|
||||
strange URL unescaping rules.
|
||||
absolute paths passed to mpv start with ``/``, and relative paths with ``./``.
|
||||
|
||||
The name ``-`` itself is interpreted as stdin, and will cause mpv to disable
|
||||
console controls. (Which makes it suitable for playing data piped to stdin.)
|
||||
|
||||
The special argument ``--`` can be used to stop mpv from interpreting the
|
||||
following arguments as options.
|
||||
|
||||
When using the client API, you should strictly avoid using ``mpv_command_string``
|
||||
for invoking the ``loadfile`` command, and instead prefer e.g. ``mpv_command``
|
||||
to avoid the need for filename escaping.
|
||||
|
||||
For paths passed to suboptions, the situation is further complicated by the
|
||||
need to escape special characters. To work this around, the path can be
|
||||
additionally wrapped in the fixed-length syntax, e.g. ``%n%string_of_length_n``
|
||||
(see above).
|
||||
additionally wrapped in the ``%n%string_of_length_n`` syntax (see above).
|
||||
|
||||
Some mpv options interpret paths starting with ``~``. Currently, the prefix
|
||||
``~~/`` expands to the mpv configuration directory (usually ``~/.config/mpv/``).
|
||||
``~~/`` expands to the mpv configuration directory (usually ``~/.mpv/``).
|
||||
``~/`` expands to the user's home directory. (The trailing ``/`` is always
|
||||
required.) There are the following paths as well:
|
||||
|
||||
================ ===============================================================
|
||||
Name Meaning
|
||||
================ ===============================================================
|
||||
``~~home/`` same as ``~~/``
|
||||
``~~global/`` the global config path, if available (not on win32)
|
||||
``~~osxbundle/`` the OSX bundle resource path (OSX only)
|
||||
``~~desktop/`` the path to the desktop (win32, OSX)
|
||||
================ ===============================================================
|
||||
|
||||
required.)
|
||||
|
||||
Per-File Options
|
||||
----------------
|
||||
@@ -415,79 +299,6 @@ file stops playing. If option ``--c`` is changed during playback of
|
||||
``file2.mkv``, it is reset when advancing to ``file3.mkv``. This only affects
|
||||
file-local options. The option ``--a`` is never reset here.
|
||||
|
||||
|
||||
List Options
|
||||
------------
|
||||
|
||||
Some options which store lists of option values can have action suffixes. For
|
||||
example, you can set a ``,``-separated list of filters with ``--vf``, but the
|
||||
option also allows you to append filters with ``--vf-append``.
|
||||
|
||||
Options for filenames do not use ``,`` as separator, but ``:`` (Unix) or ``;``
|
||||
(Windows).
|
||||
|
||||
============= ===============================================
|
||||
Suffix Meaning
|
||||
============= ===============================================
|
||||
-add Append 1 or more items (may become alias for -append)
|
||||
-append Append single item (avoids need for escaping)
|
||||
-clr Clear the option
|
||||
-del Delete an existing item by integer index
|
||||
-pre Prepend 1 or more items
|
||||
-set Set a list of items
|
||||
============= ===============================================
|
||||
|
||||
Although some operations allow specifiying multiple ``,``-separated items, using
|
||||
this is strongly discouraged and deprecated, except for ``-set``.
|
||||
|
||||
Without suffix, the action taken is normally ``-set``.
|
||||
|
||||
Some options (like ``--sub-file``, ``--audio-file``, ``--opengl-shader``) are
|
||||
aliases for the proper option with ``-append`` action. For example,
|
||||
``--sub-file`` is an alias for ``--sub-files-append``.
|
||||
|
||||
Playing DVDs
|
||||
------------
|
||||
|
||||
DVDs can be played with the ``dvd://[title]`` syntax. The optional
|
||||
title specifier is a number which selects between separate video
|
||||
streams on the DVD. If no title is given (``dvd://``) then the longest
|
||||
title is selected automatically by the library. This is usually what
|
||||
you want. mpv does not support DVD menus.
|
||||
|
||||
DVDs which have been copied on to a hard drive or other mounted
|
||||
filesystem (by e.g. the ``dvdbackup`` tool) are accommodated by
|
||||
specifying the path to the local copy: ``--dvd-device=PATH``.
|
||||
Alternatively, running ``mpv PATH`` should auto-detect a DVD directory
|
||||
tree and play the longest title.
|
||||
|
||||
.. note:: DVD library choices
|
||||
|
||||
mpv uses a different default DVD library than MPlayer. MPlayer
|
||||
uses libdvdread by default, and mpv uses libdvdnav by default.
|
||||
Both libraries are developed in parallel, but libdvdnav is
|
||||
intended to support more sophisticated DVD features such as menus
|
||||
and multi-angle playback. mpv uses libdvdnav for files specified
|
||||
as either ``dvd://...`` or ``dvdnav://...``. To use libdvdread,
|
||||
which will produce behavior more like MPlayer, specify
|
||||
``dvdread://...`` instead. Some users have experienced problems
|
||||
when using libdvdnav, in which playback gets stuck in a DVD menu
|
||||
stream. These problems are reported to go away when auto-selecting
|
||||
the title (``dvd://`` rather than ``dvd://1``) or when using
|
||||
libdvdread (e.g. ``dvdread://0``). There are also outstanding bugs
|
||||
in libdvdnav with seeking backwards and forwards in a video
|
||||
stream. Specify ``dvdread://...`` to fix such problems.
|
||||
|
||||
.. note:: DVD subtitles
|
||||
|
||||
DVDs use image-based subtitles. Image subtitles are implemented as
|
||||
a bitmap video stream which can be superimposed over the main
|
||||
movie. mpv's subtitle styling and positioning options and keyboard
|
||||
shortcuts generally do not work with image-based subtitles.
|
||||
Exceptions include options like ``--stretch-dvd-subs`` and
|
||||
``--stretch-image-subs-to-screen``.
|
||||
|
||||
|
||||
CONFIGURATION FILES
|
||||
===================
|
||||
|
||||
@@ -497,12 +308,10 @@ Location and Syntax
|
||||
You can put all of the options in configuration files which will be read every
|
||||
time mpv is run. The system-wide configuration file 'mpv.conf' is in your
|
||||
configuration directory (e.g. ``/etc/mpv`` or ``/usr/local/etc/mpv``), the
|
||||
user-specific one is ``~/.config/mpv/mpv.conf``. For details and platform
|
||||
specifics (in particular Windows paths) see the `FILES`_ section.
|
||||
|
||||
user-specific one is ``~/.config/mpv/mpv.conf``.
|
||||
User-specific options override system-wide options and options given on the
|
||||
command line override either. The syntax of the configuration files is
|
||||
``option=value``. Everything after a *#* is considered a comment. Options
|
||||
``option=<value>``; everything after a *#* is considered a comment. Options
|
||||
that work without values can be enabled by setting them to *yes* and disabled by
|
||||
setting them to *no*. Even suboptions can be specified in this way.
|
||||
|
||||
@@ -515,17 +324,6 @@ setting them to *no*. Even suboptions can be specified in this way.
|
||||
# Use quotes for text that can contain spaces:
|
||||
status-msg="Time: ${time-pos}"
|
||||
|
||||
Escaping spaces and special characters
|
||||
--------------------------------------
|
||||
|
||||
This is done like with command line options. The shell is not involved here,
|
||||
but option values still need to be quoted as a whole if it contains certain
|
||||
characters like spaces. A config entry can be quoted with ``"``,
|
||||
as well as with the fixed-length syntax (``%n%``) mentioned before. This is like
|
||||
passing the exact contents of the quoted string as command line option. C-style
|
||||
escapes are currently _not_ interpreted on this level, although some options do
|
||||
this manually. (This is a mess and should probably be changed at some point.)
|
||||
|
||||
Putting Command Line Options into the Configuration File
|
||||
--------------------------------------------------------
|
||||
|
||||
@@ -547,11 +345,11 @@ File-specific Configuration Files
|
||||
You can also write file-specific configuration files. If you wish to have a
|
||||
configuration file for a file called 'video.avi', create a file named
|
||||
'video.avi.conf' with the file-specific options in it and put it in
|
||||
``~/.config/mpv/``. You can also put the configuration file in the same directory
|
||||
as the file to be played. Both require you to set the ``--use-filedir-conf``
|
||||
``~/.mpv/``. You can also put the configuration file in the same directory
|
||||
as the file to be played, as long as you give the ``--use-filedir-conf``
|
||||
option (either on the command line or in your global config file). If a
|
||||
file-specific configuration file is found in the same directory, no
|
||||
file-specific configuration is loaded from ``~/.config/mpv``. In addition, the
|
||||
file-specific configuration is loaded from ``~/.mpv``. In addition, the
|
||||
``--use-filedir-conf`` option enables directory-specific configuration files.
|
||||
For this, mpv first tries to load a mpv.conf from the same directory
|
||||
as the file played and then tries to load any file-specific configuration.
|
||||
@@ -567,209 +365,100 @@ description (shown by ``--profile=help``) can be defined with the
|
||||
``profile-desc`` option. To end the profile, start another one or use the
|
||||
profile name ``default`` to continue with normal options.
|
||||
|
||||
.. admonition:: Example mpv config file with profiles
|
||||
.. admonition:: Example mpv profile
|
||||
|
||||
::
|
||||
|
||||
# normal top-level option
|
||||
fullscreen=yes
|
||||
|
||||
# a profile that can be enabled with --profile=big-cache
|
||||
[big-cache]
|
||||
cache=123400
|
||||
demuxer-readahead-secs=20
|
||||
|
||||
[slow]
|
||||
profile-desc="some profile name"
|
||||
# reference a builtin profile
|
||||
profile=opengl-hq
|
||||
|
||||
[fast]
|
||||
vo=vdpau
|
||||
|
||||
# using a profile again extends it
|
||||
[slow]
|
||||
framedrop=no
|
||||
# you can also include other profiles
|
||||
profile=big-cache
|
||||
|
||||
|
||||
Auto profiles
|
||||
-------------
|
||||
|
||||
Some profiles are loaded automatically. The following example demonstrates this:
|
||||
|
||||
.. admonition:: Auto profile loading
|
||||
|
||||
::
|
||||
[vo.vdpau]
|
||||
# Use hardware decoding (might break playback of some h264 files)
|
||||
hwdec=vdpau
|
||||
|
||||
[protocol.dvd]
|
||||
profile-desc="profile for dvd:// streams"
|
||||
vf=pp=hb/vb/dr/al/fd
|
||||
alang=en
|
||||
|
||||
[extension.flv]
|
||||
profile-desc="profile for .flv files"
|
||||
vf=flip
|
||||
|
||||
The profile name follows the schema ``type.name``, where type can be
|
||||
``protocol`` for the input/output protocol in use (see ``--list-protocols``),
|
||||
and ``extension`` for the extension of the path of the currently played file
|
||||
(*not* the file format).
|
||||
[ao.alsa]
|
||||
device=spdif
|
||||
|
||||
This feature is very limited, and there are no other auto profiles.
|
||||
|
||||
TAKING SCREENSHOTS
|
||||
==================
|
||||
|
||||
Screenshots of the currently played file can be taken using the 'screenshot'
|
||||
input mode command, which is by default bound to the ``s`` key. Files named
|
||||
``mpv-shotNNNN.jpg`` will be saved in the working directory, using the first
|
||||
available number - no files will be overwritten. In pseudo-GUI mode, the
|
||||
screenshot will be saved somewhere else. See `PSEUDO GUI MODE`_.
|
||||
``shotNNNN.jpg`` will be saved in the working directory, using the first
|
||||
available number - no files will be overwritten.
|
||||
|
||||
A screenshot will usually contain the unscaled video contents at the end of the
|
||||
video filter chain and subtitles. By default, ``S`` takes screenshots without
|
||||
subtitles, while ``s`` includes subtitles.
|
||||
|
||||
Unlike with MPlayer, the ``screenshot`` video filter is not required. This
|
||||
filter was never required in mpv, and has been removed.
|
||||
|
||||
TERMINAL STATUS LINE
|
||||
====================
|
||||
|
||||
During playback, mpv shows the playback status on the terminal. It looks like
|
||||
something like this:
|
||||
|
||||
``AV: 00:03:12 / 00:24:25 (13%) A-V: -0.000``
|
||||
|
||||
The status line can be overridden with the ``--term-status-msg`` option.
|
||||
|
||||
The following is a list of things that can show up in the status line. Input
|
||||
properties, that can be used to get the same information manually, are also
|
||||
listed.
|
||||
|
||||
- ``AV:`` or ``V:`` (video only) or ``A:`` (audio only)
|
||||
- The current time position in ``HH:MM:SS`` format (``playback-time`` property)
|
||||
- The total file duration (absent if unknown) (``length`` property)
|
||||
- Playback speed, e.g. `` x2.0``. Only visible if the speed is not normal. This
|
||||
is the user-requested speed, and not the actual speed (usually they should
|
||||
be the same, unless playback is too slow). (``speed`` property.)
|
||||
- Playback percentage, e.g. ``(13%)``. How much of the file has been played.
|
||||
Normally calculated out of playback position and duration, but can fallback
|
||||
to other methods (like byte position) if these are not available.
|
||||
(``percent-pos`` property.)
|
||||
- The audio/video sync as ``A-V: 0.000``. This is the difference between
|
||||
audio and video time. Normally it should be 0 or close to 0. If it's growing,
|
||||
it might indicate a playback problem. (``avsync`` property.)
|
||||
- Total A/V sync change, e.g. ``ct: -0.417``. Normally invisible. Can show up
|
||||
if there is audio "missing", or not enough frames can be dropped. Usually
|
||||
this will indicate a problem. (``total-avsync-change`` property.)
|
||||
- Encoding state in ``{...}``, only shown in encoding mode.
|
||||
- Display sync state. If display sync is active (``display-sync-active``
|
||||
property), this shows ``DS: 2.500/13``, where the first number is average
|
||||
number of vsyncs per video frame (e.g. 2.5 when playing 24Hz videos on 60Hz
|
||||
screens), which might jitter if the ratio doesn't round off, or there are
|
||||
mistimed frames (``vsync-ratio``), and the second number of estimated number
|
||||
of vsyncs which took too long (``vo-delayed-frame-count`` property). The
|
||||
latter is a heuristic, as it's generally not possible to determine this with
|
||||
certainty.
|
||||
- Dropped frames, e.g. ``Dropped: 4``. Shows up only if the count is not 0. Can
|
||||
grow if the video framerate is higher than that of the display, or if video
|
||||
rendering is too slow. May also be incremented on "hiccups" and when the video
|
||||
frame couldn't be displayed on time. (``vo-drop-frame-count`` property.)
|
||||
If the decoder drops frames, the number of decoder-dropped frames is appended
|
||||
to the display as well, e.g.: ``Dropped: 4/34``. This happens only if
|
||||
decoder frame dropping is enabled with the ``--framedrop`` options.
|
||||
(``drop-frame-count`` property.)
|
||||
- Cache state, e.g. ``Cache: 2s+134KB``. Visible if the stream cache is enabled.
|
||||
The first value shows the amount of video buffered in the demuxer in seconds,
|
||||
the second value shows *additional* data buffered in the stream cache in
|
||||
kilobytes. (``demuxer-cache-duration`` and ``cache-used`` properties.)
|
||||
|
||||
The ``screenshot`` video filter is not required when using a recommended GUI
|
||||
video output driver. It should normally not be added to the config file, as
|
||||
taking screenshots is handled by the VOs, and adding the screenshot filter will
|
||||
break hardware decoding. (The filter may still be useful for taking screenshots
|
||||
at a certain point within the video chain when using multiple video filters.)
|
||||
|
||||
PROTOCOLS
|
||||
=========
|
||||
|
||||
``http://...``, ``https://``, ...
|
||||
|
||||
Many network protocols are supported, but the protocol prefix must always
|
||||
be specified. mpv will never attempt to guess whether a filename is
|
||||
actually a network address. A protocol prefix is always required.
|
||||
|
||||
Note that not all prefixes are documented here. Undocumented prefixes are
|
||||
either aliases to documented protocols, or are just redirections to
|
||||
protocols implemented and documented in FFmpeg.
|
||||
|
||||
``data:`` is supported in FFmpeg (not in Libav), but needs to be in the
|
||||
format ``data://``. This is done to avoid ambiguity with filenames. You
|
||||
can also prefix it with ``lavf://`` or ``ffmpeg://``.
|
||||
|
||||
``ytdl://...``
|
||||
|
||||
By default, the youtube-dl hook script (enabled by default for mpv CLI)
|
||||
only looks at http URLs. Prefixing an URL with ``ytdl://`` forces it to
|
||||
be always processed by the script. This can also be used to invoke special
|
||||
youtube-dl functionality like playing a video by ID or invoking search.
|
||||
|
||||
Keep in mind that you can't pass youtube-dl command line options by this,
|
||||
and you have to use ``--ytdl-raw-options`` instead.
|
||||
|
||||
``-``
|
||||
|
||||
Play data from stdin.
|
||||
|
||||
``smb://PATH``
|
||||
|
||||
Play a path from Samba share.
|
||||
|
||||
``bd://[title][/device]`` ``--bluray-device=PATH``
|
||||
|
||||
Play a Blu-ray disc. Currently, this does not accept ISO files. Instead,
|
||||
Play a Blu-Ray disc. Currently, this does not accept ISO files. Instead,
|
||||
you must mount the ISO file as filesystem, and point ``--bluray-device``
|
||||
to the mounted directory directly.
|
||||
to the mounted directly.
|
||||
|
||||
``bdnav://[title][/device]``
|
||||
Play a Blu-Ray disc, with navigation features enabled. This feature is
|
||||
permanently experimental.
|
||||
|
||||
``dvd://[title|[starttitle]-endtitle][/device]`` ``--dvd-device=PATH``
|
||||
|
||||
Play a DVD. DVD menus are not supported. If no title is given, the longest
|
||||
title is auto-selected.
|
||||
Play a DVD. If you want dvdnav menus, use ``dvd://menu``. If no title
|
||||
is given, the longest title is auto-selected.
|
||||
|
||||
``dvdnav://`` is an old alias for ``dvd://`` and does exactly the same
|
||||
thing.
|
||||
|
||||
``dvdread://...:``
|
||||
|
||||
Play a DVD using the old libdvdread code. This is what MPlayer and
|
||||
older mpv versions use for ``dvd://``. Use is discouraged. It's
|
||||
provided only for compatibility and for transition, and to work
|
||||
around outstanding dvdnav bugs (see "DVD library choices" above).
|
||||
Play a DVD using the old libdvdread code. This is what MPlayer and older
|
||||
mpv versions use for ``dvd://``. Use is discouraged. It's provided only
|
||||
for compatibility and for transition.
|
||||
|
||||
``tv://[channel][/input_id]`` ``--tv-...``
|
||||
|
||||
Analogue TV via V4L. Also useful for webcams. (Linux only.)
|
||||
|
||||
``pvr://`` ``--pvr-...``
|
||||
|
||||
PVR. (Linux only.)
|
||||
|
||||
``dvb://[cardnumber@]channel`` ``--dvbin-...``
|
||||
|
||||
Digital TV via DVB. (Linux only.)
|
||||
|
||||
``mf://[filemask|@listfile]`` ``--mf-...``
|
||||
|
||||
Play a series of images as video.
|
||||
|
||||
``cdda://[device]`` ``--cdrom-device=PATH`` ``--cdda-...``
|
||||
|
||||
``cdda://track[-endtrack][:speed][/device]`` ``--cdrom-device=PATH`` ``--cdda-...``
|
||||
Play CD.
|
||||
|
||||
``lavf://...``
|
||||
|
||||
Access any FFmpeg/Libav libavformat protocol. Basically, this passed the
|
||||
string after the ``//`` directly to libavformat.
|
||||
|
||||
``av://type:options``
|
||||
|
||||
This is intended for using libavdevice inputs. ``type`` is the libavdevice
|
||||
demuxer name, and ``options`` is the (pseudo-)filename passed to the
|
||||
demuxer.
|
||||
@@ -781,81 +470,19 @@ PROTOCOLS
|
||||
``avdevice://`` is an alias.
|
||||
|
||||
``file://PATH``
|
||||
|
||||
A local path as URL. Might be useful in some special use-cases. Note that
|
||||
``PATH`` itself should start with a third ``/`` to make the path an
|
||||
absolute path.
|
||||
|
||||
``fd://123``
|
||||
|
||||
Read data from the given file descriptor (for example 123). This is similar
|
||||
to piping data to stdin via ``-``, but can use an arbitrary file descriptor.
|
||||
|
||||
``fdclose://123``
|
||||
|
||||
Like ``fd://``, but the file descriptor is closed after use. When using this
|
||||
you need to ensure that the same fd URL will only be used once.
|
||||
|
||||
``edl://[edl specification as in edl-mpv.rst]``
|
||||
|
||||
Stitch together parts of multiple files and play them.
|
||||
|
||||
``null://``
|
||||
|
||||
Simulate an empty file. If opened for writing, it will discard all data.
|
||||
The ``null`` demuxer will specifically pass autoprobing if this protocol
|
||||
is used (while it's not automatically invoked for empty files).
|
||||
Simulate an empty file.
|
||||
|
||||
``memory://data``
|
||||
|
||||
Use the ``data`` part as source data.
|
||||
|
||||
``hex://data``
|
||||
|
||||
Like ``memory://``, but the string is interpreted as hexdump.
|
||||
|
||||
PSEUDO GUI MODE
|
||||
===============
|
||||
|
||||
mpv has no official GUI, other than the OSC (`ON SCREEN CONTROLLER`_), which
|
||||
is not a full GUI and is not meant to be. However, to compensate for the lack
|
||||
of expected GUI behavior, mpv will in some cases start with some settings
|
||||
changed to behave slightly more like a GUI mode.
|
||||
|
||||
Currently this happens only in the following cases:
|
||||
|
||||
- if started using the ``mpv.desktop`` file on Linux (e.g. started from menus
|
||||
or file associations provided by desktop environments)
|
||||
- if started from explorer.exe on Windows (technically, if it was started on
|
||||
Windows, and all of the stdout/stderr/stdin handles are unset)
|
||||
- started out of the bundle on OSX
|
||||
- if you manually use ``--player-operation-mode=pseudo-gui`` on the command line
|
||||
|
||||
This mode applies options from the builtin profile ``builtin-pseudo-gui``, but
|
||||
only if these haven't been set in the user's config file or on the command line.
|
||||
Also, for compatibility with the old pseudo-gui behavior, the options in the
|
||||
``pseudo-gui`` profile are applied unconditionally. In addition, the profile
|
||||
makes sure to enable the pseudo-GUI mode, so that ``--profile=pseudo-gui``
|
||||
works like in older mpv releases. The profiles are currently defined as follows:
|
||||
|
||||
::
|
||||
|
||||
[builtin-pseudo-gui]
|
||||
terminal=no
|
||||
force-window=yes
|
||||
idle=once
|
||||
screenshot-directory=~~desktop/
|
||||
[pseudo-gui]
|
||||
player-operation-mode=pseudo-gui
|
||||
|
||||
.. warning::
|
||||
|
||||
Currently, you can extend the ``pseudo-gui`` profile in the config file the
|
||||
normal way. This is deprecated. In future mpv releases, the behavior might
|
||||
change, and not apply your additional settings, and/or use a different
|
||||
profile name.
|
||||
|
||||
|
||||
.. include:: options.rst
|
||||
|
||||
.. include:: ao.rst
|
||||
@@ -874,14 +501,8 @@ works like in older mpv releases. The profiles are currently defined as follows:
|
||||
|
||||
.. include:: lua.rst
|
||||
|
||||
.. include:: javascript.rst
|
||||
|
||||
.. include:: ipc.rst
|
||||
|
||||
.. include:: changes.rst
|
||||
|
||||
.. include:: libmpv.rst
|
||||
|
||||
ENVIRONMENT VARIABLES
|
||||
=====================
|
||||
|
||||
@@ -899,6 +520,9 @@ behavior of mpv.
|
||||
If set, XDG-style system configuration directories are used. Otherwise,
|
||||
the UNIX convention (``PREFIX/etc/mpv/``) is used.
|
||||
|
||||
``TERM``
|
||||
Used to determine terminal type.
|
||||
|
||||
``MPV_HOME``
|
||||
Directory where mpv looks for user settings. Overrides ``HOME``, and mpv
|
||||
will try to load the config file as ``$MPV_HOME/mpv.conf``.
|
||||
@@ -909,7 +533,8 @@ behavior of mpv.
|
||||
of ``--v`` options passed to the command line.
|
||||
|
||||
``MPV_LEAK_REPORT``
|
||||
If set to ``1``, enable internal talloc leak reporting.
|
||||
If set to ``1``, enable internal talloc leak reporting. Note that this can
|
||||
cause trouble with multithreading, so only developers should use this.
|
||||
|
||||
``LADSPA_PATH``
|
||||
Specifies the search path for LADSPA plugins. If it is unset, fully
|
||||
@@ -949,7 +574,7 @@ libdvdcss:
|
||||
|
||||
key
|
||||
is the default method. libdvdcss will use a set of calculated
|
||||
player keys to try to get the disc key. This can fail if the drive
|
||||
player keys to try and get the disc key. This can fail if the drive
|
||||
does not recognize any of the player keys.
|
||||
|
||||
disc
|
||||
@@ -1002,8 +627,6 @@ If errors happen, the following exit codes can be returned:
|
||||
immediately after initialization.
|
||||
:3: There were some files that could be played, and some files which
|
||||
couldn't (using the definition of success from above).
|
||||
:4: Quit due to a signal, Ctrl+c in a VO window (by default), or from the
|
||||
default quit key bindings in encoding mode.
|
||||
|
||||
Note that quitting the player manually will always lead to exit code 0,
|
||||
overriding the exit code that would be returned normally. Also, the ``quit``
|
||||
@@ -1012,103 +635,69 @@ input command can take an exit code: in this case, that exit code is returned.
|
||||
FILES
|
||||
=====
|
||||
|
||||
For Windows-specifics, see `FILES ON WINDOWS`_ section.
|
||||
|
||||
``/usr/local/etc/mpv/mpv.conf``
|
||||
mpv system-wide settings (depends on ``--prefix`` passed to configure - mpv
|
||||
in default configuration will use ``/usr/local/etc/mpv/`` as config
|
||||
directory, while most Linux distributions will set it to ``/etc/mpv/``).
|
||||
mpv system-wide settings (depends on ``--prefix`` passed to configure)
|
||||
|
||||
``~/.config/mpv/mpv.conf``
|
||||
mpv user settings (see `CONFIGURATION FILES`_ section)
|
||||
mpv user settings
|
||||
|
||||
``~/.config/mpv/input.conf``
|
||||
key bindings (see `INPUT.CONF`_ section)
|
||||
|
||||
``~/.config/mpv/fonts.conf``
|
||||
Fontconfig fonts.conf that is customized for mpv. You should include system
|
||||
fonts.conf in this file or mpv would not know about fonts that you already
|
||||
have in the system.
|
||||
|
||||
Only available when libass is built with fontconfig.
|
||||
|
||||
``~/.config/mpv/subfont.ttf``
|
||||
fallback subtitle font
|
||||
|
||||
``~/.config/mpv/fonts/``
|
||||
Font files in this directory are used by mpv/libass for subtitles. Useful
|
||||
if you do not want to install fonts to your system. Note that files in this
|
||||
directory are loaded into memory before being used by mpv. If you have a
|
||||
lot of fonts, consider using fonts.conf (see above) to include additional
|
||||
fonts, which is more memory-efficient.
|
||||
|
||||
``~/.config/mpv/scripts/``
|
||||
All files in this directory are loaded as if they were passed to the
|
||||
``--script`` option. They are loaded in alphabetical order, and sub-directories
|
||||
``~/.config/mpv/lua/``
|
||||
All files in this directly are loaded as if they were passed to the
|
||||
``--lua`` option. They are loaded in alphabetical order, and sub-directories
|
||||
and files with no ``.lua`` extension are ignored. The ``--load-scripts=no``
|
||||
option disables loading these files.
|
||||
|
||||
``~/.config/mpv/watch_later/``
|
||||
Contains temporary config files needed for resuming playback of files with
|
||||
the watch later feature. See for example the ``Q`` key binding, or the
|
||||
``quit-watch-later`` input command.
|
||||
|
||||
Each file is a small config file which is loaded if the corresponding media
|
||||
file is loaded. It contains the playback position and some (not necessarily
|
||||
all) settings that were changed during playback. The filenames are hashed
|
||||
from the full paths of the media files. It's in general not possible to
|
||||
extract the media filename from this hash. However, you can set the
|
||||
``--write-filename-in-watch-later-config`` option, and the player will
|
||||
add the media filename to the contents of the resume config file.
|
||||
|
||||
``~/.config/mpv/lua-settings/osc.conf``
|
||||
This is loaded by the OSC script. See the `ON SCREEN CONTROLLER`_ docs
|
||||
for details.
|
||||
|
||||
Other files in this directory are specific to the corresponding scripts
|
||||
as well, and the mpv core doesn't touch them.
|
||||
|
||||
Note that the environment variables ``$XDG_CONFIG_HOME`` and ``$MPV_HOME`` can
|
||||
override the standard directory ``~/.config/mpv/``.
|
||||
|
||||
Also, the old config location at ``~/.mpv/`` is still read, and if the XDG
|
||||
variant does not exist, will still be preferred.
|
||||
|
||||
FILES ON WINDOWS
|
||||
================
|
||||
EXAMPLES OF MPV USAGE
|
||||
=====================
|
||||
|
||||
On win32 (if compiled with MinGW, but not Cygwin), the default config file
|
||||
locations are different. They are generally located under ``%APPDATA%/mpv/``.
|
||||
For example, the path to mpv.conf is ``%APPDATA%/mpv/mpv.conf``, which maps to
|
||||
a system and user-specific path, for example
|
||||
Blu-ray playback:
|
||||
- ``mpv bd:////path/to/disc``
|
||||
- ``mpv bd:// --bluray-device=/path/to/disc``
|
||||
|
||||
``C:\users\USERNAME\AppData\Roaming\mpv\mpv.conf``
|
||||
Play in Japanese with English subtitles:
|
||||
``mpv dvd://1 --alang=ja --slang=en``
|
||||
|
||||
You can find the exact path by running ``echo %APPDATA%\mpv\mpv.conf`` in cmd.exe.
|
||||
Play only chapters 5, 6, 7:
|
||||
``mpv dvd://1 --chapter=5-7``
|
||||
|
||||
Other config files (such as ``input.conf``) are in the same directory. See the
|
||||
`FILES`_ section above.
|
||||
Play only titles 5, 6, 7:
|
||||
``mpv dvd://5-7``
|
||||
|
||||
The environment variable ``$MPV_HOME`` completely overrides these, like on
|
||||
UNIX.
|
||||
Play a multi-angle DVD:
|
||||
``mpv dvd://1 --dvd-angle=2``
|
||||
|
||||
If a directory named ``portable_config`` next to the mpv.exe exists, all
|
||||
config will be loaded from this directory only. Watch later config files are
|
||||
written to this directory as well. (This exists on Windows only and is redundant
|
||||
with ``$MPV_HOME``. However, since Windows is very scripting unfriendly, a
|
||||
wrapper script just setting ``$MPV_HOME``, like you could do it on other
|
||||
systems, won't work. ``portable_config`` is provided for convenience to get
|
||||
around this restriction.)
|
||||
Play from a different DVD device:
|
||||
``mpv dvd://1 --dvd-device=/dev/dvd2``
|
||||
|
||||
Config files located in the same directory as ``mpv.exe`` are loaded with
|
||||
lower priority. Some config files are loaded only once, which means that
|
||||
e.g. of 2 ``input.conf`` files located in two config directories, only the
|
||||
one from the directory with higher priority will be loaded.
|
||||
Play DVD video from a directory with VOB files:
|
||||
``mpv dvd://1 --dvd-device=/path/to/directory/``
|
||||
|
||||
A third config directory with the lowest priority is the directory named ``mpv``
|
||||
in the same directory as ``mpv.exe``. This used to be the directory with the
|
||||
highest priority, but is now discouraged to use and might be removed in the
|
||||
future.
|
||||
Stream from HTTP:
|
||||
``mpv http://example.com/example.avi``
|
||||
|
||||
Note that mpv likes to mix ``/`` and ``\`` path separators for simplicity.
|
||||
kernel32.dll accepts this, but cmd.exe does not.
|
||||
Stream using RTSP:
|
||||
``mpv rtsp://server.example.com/streamName``
|
||||
|
||||
Play a libavfilter graph:
|
||||
``mpv avdevice://lavfi:mandelbrot``
|
||||
|
||||
AUTHORS
|
||||
=======
|
||||
|
||||
mpv is a MPlayer fork based on mplayer2, which in turn is a fork of MPlayer.
|
||||
|
||||
MPlayer was initially written by Arpad Gereoffy. See the ``AUTHORS`` file for
|
||||
a list of some of the many other contributors.
|
||||
|
||||
MPlayer is (C) 2000-2013 The MPlayer Team
|
||||
|
||||
This man page was written mainly by Gabucino, Jonas Jermann and Diego Biurrun.
|
||||
+753
-2941
File diff suppressed because it is too large.
Load diff
+119
-180
@@ -5,7 +5,7 @@ The On Screen Controller (short: OSC) is a minimal GUI integrated with mpv to
|
||||
offer basic mouse-controllability. It is intended to make interaction easier
|
||||
for new users and to enable precise and direct seeking.
|
||||
|
||||
The OSC is enabled by default if mpv was compiled with Lua support. It can be
|
||||
The OSC is enabled by default if mpv was compiled with lua support. It can be
|
||||
disabled entirely using the ``--osc=no`` option.
|
||||
|
||||
Using the OSC
|
||||
@@ -20,77 +20,37 @@ The Interface
|
||||
|
||||
::
|
||||
|
||||
+---------+----------+------------------------------------------+----------+
|
||||
| pl prev | pl next | title | cache |
|
||||
+------+--+---+------+---------+-----------+------+-------+-----+-----+----+
|
||||
| play | skip | skip | time | seekbar | time | audio | sub | vol | fs |
|
||||
| | back | frwd | elapsed | | left | | | | |
|
||||
+------+------+------+---------+-----------+------+-------+-----+-----+----+
|
||||
+------------------+-----------+--------------------+
|
||||
| playlist prev | title | playlist next |
|
||||
+-------+------+---+--+------+-+----+------+--------+
|
||||
| audio | skip | seek | | seek | skip | full |
|
||||
+-------+ back | back | play | frwd | frwd | screen |
|
||||
| sub | | | | | | |
|
||||
+-------+------+------+------+------+------+--------+
|
||||
| seekbar |
|
||||
+----------------+--------------+-------------------+
|
||||
| time passed | cache status | time remaining |
|
||||
+----------------+--------------+-------------------+
|
||||
|
||||
|
||||
pl prev
|
||||
playlist prev
|
||||
============= ================================================
|
||||
left-click play previous file in playlist
|
||||
right-click show playlist
|
||||
shift+L-click show playlist
|
||||
============= ================================================
|
||||
|
||||
pl next
|
||||
============= ================================================
|
||||
left-click play next file in playlist
|
||||
right-click show playlist
|
||||
shift+L-click show playlist
|
||||
============= ================================================
|
||||
|
||||
title
|
||||
| Displays current media-title, filename, or custom title
|
||||
| Displays current media-title or filename
|
||||
|
||||
============= ================================================
|
||||
left-click show playlist position and length and full title
|
||||
right-click show filename
|
||||
============= ================================================
|
||||
|
||||
cache
|
||||
| Shows current cache fill status
|
||||
|
||||
play
|
||||
playlist next
|
||||
============= ================================================
|
||||
left-click toggle play/pause
|
||||
============= ================================================
|
||||
|
||||
skip back
|
||||
============= ================================================
|
||||
left-click go to beginning of chapter / previous chapter
|
||||
right-click show chapters
|
||||
shift+L-click show chapters
|
||||
============= ================================================
|
||||
|
||||
skip frwd
|
||||
============= ================================================
|
||||
left-click go to next chapter
|
||||
right-click show chapters
|
||||
shift+L-click show chapters
|
||||
============= ================================================
|
||||
|
||||
time elapsed
|
||||
| Shows current playback position timestamp
|
||||
|
||||
============= ================================================
|
||||
left-click toggle displaying timecodes with milliseconds
|
||||
============= ================================================
|
||||
|
||||
seekbar
|
||||
| Indicates current playback position and position of chapters
|
||||
|
||||
============= ================================================
|
||||
left-click seek to position
|
||||
============= ================================================
|
||||
|
||||
time left
|
||||
| Shows remaining playback time timestamp
|
||||
|
||||
============= ================================================
|
||||
left-click toggle between total and remaining time
|
||||
left-click play next file in playlist
|
||||
shift+L-click show playlist
|
||||
============= ================================================
|
||||
|
||||
audio and sub
|
||||
@@ -102,26 +62,75 @@ audio and sub
|
||||
shift+L-click show available audio/sub tracks
|
||||
============= ================================================
|
||||
|
||||
vol
|
||||
skip back
|
||||
============= ================================================
|
||||
left-click toggle mute
|
||||
mouse wheel volume up/down
|
||||
left-click go to beginning of chapter / previous chapter
|
||||
shift+L-click show chapters
|
||||
============= ================================================
|
||||
|
||||
fs
|
||||
seek back
|
||||
============= ================================================
|
||||
left-click skip back 5 seconds
|
||||
right-click skip back 30 seconds
|
||||
shift-L-click skip back 1 frame
|
||||
============= ================================================
|
||||
|
||||
play
|
||||
============= ================================================
|
||||
left-click toggle play/pause
|
||||
============= ================================================
|
||||
|
||||
seek frwd
|
||||
============= ================================================
|
||||
left-click skip forward 10 seconds
|
||||
right-click skip forward 60 seconds
|
||||
shift-L-click skip forward 1 frame
|
||||
============= ================================================
|
||||
|
||||
skip frwd
|
||||
============= ================================================
|
||||
left-click go to next chapter
|
||||
shift+L-click show chapters
|
||||
============= ================================================
|
||||
|
||||
fullscreen
|
||||
============= ================================================
|
||||
left-click toggle fullscreen
|
||||
============= ================================================
|
||||
|
||||
seekbar
|
||||
| Indicates current playback position and position of chapters
|
||||
|
||||
============= ================================================
|
||||
left-click seek to position
|
||||
============= ================================================
|
||||
|
||||
time passed
|
||||
| Shows current playback position timestamp
|
||||
|
||||
============= ================================================
|
||||
left-click toggle displaying timecodes with milliseconds
|
||||
============= ================================================
|
||||
|
||||
cache status
|
||||
| Shows current cache fill status (only visible when below 45%)
|
||||
|
||||
time remaining
|
||||
| Shows remaining playback time timestamp
|
||||
|
||||
============= ================================================
|
||||
left-click toggle between total and remaining time
|
||||
============= ================================================
|
||||
|
||||
Key Bindings
|
||||
~~~~~~~~~~~~
|
||||
|
||||
These key bindings are active by default if nothing else is already bound to
|
||||
these keys. In case of collision, the function needs to be bound to a
|
||||
different key. See the `Script Commands`_ section.
|
||||
different key. See `Script Commands`_ section.
|
||||
|
||||
============= ================================================
|
||||
del Cycles visibility between never / auto (mouse-move) / always
|
||||
del Hide the OSC permanently until mpv is restarted.
|
||||
============= ================================================
|
||||
|
||||
Configuration
|
||||
@@ -129,7 +138,7 @@ Configuration
|
||||
|
||||
The OSC offers limited configuration through a config file
|
||||
``lua-settings/osc.conf`` placed in mpv's user dir and through the
|
||||
``--script-opts`` command-line option. Options provided through the command-line
|
||||
``--lua-opts`` command-line option. Options provided through the command-line
|
||||
will override those from the config file.
|
||||
|
||||
Config Syntax
|
||||
@@ -152,138 +161,73 @@ To avoid collisions with other scripts, all options need to be prefixed with
|
||||
|
||||
Example::
|
||||
|
||||
--script-opts=osc-optionA=value1,osc-optionB=value2
|
||||
--lua-opts=osc-optionA=value1:osc-optionB=value2
|
||||
|
||||
|
||||
Configurable Options
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``layout``
|
||||
Default: bottombar
|
||||
|
||||
The layout for the OSC. Currently available are: box, slimbox,
|
||||
bottombar and topbar. Default pre-0.21.0 was 'box'.
|
||||
|
||||
``seekbarstyle``
|
||||
Default: bar
|
||||
|
||||
Sets the style of the seekbar, slider (diamond marker), knob (circle
|
||||
marker with guide), or bar (fill).
|
||||
Default pre-0.21.0 was 'slider'.
|
||||
|
||||
``deadzonesize``
|
||||
Default: 0.5
|
||||
|
||||
Size of the deadzone. The deadzone is an area that makes the mouse act
|
||||
like leaving the window. Movement there won't make the OSC show up and
|
||||
it will hide immediately if the mouse enters it. The deadzone starts
|
||||
at the window border opposite to the OSC and the size controls how much
|
||||
of the window it will span. Values between 0.0 and 1.0, where 0 means the
|
||||
OSC will always popup with mouse movement in the window, and 1 means the
|
||||
OSC will only show up when the mouse hovers it. Default pre-0.21.0 was 0.
|
||||
|
||||
``minmousemove``
|
||||
Default: 0
|
||||
|
||||
Minimum amount of pixels the mouse has to move between ticks to make
|
||||
the OSC show up. Default pre-0.21.0 was 3.
|
||||
|
||||
``showwindowed``
|
||||
Default: yes
|
||||
|
||||
Enable the OSC when windowed
|
||||
| Default: yes
|
||||
| Show OSC when windowed?
|
||||
|
||||
``showfullscreen``
|
||||
Default: yes
|
||||
|
||||
Enable the OSC when fullscreen
|
||||
| Default: yes
|
||||
| Show OSC when fullscreen?
|
||||
|
||||
``scalewindowed``
|
||||
Default: 1.0
|
||||
|
||||
Scale factor of the OSC when windowed.
|
||||
| Default: 1
|
||||
| Scaling of the controller when windowed
|
||||
|
||||
``scalefullscreen``
|
||||
Default: 1.0
|
||||
|
||||
Scale factor of the OSC when fullscreen
|
||||
| Default: 1
|
||||
| Scaling of the controller when fullscreen
|
||||
|
||||
``scaleforcedwindow``
|
||||
Default: 2.0
|
||||
|
||||
Scale factor of the OSC when rendered on a forced (dummy) window
|
||||
| Default: 2
|
||||
| Scaling of the controller when rendered on a forced (dummy) window
|
||||
|
||||
``vidscale``
|
||||
Default: yes
|
||||
|
||||
Scale the OSC with the video
|
||||
``no`` tries to keep the OSC size constant as much as the window size allows
|
||||
| Default: yes
|
||||
| Scale the controller with the video?
|
||||
|
||||
``valign``
|
||||
Default: 0.8
|
||||
|
||||
Vertical alignment, -1 (top) to 1 (bottom)
|
||||
| Default: 0.8
|
||||
| Vertical alignment, -1 (top) to 1 (bottom)
|
||||
|
||||
``halign``
|
||||
Default: 0.0
|
||||
|
||||
Horizontal alignment, -1 (left) to 1 (right)
|
||||
|
||||
``barmargin``
|
||||
Default: 0
|
||||
|
||||
Margin from bottom (bottombar) or top (topbar), in pixels
|
||||
| Default: 0
|
||||
| Horizontal alignment, -1 (left) to 1 (right)
|
||||
|
||||
``boxalpha``
|
||||
Default: 80
|
||||
|
||||
Alpha of the background box, 0 (opaque) to 255 (fully transparent)
|
||||
| Default: 80
|
||||
| Alpha of the background box, 0 (opaque) to 255 (fully transparent)
|
||||
|
||||
``hidetimeout``
|
||||
Default: 500
|
||||
|
||||
Duration in ms until the OSC hides if no mouse movement, must not be
|
||||
negative
|
||||
| Default: 500
|
||||
| Duration in ms until the OSC hides if no mouse movement, negative value
|
||||
disables auto-hide
|
||||
|
||||
``fadeduration``
|
||||
Default: 200
|
||||
| Default: 200
|
||||
| Duration of fade out in ms, 0 = no fade
|
||||
|
||||
Duration of fade out in ms, 0 = no fade
|
||||
``deadzonesize``
|
||||
| Default: 0
|
||||
| Size of the deadzone. The deadzone is an area that makes the mouse act
|
||||
like leaving the window. Movement there won't make the OSC show up and
|
||||
it will hide immediately if the mouse enters it. The deadzone starts
|
||||
at the window border opposite to the OSC and the size controls how much
|
||||
of the window it will span. Values between 0 and 1.
|
||||
|
||||
``title``
|
||||
Default: ${media-title}
|
||||
``minmousemove``
|
||||
| Default: 3
|
||||
| Minimum amount of pixels the mouse has to move between ticks to make
|
||||
the OSC show up
|
||||
|
||||
String that supports property expansion that will be displayed as
|
||||
OSC title.
|
||||
ASS tags are escaped, and newlines and trailing slashes are stripped.
|
||||
|
||||
``tooltipborder``
|
||||
Default: 1
|
||||
|
||||
Size of the tooltip outline when using bottombar or topbar layouts
|
||||
|
||||
``timetotal``
|
||||
Default: no
|
||||
|
||||
Show total time instead of time remaining
|
||||
|
||||
``timems``
|
||||
Default: no
|
||||
|
||||
Display timecodes with milliseconds
|
||||
|
||||
``visibility``
|
||||
Default: auto (auto hide/show on mouse move)
|
||||
|
||||
Also supports ``never`` and ``always``
|
||||
|
||||
``boxmaxchars``
|
||||
Default: 80
|
||||
|
||||
Max chars for the osc title at the box layout. mpv does not measure the
|
||||
text width on screen and so it needs to limit it by number of chars. The
|
||||
default is conservative to allow wide fonts to be used without overflow.
|
||||
However, with many common fonts a bigger number can be used. YMMV.
|
||||
``seektooltip``
|
||||
| Default: yes
|
||||
| Display a tooltip over the seekbar indicating time at mouse position.
|
||||
|
||||
Script Commands
|
||||
~~~~~~~~~~~~~~~
|
||||
@@ -291,23 +235,18 @@ Script Commands
|
||||
The OSC script listens to certain script commands. These commands can bound
|
||||
in ``input.conf``, or sent by other scripts.
|
||||
|
||||
``osc-message``
|
||||
Show a message on screen using the OSC. First argument is the message,
|
||||
second the duration in seconds.
|
||||
``enable-osc``
|
||||
Undoes ``disable-osc`` or the effect of the ``del`` key.
|
||||
|
||||
``disable-osc``
|
||||
Hide the OSC permanently. This is also what the ``del`` key does.
|
||||
|
||||
``osc-visibility``
|
||||
Controls visibility mode ``never`` / ``auto`` (on mouse move) / ``always``
|
||||
and also ``cycle`` to cycle between the modes
|
||||
|
||||
Example
|
||||
|
||||
You could put this into ``input.conf`` to hide the OSC with the ``a`` key and
|
||||
to set auto mode (the default) with ``b``::
|
||||
to unhide it with ``b``::
|
||||
|
||||
a script-message osc-visibility never
|
||||
b script-message osc-visibility auto
|
||||
|
||||
``osc-playlist``, ``osc-chapterlist``, ``osc-tracklist``
|
||||
Shows a limited view of the respective type of list using the OSC. First
|
||||
argument is duration in seconds.
|
||||
a script_message disable-osc
|
||||
b script_message enable-osc
|
||||
|
||||
+417
-322
@@ -5,41 +5,7 @@ Video filters allow you to modify the video stream and its properties. The
|
||||
syntax is:
|
||||
|
||||
``--vf=<filter1[=parameter1:parameter2:...],filter2,...>``
|
||||
Setup a chain of video filters. This consists on the filter name, and an
|
||||
option list of parameters after ``=``. The parameters are separated by
|
||||
``:`` (not ``,``, as that starts a new filter entry).
|
||||
|
||||
Before the filter name, a label can be specified with ``@name:``, where
|
||||
name is an arbitrary user-given name, which identifies the filter. This
|
||||
is only needed if you want to toggle the filter at runtime.
|
||||
|
||||
A ``!`` before the filter name means the filter is enabled by default. It
|
||||
will be skipped on filter creation. This is also useful for runtime filter
|
||||
toggling.
|
||||
|
||||
See the ``vf`` command (and ``toggle`` sub-command) for further explanations
|
||||
and examples.
|
||||
|
||||
The general filter entry syntax is:
|
||||
|
||||
``["@"<label-name>":"] ["!"] <filter-name> [ "=" <filter-parameter-list> ]``
|
||||
|
||||
or for the special "toggle" syntax (see ``vf`` command):
|
||||
|
||||
``"@"<label-name>``
|
||||
|
||||
and the ``filter-parameter-list``:
|
||||
|
||||
``<filter-parameter> | <filter-parameter> "," <filter-parameter-list>``
|
||||
|
||||
and ``filter-parameter``:
|
||||
|
||||
``( <param-name> "=" <param-value> ) | <param-value>``
|
||||
|
||||
``param-value`` can further be quoted in ``[`` / ``]`` in case the value
|
||||
contains characters like ``,`` or ``=``. This is used in particular with
|
||||
the ``lavfi`` filter, which uses a very similar syntax as mpv (MPlayer
|
||||
historically) to specify filters and their parameters.
|
||||
Setup a chain of video filters.
|
||||
|
||||
You can also set defaults for each filter. The defaults are applied before the
|
||||
normal filter parameters.
|
||||
@@ -49,28 +15,7 @@ normal filter parameters.
|
||||
|
||||
.. note::
|
||||
|
||||
To get a full list of available video filters, see ``--vf=help`` and
|
||||
http://ffmpeg.org/ffmpeg-filters.html .
|
||||
|
||||
Also, keep in mind that most actual filters are available via the ``lavfi``
|
||||
wrapper, which gives you access to most of libavfilter's filters. This
|
||||
includes all filters that have been ported from MPlayer to libavfilter.
|
||||
|
||||
Most builtin filters are deprecated in some ways, unless they're only available
|
||||
in mpv (such as filters which deal with mpv specifics, or which are
|
||||
implemented in mpv only).
|
||||
|
||||
If a filter is not builtin, the ``lavfi-bridge`` will be automatically
|
||||
tried. This bridge does not support help output, and does not verify
|
||||
parameters before the filter is actually used. Although the mpv syntax
|
||||
is rather similar to libavfilter's, it's not the same. (Which means not
|
||||
everything accepted by vf_lavfi's ``graph`` option will be accepted by
|
||||
``--vf``.)
|
||||
|
||||
You can also prefix the filter name with ``lavfi-`` to force the wrapper.
|
||||
This is helpful if the filter name collides with a deprecated mpv builtin
|
||||
filter. For example ``--vf=lavfi-scale=args`` would use libavfilter's
|
||||
``scale`` filter over mpv's deprecated builtin one.
|
||||
To get a full list of available video filters, see ``--vf=help``.
|
||||
|
||||
Video filters are managed in lists. There are a few commands to manage the
|
||||
filter list.
|
||||
@@ -98,7 +43,7 @@ With filters that support it, you can access parameters by their name.
|
||||
Sets a named parameter to the given value. Use on and off or yes and no to
|
||||
set flag parameters.
|
||||
|
||||
Available mpv-only filters are:
|
||||
Available filters are:
|
||||
|
||||
``crop[=w:h:x:y]``
|
||||
Crops the given part of the image and discards the rest. Useful to remove
|
||||
@@ -152,7 +97,7 @@ Available mpv-only filters are:
|
||||
|
||||
All parameters are optional.
|
||||
|
||||
``<w>:<h>``
|
||||
``<w>,<h>``
|
||||
scaled width/height (default: original width/height)
|
||||
|
||||
:0: scaled d_width/d_height
|
||||
@@ -198,19 +143,19 @@ Available mpv-only filters are:
|
||||
Accurate rounding for the vertical scaler, which may be faster or
|
||||
slower than the default rounding.
|
||||
|
||||
:no: Disable accurate rounding (default).
|
||||
:yes: Enable accurate rounding.
|
||||
:0: Disable accurate rounding (default).
|
||||
:1: Enable accurate rounding.
|
||||
|
||||
``dsize[=w:h:aspect-method:r:aspect]``
|
||||
Changes the intended display aspect at an arbitrary point in the
|
||||
Changes the intended display size/aspect at an arbitrary point in the
|
||||
filter chain. Aspect can be given as a fraction (4/3) or floating point
|
||||
number (1.33). Note that this filter does *not* do any scaling itself; it
|
||||
number (1.33). Alternatively, you may specify the exact display width and
|
||||
height desired. Note that this filter does *not* do any scaling itself; it
|
||||
just affects what later scalers (software or hardware) will do when
|
||||
auto-scaling to the correct aspect.
|
||||
auto-scaling to correct aspect.
|
||||
|
||||
``<w>,<h>``
|
||||
New aspect ratio given by a display width and height. Unlike older mpv
|
||||
versions or MPlayer, this does not set the display size.
|
||||
New display width and height.
|
||||
|
||||
Can also be these special values:
|
||||
|
||||
@@ -253,7 +198,7 @@ Available mpv-only filters are:
|
||||
``<aspect>``
|
||||
Force an aspect ratio.
|
||||
|
||||
``format=fmt=<value>:colormatrix=<value>:...``
|
||||
``format[=fmt[:outfmt]]``
|
||||
Restricts the color space for the next filter without doing any conversion.
|
||||
Use together with the scale filter for a real conversion.
|
||||
|
||||
@@ -262,158 +207,19 @@ Available mpv-only filters are:
|
||||
For a list of available formats, see ``format=fmt=help``.
|
||||
|
||||
``<fmt>``
|
||||
Format name, e.g. rgb15, bgr24, 420p, etc. (default: don't change).
|
||||
Format name, e.g. rgb15, bgr24, 420p, etc. (default: yuyv).
|
||||
``<outfmt>``
|
||||
Format name that should be substituted for the output. If they do not
|
||||
have the same bytes per pixel and chroma subsampling, it will fail.
|
||||
``<colormatrix>``
|
||||
Controls the YUV to RGB color space conversion when playing video. There
|
||||
are various standards. Normally, BT.601 should be used for SD video, and
|
||||
BT.709 for HD video. (This is done by default.) Using incorrect color space
|
||||
results in slightly under or over saturated and shifted colors.
|
||||
Format name that should be substituted for the output. If this is not
|
||||
100% compatible with the ``<fmt>`` value, it will crash.
|
||||
|
||||
These options are not always supported. Different video outputs provide
|
||||
varying degrees of support. The ``opengl`` and ``vdpau`` video output
|
||||
drivers usually offer full support. The ``xv`` output can set the color
|
||||
space if the system video driver supports it, but not input and output
|
||||
levels. The ``scale`` video filter can configure color space and input
|
||||
levels, but only if the output format is RGB (if the video output driver
|
||||
supports RGB output, you can force this with ``-vf scale,format=rgba``).
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
color space flag will be used. If that flag is unset, the color space
|
||||
will be selected automatically. This is done using a simple heuristic that
|
||||
attempts to distinguish SD and HD video. If the video is larger than
|
||||
1279x576 pixels, BT.709 (HD) will be used; otherwise BT.601 (SD) is
|
||||
selected.
|
||||
|
||||
Available color spaces are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:bt.601: ITU-R BT.601 (SD)
|
||||
:bt.709: ITU-R BT.709 (HD)
|
||||
:bt.2020-ncl: ITU-R BT.2020 non-constant luminance system
|
||||
:bt.2020-cl: ITU-R BT.2020 constant luminance system
|
||||
:smpte-240m: SMPTE-240M
|
||||
|
||||
``<colorlevels>``
|
||||
YUV color levels used with YUV to RGB conversion. This option is only
|
||||
necessary when playing broken files which do not follow standard color
|
||||
levels or which are flagged wrong. If the video does not specify its
|
||||
color range, it is assumed to be limited range.
|
||||
|
||||
The same limitations as with ``<colormatrix>`` apply.
|
||||
|
||||
Available color ranges are:
|
||||
|
||||
:auto: automatic selection (normally limited range) (default)
|
||||
:limited: limited range (16-235 for luma, 16-240 for chroma)
|
||||
:full: full range (0-255 for both luma and chroma)
|
||||
|
||||
``<primaries>``
|
||||
RGB primaries the source file was encoded with. Normally this should be set
|
||||
in the file header, but when playing broken or mistagged files this can be
|
||||
used to override the setting.
|
||||
|
||||
This option only affects video output drivers that perform color
|
||||
management, for example ``opengl`` with the ``target-prim`` or
|
||||
``icc-profile`` suboptions set.
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
primaries flag will be used. If that flag is unset, the color space will
|
||||
be selected automatically, using the following heuristics: If the
|
||||
``<colormatrix>`` is set or determined as BT.2020 or BT.709, the
|
||||
corresponding primaries are used. Otherwise, if the video height is
|
||||
exactly 576 (PAL), BT.601-625 is used. If it's exactly 480 or 486 (NTSC),
|
||||
BT.601-525 is used. If the video resolution is anything else, BT.709 is
|
||||
used.
|
||||
|
||||
Available primaries are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:bt.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC, SMPTE-C)
|
||||
:bt.601-625: ITU-R BT.601 (SD) 625-line systems (PAL, SECAM)
|
||||
:bt.709: ITU-R BT.709 (HD) (same primaries as sRGB)
|
||||
:bt.2020: ITU-R BT.2020 (UHD)
|
||||
:apple: Apple RGB
|
||||
:adobe: Adobe RGB (1998)
|
||||
:prophoto: ProPhoto RGB (ROMM)
|
||||
:cie1931: CIE 1931 RGB
|
||||
:dci-p3: DCI-P3 (Digital Cinema)
|
||||
:v-gamut: Panasonic V-Gamut primaries
|
||||
|
||||
``<gamma>``
|
||||
Gamma function the source file was encoded with. Normally this should be set
|
||||
in the file header, but when playing broken or mistagged files this can be
|
||||
used to override the setting.
|
||||
|
||||
This option only affects video output drivers that perform color management.
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the gamma will
|
||||
be set to BT.1886 for YCbCr content, sRGB for RGB content and Linear for
|
||||
XYZ content.
|
||||
|
||||
Available gamma functions are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:bt.1886: ITU-R BT.1886 (EOTF corresponding to BT.601/BT.709/BT.2020)
|
||||
:srgb: IEC 61966-2-4 (sRGB)
|
||||
:linear: Linear light
|
||||
:gamma1.8: Pure power curve (gamma 1.8)
|
||||
:gamma2.2: Pure power curve (gamma 2.2)
|
||||
:gamma2.8: Pure power curve (gamma 2.8)
|
||||
:prophoto: ProPhoto RGB (ROMM) curve
|
||||
:pq: ITU-R BT.2100 PQ (Perceptual quantizer) curve
|
||||
:hlg: ITU-R BT.2100 HLG (Hybrid Log-gamma) curve
|
||||
:v-log: Panasonic V-Log transfer curve
|
||||
:s-log1: Sony S-Log1 transfer curve
|
||||
:s-log2: Sony S-Log2 transfer curve
|
||||
|
||||
``<sig-peak>``
|
||||
Reference peak illumination for the video file, relative to the
|
||||
signal's reference white level. This is mostly interesting for HDR, but
|
||||
it can also be used tone map SDR content to simulate a different
|
||||
exposure. Normally inferred from tags such as MaxCLL or mastering
|
||||
metadata.
|
||||
|
||||
The default of 0.0 will default to the source's nominal peak luminance.
|
||||
|
||||
``<light>``
|
||||
Light type of the scene. This is mostly correctly inferred based on the
|
||||
gamma function, but it can be useful to override this when viewing raw
|
||||
camera footage (e.g. V-Log), which is normally scene-referred instead
|
||||
of display-referred.
|
||||
|
||||
Available light types are:
|
||||
|
||||
:auto: Automatic selection (default)
|
||||
:display: Display-referred light (most content)
|
||||
:hlg: Scene-referred using the HLG OOTF (e.g. HLG content)
|
||||
:709-1886: Scene-referred using the BT709+BT1886 interaction
|
||||
:gamma1.2: Scene-referred using a pure power OOTF (gamma=1.2)
|
||||
|
||||
``<stereo-in>``
|
||||
Set the stereo mode the video is assumed to be encoded in. Takes the
|
||||
same values as the ``--video-stereo-mode`` option.
|
||||
|
||||
``<stereo-out>``
|
||||
Set the stereo mode the video should be displayed as. Takes the
|
||||
same values as the ``--video-stereo-mode`` option.
|
||||
|
||||
``<rotate>``
|
||||
Set the rotation the video is assumed to be encoded with in degrees.
|
||||
The special value ``-1`` uses the input format.
|
||||
|
||||
``<dw>``, ``<dh>``
|
||||
Set the display size. Note that setting the display size such that
|
||||
the video is scaled in both directions instead of just changing the
|
||||
aspect ratio is an implementation detail, and might change later.
|
||||
|
||||
``<dar>``
|
||||
Set the display aspect ratio of the video frame. This is a float,
|
||||
but values such as ``[16:9]`` can be passed too (``[...]`` for quoting
|
||||
to prevent the option parser from interpreting the ``:`` character).
|
||||
.. admonition:: Examples
|
||||
|
||||
====================== =====================
|
||||
Valid Invalid (will crash)
|
||||
====================== =====================
|
||||
``format=rgb24:bgr24`` ``format=rgb24:420p``
|
||||
``format=yuyv:uyvy``
|
||||
====================== =====================
|
||||
|
||||
``noformat[=fmt]``
|
||||
Restricts the color space for the next filter without doing any conversion.
|
||||
@@ -425,6 +231,150 @@ Available mpv-only filters are:
|
||||
``<fmt>``
|
||||
Format name, e.g. rgb15, bgr24, 420p, etc. (default: 420p).
|
||||
|
||||
``pp[=[filter1[:option1[:option2...]]/[-]filter2...]]``
|
||||
Enables the specified chain of post-processing subfilters. Subfilters must
|
||||
be separated by '/' and can be disabled by prepending a '-'. Each
|
||||
subfilter and some options have a short and a long name that can be used
|
||||
interchangeably, i.e. ``dr``/``dering`` are the same. All subfilters share
|
||||
common options to determine their scope:
|
||||
|
||||
``a/autoq``
|
||||
Automatically switch the subfilter off if the CPU is too slow.
|
||||
``c/chrom``
|
||||
Do chrominance filtering, too (default).
|
||||
``y/nochrom``
|
||||
Do luminance filtering only (no chrominance).
|
||||
``n/noluma``
|
||||
Do chrominance filtering only (no luminance).
|
||||
|
||||
.. note::
|
||||
|
||||
``--vf=pp:help`` shows a list of available subfilters.
|
||||
|
||||
.. note::
|
||||
|
||||
Unlike in MPlayer or in earlier versions, you must quote the pp string
|
||||
if it contains ``:`` characters, e.g. ``'--vf=pp=[...]'``.
|
||||
|
||||
Available subfilters are:
|
||||
|
||||
``hb/hdeblock[:difference[:flatness]]``
|
||||
horizontal deblocking filter
|
||||
|
||||
:<difference>: Difference factor where higher values mean more
|
||||
deblocking (default: 32).
|
||||
:<flatness>: Flatness threshold where lower values mean more
|
||||
deblocking (default: 39).
|
||||
|
||||
``vb/vdeblock[:difference[:flatness]]``
|
||||
vertical deblocking filter
|
||||
|
||||
:<difference>: Difference factor where higher values mean more
|
||||
deblocking (default: 32).
|
||||
:<flatness>: Flatness threshold where lower values mean more
|
||||
deblocking (default: 39).
|
||||
|
||||
``ha/hadeblock[:difference[:flatness]]``
|
||||
accurate horizontal deblocking filter
|
||||
|
||||
:<difference>: Difference factor where higher values mean more
|
||||
deblocking (default: 32).
|
||||
:<flatness>: Flatness threshold where lower values mean more
|
||||
deblocking (default: 39).
|
||||
|
||||
``va/vadeblock[:difference[:flatness]]``
|
||||
accurate vertical deblocking filter
|
||||
|
||||
:<difference>: Difference factor where higher values mean more
|
||||
deblocking (default: 32).
|
||||
:<flatness>: Flatness threshold where lower values mean more
|
||||
deblocking (default: 39).
|
||||
|
||||
The horizontal and vertical deblocking filters share the difference and
|
||||
flatness values so you cannot set different horizontal and vertical
|
||||
thresholds.
|
||||
|
||||
``h1/x1hdeblock``
|
||||
experimental horizontal deblocking filter
|
||||
|
||||
``v1/x1vdeblock``
|
||||
experimental vertical deblocking filter
|
||||
|
||||
``dr/dering``
|
||||
deringing filter
|
||||
|
||||
``tn/tmpnoise[:threshold1[:threshold2[:threshold3]]]``
|
||||
temporal noise reducer
|
||||
|
||||
:<threshold1>: larger -> stronger filtering
|
||||
:<threshold2>: larger -> stronger filtering
|
||||
:<threshold3>: larger -> stronger filtering
|
||||
|
||||
``al/autolevels[:f/fullyrange]``
|
||||
automatic brightness / contrast correction
|
||||
|
||||
:f/fullyrange: Stretch luminance to (0-255).
|
||||
|
||||
``lb/linblenddeint``
|
||||
Linear blend deinterlacing filter that deinterlaces the given block by
|
||||
filtering all lines with a (1 2 1) filter.
|
||||
|
||||
``li/linipoldeint``
|
||||
Linear interpolating deinterlacing filter that deinterlaces the given
|
||||
block by linearly interpolating every second line.
|
||||
|
||||
``ci/cubicipoldeint``
|
||||
Cubic interpolating deinterlacing filter deinterlaces the given block
|
||||
by cubically interpolating every second line.
|
||||
|
||||
``md/mediandeint``
|
||||
Median deinterlacing filter that deinterlaces the given block by
|
||||
applying a median filter to every second line.
|
||||
|
||||
``fd/ffmpegdeint``
|
||||
FFmpeg deinterlacing filter that deinterlaces the given block by
|
||||
filtering every second line with a (-1 4 2 4 -1) filter.
|
||||
|
||||
``l5/lowpass5``
|
||||
Vertically applied FIR low-pass deinterlacing filter that deinterlaces
|
||||
the given block by filtering all lines with a (-1 2 6 2 -1) filter.
|
||||
|
||||
``fq/forceQuant[:quantizer]``
|
||||
Overrides the quantizer table from the input with the constant
|
||||
quantizer you specify.
|
||||
|
||||
:<quantizer>: quantizer to use
|
||||
|
||||
``de/default``
|
||||
default pp filter combination (hb:a,vb:a,dr:a)
|
||||
|
||||
``fa/fast``
|
||||
fast pp filter combination (h1:a,v1:a,dr:a)
|
||||
|
||||
``ac``
|
||||
high quality pp filter combination (ha:a:128:7,va:a,dr:a)
|
||||
|
||||
.. note::
|
||||
|
||||
This filter is only available if FFmpeg/Libav has been compiled
|
||||
with libpostproc enabled.
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
``--vf=pp=hb/vb/dr/al``
|
||||
horizontal and vertical deblocking, deringing and automatic
|
||||
brightness/contrast
|
||||
|
||||
``--vf=pp=de/-al``
|
||||
default filters without brightness/contrast correction
|
||||
|
||||
``--vf=pp=[default/tmpnoise:1:2:3]``
|
||||
Enable default filters & temporal denoiser.
|
||||
|
||||
``--vf=pp=[hb:y/vb:a]``
|
||||
Horizontal deblocking on luminance only, and switch vertical
|
||||
deblocking on or off automatically depending on available CPU time.
|
||||
|
||||
``lavfi=graph[:sws-flags[:o=opts]]``
|
||||
Filter video using FFmpeg's libavfilter.
|
||||
|
||||
@@ -474,6 +424,45 @@ Available mpv-only filters are:
|
||||
``'--vf=lavfi=yadif:o="threads=2,thread_type=slice"'``
|
||||
forces a specific threading configuration.
|
||||
|
||||
``noise[=<strength>[:averaged][:pattern][:temporal][:uniform][:hq]``
|
||||
Adds noise.
|
||||
|
||||
``strength``
|
||||
Set the noise for all components. If you want different strength
|
||||
values for luma and chroma, use libavfilter's noise filter directly
|
||||
(using ``--vf=lavfi=[noise=...]``), or tell the libavfilter developers
|
||||
to stop being stupid.
|
||||
|
||||
``averaged``
|
||||
averaged temporal noise (smoother, but a lot slower)
|
||||
|
||||
``pattern``
|
||||
mix random noise with a (semi)regular pattern
|
||||
|
||||
``temporal``
|
||||
temporal noise (noise pattern changes between frames)
|
||||
|
||||
``uniform``
|
||||
uniform noise (Gaussian otherwise)
|
||||
|
||||
``hq``
|
||||
high quality (slightly better looking, slightly slower) - not available
|
||||
when using libavfilter
|
||||
|
||||
``hqdn3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp]``
|
||||
This filter aims to reduce image noise producing smooth images and making
|
||||
still images really still (This should enhance compressibility.).
|
||||
|
||||
``<luma_spatial>``
|
||||
spatial luma strength (default: 4)
|
||||
``<chroma_spatial>``
|
||||
spatial chroma strength (default: 3)
|
||||
``<luma_tmp>``
|
||||
luma temporal strength (default: 6)
|
||||
``<chroma_tmp>``
|
||||
chroma temporal strength (default:
|
||||
``luma_tmp*chroma_spatial/luma_spatial``)
|
||||
|
||||
``eq[=gamma:contrast:brightness:saturation:rg:gg:bg:weight]``
|
||||
Software equalizer that uses lookup tables (slow), allowing gamma correction
|
||||
in addition to simple brightness and contrast adjustment. The parameters are
|
||||
@@ -500,6 +489,39 @@ Available mpv-only filters are:
|
||||
and just plain white. A value of 0.0 turns the gamma correction all
|
||||
the way down while 1.0 leaves it at its full strength (default: 1.0).
|
||||
|
||||
``ilpack[=mode]``
|
||||
When interlaced video is stored in YUV 4:2:0 formats, chroma interlacing
|
||||
does not line up properly due to vertical downsampling of the chroma
|
||||
channels. This filter packs the planar 4:2:0 data into YUY2 (4:2:2) format
|
||||
with the chroma lines in their proper locations, so that in any given
|
||||
scanline, the luma and chroma data both come from the same field.
|
||||
|
||||
``<mode>``
|
||||
Select the sampling mode.
|
||||
|
||||
:0: nearest-neighbor sampling, fast but incorrect
|
||||
:1: linear interpolation (default)
|
||||
|
||||
``unsharp[=lx:ly:la:cx:cy:ca]``
|
||||
unsharp mask / Gaussian blur
|
||||
|
||||
``l`` is for the luma component, ``c`` for the chroma component. ``x``/``y``
|
||||
is the filter size. ``a`` is the amount.
|
||||
|
||||
``lx``, ``ly``, ``cx``, ``cy``
|
||||
width and height of the matrix, odd sized in both directions (min =
|
||||
3:3, max = 13:11 or 11:13, usually something between 3:3 and 7:7)
|
||||
|
||||
``la``, ``ca``
|
||||
Relative amount of sharpness/blur to add to the image (a sane range
|
||||
should be -1.5-1.5).
|
||||
|
||||
:<0: blur
|
||||
:>0: sharpen
|
||||
|
||||
``swapuv``
|
||||
Swap U & V plane.
|
||||
|
||||
``pullup[=jl:jr:jt:jb:sb:mp]``
|
||||
Pulldown reversal (inverse telecine) filter, capable of handling mixed
|
||||
hard-telecine, 24000/1001 fps progressive, and 30000/1001 fps progressive
|
||||
@@ -519,8 +541,9 @@ Available mpv-only filters are:
|
||||
generating an occasional mismatched frame, but it may also cause an
|
||||
excessive number of frames to be dropped during high motion sequences.
|
||||
Conversely, setting it to -1 will make ``pullup`` match fields more
|
||||
easily. This may help process video with slight blurring between the
|
||||
fields, but may also cause interlaced frames in the output.
|
||||
easily. This may help processing of video where there is slight
|
||||
blurring between the fields, but may also cause there to be interlaced
|
||||
frames in the output.
|
||||
|
||||
``mp`` (metric plane)
|
||||
This option may be set to ``u`` or ``v`` to use a chroma plane instead of the
|
||||
@@ -530,32 +553,169 @@ Available mpv-only filters are:
|
||||
video. The main purpose of setting ``mp`` to a chroma plane is to reduce
|
||||
CPU load and make pullup usable in realtime on slow machines.
|
||||
|
||||
``yadif=[mode:interlaced-only]``
|
||||
``divtc[=options]``
|
||||
Inverse telecine for deinterlaced video. If 3:2-pulldown telecined video
|
||||
has lost one of the fields or is deinterlaced using a method that keeps
|
||||
one field and interpolates the other, the result is a juddering video that
|
||||
has every fourth frame duplicated. This filter is intended to find and
|
||||
drop those duplicates and restore the original film framerate. Two
|
||||
different modes are available: One-pass mode is the default and is
|
||||
straightforward to use, but has the disadvantage that any changes in the
|
||||
telecine phase (lost frames or bad edits) cause momentary judder until the
|
||||
filter can resync again. Two-pass mode avoids this by analyzing the entire
|
||||
video beforehand so it will have forward knowledge about the phase changes
|
||||
and can resync at the exact spot. These passes do *not* correspond to pass
|
||||
one and two of the encoding process. You must run an extra pass using
|
||||
``divtc`` pass one before the actual encoding throwing the resulting video
|
||||
away. Then use ``divtc`` pass two for the actual encoding. If you use
|
||||
multiple encoder passes, use ``divtc`` pass two for all of them.
|
||||
|
||||
The options are:
|
||||
|
||||
``pass=1|2``
|
||||
Use two pass mode.
|
||||
|
||||
``file=<filename>``
|
||||
Set the two pass log filename (default: ``framediff.log``).
|
||||
|
||||
``threshold=<value>``
|
||||
Set the minimum strength the telecine pattern must have for the filter
|
||||
to believe in it (default: 0.5). This is used to avoid recognizing
|
||||
false pattern from the parts of the video that are very dark or very
|
||||
still.
|
||||
|
||||
``window=<numframes>``
|
||||
Set the number of past frames to look at when searching for pattern
|
||||
(default: 30). Longer window improves the reliability of the pattern
|
||||
search, but shorter window improves the reaction time to the changes
|
||||
in the telecine phase. This only affects the one-pass mode. The
|
||||
two-pass mode currently uses fixed window that extends to both future
|
||||
and past.
|
||||
|
||||
``phase=0|1|2|3|4``
|
||||
Sets the initial telecine phase for one pass mode (default: 0). The
|
||||
two-pass mode can see the future, so it is able to use the correct
|
||||
phase from the beginning, but one-pass mode can only guess. It catches
|
||||
the correct phase when it finds it, but this option can be used to fix
|
||||
the possible juddering at the beginning. The first pass of the two
|
||||
pass mode also uses this, so if you save the output from the first
|
||||
pass, you get constant phase result.
|
||||
|
||||
``deghost=<value>``
|
||||
Set the deghosting threshold (0-255 for one-pass mode, -255-255 for
|
||||
two-pass mode, default 0). If nonzero, deghosting mode is used. This
|
||||
is for video that has been deinterlaced by blending the fields
|
||||
together instead of dropping one of the fields. Deghosting amplifies
|
||||
any compression artifacts in the blended frames, so the parameter
|
||||
value is used as a threshold to exclude those pixels from deghosting
|
||||
that differ from the previous frame less than specified value. If two
|
||||
pass mode is used, then negative value can be used to make the filter
|
||||
analyze the whole video in the beginning of pass-2 to determine
|
||||
whether it needs deghosting or not and then select either zero or the
|
||||
absolute value of the parameter. Specify this option for pass 2, it
|
||||
makes no difference on pass 1.
|
||||
|
||||
``phase[=t|b|p|a|u|T|B|A|U][:v]``
|
||||
Delay interlaced video by one field time so that the field order changes.
|
||||
The intended use is to fix PAL videos that have been captured with the
|
||||
opposite field order to the film-to-video transfer. The options are:
|
||||
|
||||
``t``
|
||||
Capture field order top-first, transfer bottom-first. Filter will
|
||||
delay the bottom field.
|
||||
|
||||
``b``
|
||||
Capture bottom-first, transfer top-first. Filter will delay the top
|
||||
field.
|
||||
|
||||
``p``
|
||||
Capture and transfer with the same field order. This mode only exists
|
||||
for the documentation of the other options to refer to, but if you
|
||||
actually select it, the filter will faithfully do nothing ;-)
|
||||
|
||||
``a``
|
||||
Capture field order determined automatically by field flags, transfer
|
||||
opposite. Filter selects among ``t`` and ``b`` modes on a frame by frame
|
||||
basis using field flags. If no field information is available, then this
|
||||
works just like ``u``.
|
||||
|
||||
``u``
|
||||
Capture unknown or varying, transfer opposite. Filter selects among
|
||||
``t`` and ``b`` on a frame by frame basis by analyzing the images and
|
||||
selecting the alternative that produces best match between the fields.
|
||||
|
||||
``T``
|
||||
Capture top-first, transfer unknown or varying. Filter selects among
|
||||
``t`` and ``p`` using image analysis.
|
||||
|
||||
``B``
|
||||
Capture bottom-first, transfer unknown or varying. Filter selects
|
||||
among ``b`` and ``p`` using image analysis.
|
||||
|
||||
``A``
|
||||
Capture determined by field flags, transfer unknown or varying. Filter
|
||||
selects among ``t``, ``b`` and ``p`` using field flags and image
|
||||
analysis. If no field information is available, then this works just
|
||||
like ``U``. This is the default mode.
|
||||
|
||||
``U``
|
||||
Both capture and transfer unknown or varying. Filter selects among
|
||||
``t``, ``b`` and ``p`` using image analysis only.
|
||||
|
||||
``v``
|
||||
Verbose operation. Prints the selected mode for each frame and the
|
||||
average squared difference between fields for ``t``, ``b``, and ``p``
|
||||
alternatives. (Ignored when libavfilter is used.)
|
||||
|
||||
``yadif=[mode[:enabled=yes|no]]``
|
||||
Yet another deinterlacing filter
|
||||
|
||||
``<mode>``
|
||||
:frame: Output 1 frame for each frame.
|
||||
:field: Output 1 frame for each field (default).
|
||||
:field: Output 1 frame for each field.
|
||||
:frame-nospatial: Like ``frame`` but skips spatial interlacing check.
|
||||
:field-nospatial: Like ``field`` but skips spatial interlacing check.
|
||||
|
||||
``<interlaced-only>``
|
||||
:no: Deinterlace all frames.
|
||||
:yes: Only deinterlace frames marked as interlaced (default).
|
||||
``<enabled>``
|
||||
:yes: Filter is active (default).
|
||||
:no: Filter is not active, but can be activated with the ``D`` key
|
||||
(or any other key that toggles the ``deinterlace`` property).
|
||||
|
||||
This filter is automatically inserted when using the ``d`` key (or any
|
||||
This filter, is automatically inserted when using the ``D`` key (or any
|
||||
other key that toggles the ``deinterlace`` property or when using the
|
||||
``--deinterlace`` switch), assuming the video output does not have native
|
||||
deinterlacing support.
|
||||
|
||||
If you just want to set the default mode, put this filter and its options
|
||||
into ``--vf-defaults`` instead, and enable deinterlacing with ``d`` or
|
||||
into ``--vf-defaults`` instead, and enable deinterlacing with ``D`` or
|
||||
``--deinterlace``.
|
||||
|
||||
Also, note that the ``d`` key is stupid enough to insert a deinterlacer twice
|
||||
Also note that the ``D`` key is stupid enough to insert an interlacer twice
|
||||
when inserting yadif with ``--vf``, so using the above methods is
|
||||
recommended.
|
||||
|
||||
``delogo[=x:y:w:h:t:show]``
|
||||
Suppresses a TV station logo by a simple interpolation of the surrounding
|
||||
pixels. Just set a rectangle covering the logo and watch it disappear (and
|
||||
sometimes something even uglier appear - your mileage may vary).
|
||||
|
||||
``<x>,<y>``
|
||||
top left corner of the logo
|
||||
``<w>,<h>``
|
||||
width and height of the cleared rectangle
|
||||
``<t>``
|
||||
Thickness of the fuzzy edge of the rectangle (added to ``w`` and
|
||||
``h``). When set to -1, a green rectangle is drawn on the screen to
|
||||
simplify finding the right ``x``,``y``,``w``,``h`` parameters.
|
||||
``show``
|
||||
Draw a rectangle showing the area defined by x/y/w/h.
|
||||
|
||||
``screenshot``
|
||||
Optional filter for screenshot support. This is only needed if the video
|
||||
output does not provide working direct screenshot support. Note that it is
|
||||
not always safe to insert this filter by default. See `TAKING SCREENSHOTS`_
|
||||
for details.
|
||||
|
||||
``sub=[=bottom-margin:top-margin]``
|
||||
Moves subtitle rendering to an arbitrary point in the filter chain, or force
|
||||
subtitle rendering in the video filter as opposed to using video output OSD
|
||||
@@ -563,9 +723,9 @@ Available mpv-only filters are:
|
||||
|
||||
``<bottom-margin>``
|
||||
Adds a black band at the bottom of the frame. The SSA/ASS renderer can
|
||||
place subtitles there (with ``--sub-use-margins``).
|
||||
place subtitles there (with ``--ass-use-margins``).
|
||||
``<top-margin>``
|
||||
Black band on the top for toptitles (with ``--sub-use-margins``).
|
||||
Black band on the top for toptitles (with ``--ass-use-margins``).
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
@@ -659,6 +819,27 @@ Available mpv-only filters are:
|
||||
size of the filter in percent of the image diagonal size. This is
|
||||
used to calculate the final radius size (default: 1).
|
||||
|
||||
|
||||
``dlopen=dll[:a0[:a1[:a2[:a3]]]]``
|
||||
Loads an external library to filter the image. The library interface
|
||||
is the ``vf_dlopen`` interface specified using ``libmpcodecs/vf_dlopen.h``.
|
||||
|
||||
``dll=<library>``
|
||||
Specify the library to load. This may require a full file system path
|
||||
in some cases. This argument is required.
|
||||
|
||||
``a0=<string>``
|
||||
Specify the first parameter to pass to the library.
|
||||
|
||||
``a1=<string>``
|
||||
Specify the second parameter to pass to the library.
|
||||
|
||||
``a2=<string>``
|
||||
Specify the third parameter to pass to the library.
|
||||
|
||||
``a3=<string>``
|
||||
Specify the fourth parameter to pass to the library.
|
||||
|
||||
``vapoursynth=file:buffered-frames:concurrent-frames``
|
||||
Loads a VapourSynth filter script. This is intended for streamed
|
||||
processing: mpv actually provides a source filter, instead of using a
|
||||
@@ -701,11 +882,10 @@ Available mpv-only filters are:
|
||||
``buffered-frames``
|
||||
Maximum number of decoded video frames that should be buffered before
|
||||
the filter (default: 4). This specifies the maximum number of frames
|
||||
the script can request in reverse direction.
|
||||
E.g. if ``buffered-frames=5``, and the script just requested frame 15,
|
||||
it can still request frame 10, but frame 9 is not available anymore.
|
||||
If it requests frame 30, mpv will decode 15 more frames, and keep only
|
||||
frames 25-30.
|
||||
the script can requests backwards. E.g. if ``buffered-frames=5``, and
|
||||
the script just requested frame 15, it can still request frame 10, but
|
||||
frame 9 is not available anymore. If it requests frame 30, mpv will
|
||||
decode 15 more frames, and keep only frames 25-30.
|
||||
|
||||
The actual number of buffered frames also depends on the value of the
|
||||
``concurrent-frames`` option. Currently, both option values are
|
||||
@@ -717,68 +897,17 @@ Available mpv-only filters are:
|
||||
filters work anyway.)
|
||||
|
||||
``concurrent-frames``
|
||||
Number of frames that should be requested in parallel. The
|
||||
Number of frames that should be requested in parallel (default: 2). The
|
||||
level of concurrency depends on the filter and how quickly mpv can
|
||||
decode video to feed the filter. This value should probably be
|
||||
proportional to the number of cores on your machine. Most time,
|
||||
making it higher than the number of cores can actually make it
|
||||
slower.
|
||||
|
||||
By default, this uses the special value ``auto``, which sets the option
|
||||
to the number of detected logical CPU cores.
|
||||
|
||||
The following variables are defined by mpv:
|
||||
|
||||
``video_in``
|
||||
The mpv video source as vapoursynth clip. Note that this has no length
|
||||
set, which confuses many filters. Using ``Trim`` on the clip with a
|
||||
high dummy length can turn it into a finite clip.
|
||||
|
||||
``video_in_dw``, ``video_in_dh``
|
||||
Display size of the video. Can be different from video size if the
|
||||
video does not use square pixels (e.g. DVD).
|
||||
|
||||
``container_fps``
|
||||
FPS value as reported by file headers. This value can be wrong or
|
||||
completely broken (e.g. 0 or NaN). Even if the value is correct,
|
||||
if another filter changes the real FPS (by dropping or inserting
|
||||
frames), the value of this variable might not be useful. Note that
|
||||
the ``--fps`` command line option overrides this value.
|
||||
|
||||
Useful for some filters which insist on having a FPS.
|
||||
|
||||
``display_fps``
|
||||
Refresh rate of the current display. Note that this value can be 0.
|
||||
|
||||
``vapoursynth-lazy``
|
||||
The same as ``vapoursynth``, but doesn't load Python scripts. Instead, a
|
||||
custom backend using Lua and the raw VapourSynth API is used. The syntax
|
||||
is completely different, and absolutely no convenience features are
|
||||
provided. There's no type checking either, and you can trigger crashes.
|
||||
|
||||
.. admonition:: Example:
|
||||
|
||||
::
|
||||
|
||||
video_out = invoke("morpho", "Open", {clip = video_in})
|
||||
|
||||
The special variable ``video_in`` is the mpv video source, while the
|
||||
special variable ``video_out`` is used to read video from. The 1st argument
|
||||
is the plugin (queried with ``getPluginByNs``), the 2nd is the filter name,
|
||||
and the 3rd argument is a table with the arguments. Positional arguments
|
||||
are not supported. The types must match exactly. Since Lua is terrible and
|
||||
can't distinguish integers and floats, integer arguments must be prefixed
|
||||
with ``i_``, in which case the prefix is removed and the argument is cast
|
||||
to an integer. Should the argument's name start with ``i_``, you're out of
|
||||
luck.
|
||||
|
||||
Clips (VSNodeRef) are passed as light userdata, so trying to pass any
|
||||
other userdata type will result in hard crashes.
|
||||
|
||||
``vavpp``
|
||||
VA-AP-API video post processing. Works with ``--vo=vaapi`` and ``--vo=opengl``
|
||||
only. Currently deinterlaces. This filter is automatically inserted if
|
||||
deinterlacing is requested (either using the ``d`` key, by default mapped to
|
||||
deinterlacing is requested (either using the ``D`` key, by default mapped to
|
||||
the command ``cycle deinterlace``, or the ``--deinterlace`` option).
|
||||
|
||||
``deint=<method>``
|
||||
@@ -790,28 +919,11 @@ Available mpv-only filters are:
|
||||
Show only first field (going by ``--field-dominance``).
|
||||
bob
|
||||
bob deinterlacing (default).
|
||||
weave, motion-adaptive, motion-compensated
|
||||
Advanced deinterlacing algorithms. Whether these actually work
|
||||
depends on the GPU hardware, the GPU drivers, driver bugs, and
|
||||
mpv bugs.
|
||||
|
||||
``<interlaced-only>``
|
||||
:no: Deinterlace all frames.
|
||||
:yes: Only deinterlace frames marked as interlaced (default).
|
||||
|
||||
``reversal-bug=<yes|no>``
|
||||
:no: Use the API as it was interpreted by older Mesa drivers. While
|
||||
this interpretation was more obvious and inuitive, it was
|
||||
apparently wrong, and not shared by Intel driver developers.
|
||||
:yes: Use Intel interpretation of surface forward and backwards
|
||||
references (default). This is what Intel drivers and newer Mesa
|
||||
drivers expect. Matters only for the advanced deinterlacing
|
||||
algorithms.
|
||||
|
||||
``vdpaupp``
|
||||
VDPAU video post processing. Works with ``--vo=vdpau`` and ``--vo=opengl``
|
||||
only. This filter is automatically inserted if deinterlacing is requested
|
||||
(either using the ``d`` key, by default mapped to the command
|
||||
(either using the ``D`` key, by default mapped to the command
|
||||
``cycle deinterlace``, or the ``--deinterlace`` option). When enabling
|
||||
deinterlacing, it is always preferred over software deinterlacer filters
|
||||
if the ``vdpau`` VO is used, and also if ``opengl`` is used and hardware
|
||||
@@ -852,31 +964,14 @@ Available mpv-only filters are:
|
||||
``pullup``
|
||||
Try to apply inverse telecine, needs motion adaptive temporal
|
||||
deinterlacing.
|
||||
``interlaced-only=<yes|no>``
|
||||
If ``yes`` (default), only deinterlace frames marked as interlaced.
|
||||
``hqscaling=<0-9>``
|
||||
0
|
||||
Use default VDPAU scaling (default).
|
||||
1-9
|
||||
Apply high quality VDPAU scaling (needs capable hardware).
|
||||
|
||||
``d3d11vpp``
|
||||
Direct3D 11 video post processing. Currently requires D3D11 hardware
|
||||
decoding for use.
|
||||
|
||||
``deint=<yes|no>``
|
||||
Whether deinterlacing is enabled (default: no).
|
||||
``interlaced-only=<yes|no>``
|
||||
If ``yes`` (default), only deinterlace frames marked as interlaced.
|
||||
``mode=<blend|bob|adaptive|mocomp|ivctc|none>``
|
||||
Tries to select a video processor with the given processing capability.
|
||||
If a video processor supports multiple capabilities, it is not clear
|
||||
which algorithm is actually selected. ``none`` always falls back. On
|
||||
most if not all hardware, this option will probably do nothing, because
|
||||
a video processor usually supports all modes or none.
|
||||
|
||||
``buffer=<num>``
|
||||
Buffer ``<num>`` frames in the filter chain. This filter is probably pretty
|
||||
useless, except for debugging. (Note that this won't help to smooth out
|
||||
useless, except for debugging. (Note that this won't help smoothing out
|
||||
latencies with decoding, because the filter will never output a frame if
|
||||
the buffer isn't full, except on EOF.)
|
||||
+580
-207
File diff suppressed because it is too large.
Load diff
@@ -1,456 +0,0 @@
|
||||
CHANGES FROM OTHER VERSIONS OF MPLAYER
|
||||
======================================
|
||||
|
||||
**mpv** is based on mplayer2, which in turn is based on the original MPlayer
|
||||
(also called mplayer, mplayer-svn, mplayer1). Many changes have been made, a
|
||||
large part of which is incompatible or completely changes how the player
|
||||
behaves. Although there are still many similarities to its ancestors, **mpv**
|
||||
should generally be treated as a completely different program.
|
||||
|
||||
.. admonition:: Warning
|
||||
|
||||
This document is **not updated** anymore, and is **incomplete** and
|
||||
**outdated**. If you look for old option replacements, always check with
|
||||
the current mpv manpage, as the options could have changed meanwhile.
|
||||
|
||||
General Changes from MPlayer to mpv
|
||||
-----------------------------------
|
||||
|
||||
This listing is about changes introduced by mplayer2 and mpv relatively to
|
||||
MPlayer.
|
||||
|
||||
Player
|
||||
~~~~~~
|
||||
|
||||
* New name for the binary (``mpv``). New location for config files (either
|
||||
``~/.config/mpv/mpv.conf``, or if you want, ``~/.mpv/config``).
|
||||
* Encoding functionality (replacement for MEncoder, see the `ENCODING`_ section).
|
||||
* Support for Lua scripting (see the `LUA SCRIPTING`_ section).
|
||||
* Better pause handling (e.g. do not unpause on a command).
|
||||
* Precise seeking support.
|
||||
* Improvements in audio/video sync handling.
|
||||
* Do not lose settings when playing a new file in the same player instance.
|
||||
* Slave mode compatibility broken (see below).
|
||||
* Re-enable screensaver while the player is paused.
|
||||
* Allow resuming playback at a later point with ``Shift+q``, also see the
|
||||
``quit-watch-later`` input command.
|
||||
* ``--keep-open`` option to stop the player from closing the window and
|
||||
exiting after playback ends.
|
||||
* A client API, that allows embedding **mpv** into applications
|
||||
(see ``libmpv/client.h`` in the sources).
|
||||
|
||||
Input
|
||||
~~~~~
|
||||
|
||||
* Improved default keybindings. MPlayer bindings are also available (see
|
||||
``etc/mplayer-input.conf`` in the source tree).
|
||||
* Improved responsiveness on user input.
|
||||
* Support for modifier keys (alt, shift, ctrl) in input.conf.
|
||||
* Allow customizing whether a key binding for seeking shows the video time, the
|
||||
OSD bar, or nothing (see the `Input Command Prefixes`_ section).
|
||||
* Support mapping multiple commands to one key.
|
||||
* Classic LIRC support was removed. Install remotes as input devices instead.
|
||||
This way they will send X11 key events to the mpv window, which can be bound
|
||||
using the normal ``input.conf``.
|
||||
Also see: http://github.com/mpv-player/mpv/wiki/IR-remotes
|
||||
* Joystick support was removed. It was considered useless and was the cause
|
||||
of some problems (e.g. a laptop's accelerator being recognized as joystick).
|
||||
* Support for relative seeking by percentage.
|
||||
|
||||
Audio
|
||||
~~~~~
|
||||
|
||||
* Support for gapless audio (see the ``--gapless-audio`` option).
|
||||
* Support for OSS4 volume control.
|
||||
* Improved support for PulseAudio.
|
||||
* Make ``--softvol`` default (**mpv** is not a mixer control panel).
|
||||
* By default, do pitch correction if playback speed is increased.
|
||||
* Improved downmixing and output of surround audio:
|
||||
|
||||
- Instead of using hardcoded pan filters to do remixing, libavresample is used
|
||||
- Channel maps are used to identify the channel layout, so e.g. ``3.0`` and
|
||||
``2.1`` audio can be distinguished.
|
||||
|
||||
Video
|
||||
~~~~~
|
||||
|
||||
* Wayland support.
|
||||
* Native support for VAAPI and VDA. Improved VDPAU video output.
|
||||
* Improved OpenGL output (see the ``opengl-hq`` video output).
|
||||
* Make hardware decoding work with the ``opengl`` video output.
|
||||
* Support for libavfilter (for video->video and audio->audio). This allows
|
||||
using most of FFmpeg's filters, which improve greatly on the old MPlayer
|
||||
filters in features, performance, and correctness.
|
||||
* More correct color reproduction (color matrix generation), including support
|
||||
for BT.2020 (Ultra HD). linear XYZ (Digital Cinema) and SMPTE ST2084 (HDR)
|
||||
inputs.
|
||||
* Support for color managed displays, via ICC profiles.
|
||||
* High-quality image resamplers (see the ``opengl`` ``scale`` suboption).
|
||||
* Support for scaling in (sigmoidized) linear light.
|
||||
* Better subtitle rendering using libass by default.
|
||||
* Improvements when playing multiple files (``-fixed-vo`` is default, do not
|
||||
reset settings by default when playing a new file).
|
||||
* Replace image video outputs (``--vo=jpeg`` etc.) with ``--vo=image``.
|
||||
* Removal of ``--vo=gif89a``, ``--vo=md5sum``, ``--vo=yuv4mpeg``, as encoding
|
||||
can handle these use cases. For yuv4mpeg, for example, use::
|
||||
|
||||
mpv input.mkv -o output.y4m --no-audio --oautofps --oneverdrop
|
||||
|
||||
* Image subtitles (DVDs etc.) are rendered in color and use more correct
|
||||
positioning (color for image subs can be disabled with ``--sub-gray``).
|
||||
* Support for the X11 video output is removed, since it was considered
|
||||
deprecated. SDL video output can still be used as a fallback.
|
||||
|
||||
OSD and terminal
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* Cleaned up terminal output: nicer status line, less useless noise.
|
||||
* Improved OSD rendering using libass, with full Unicode support.
|
||||
* New OSD bar with chapter marks. Not positioned in the middle of the video
|
||||
(this can be customized with the ``--osd-bar-align-y`` option).
|
||||
* Display list of chapters and audio/subtitle tracks on OSD (see the
|
||||
`Properties`_ section).
|
||||
|
||||
Screenshots
|
||||
~~~~~~~~~~~
|
||||
|
||||
* Instant screenshots without 1-frame delay.
|
||||
* Support for taking screenshots even with hardware decoding.
|
||||
* Support for saving screenshots as JPEG or PNG.
|
||||
* Support for configurable file names.
|
||||
* Support for taking screenshots with or without subtitles.
|
||||
|
||||
Note that the ``screenshot`` video filter is not needed anymore, and should not
|
||||
be put into the mpv config file.
|
||||
|
||||
Miscellaneous
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* Better MKV support (e.g. ordered chapters, 3D metadata).
|
||||
* Matroska edition switching at runtime.
|
||||
* Support for playing URLs of popular streaming sites directly.
|
||||
(e.g. ``mpv https://www.youtube.com/watch?v=...``).
|
||||
Requires a recent version of ``youtube-dl`` to be installed. Can be
|
||||
disabled with ``ytdl=no`` in the mpv config file.
|
||||
* Support for precise scrolling which scales the parameter of commands. If the
|
||||
input doesn't support precise scrolling the scale factor stays 1.
|
||||
* Allow changing/adjusting video filters at runtime. (This is also used to make
|
||||
the ``D`` key insert vf_yadif if deinterlacing is not supported otherwise).
|
||||
* Improved support for .cue files.
|
||||
|
||||
Mac OS X
|
||||
~~~~~~~~
|
||||
|
||||
* Native OpenGL backend.
|
||||
* Cocoa event loop is independent from MPlayer's event loop, so user
|
||||
actions like accessing menus and live resizing do not block the playback.
|
||||
* Apple Remote support.
|
||||
* Media Keys support.
|
||||
* VDA support using libavcodec hwaccel API instead of FFmpeg's decoder with up
|
||||
to 2-2.5x reduction in CPU usage.
|
||||
|
||||
Windows
|
||||
~~~~~~~
|
||||
|
||||
* Improved support for Unicode file names.
|
||||
* Improved window handling.
|
||||
* Do not block playback when moving the window.
|
||||
* Improved Direct3D video output.
|
||||
* Added WASAPI audio output.
|
||||
|
||||
Internal changes
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* Switch to GPLv2+ (see ``Copyright`` file for details).
|
||||
* Removal of lots of cruft:
|
||||
|
||||
- Internal GUI (replaced by the OSC, see the `ON SCREEN CONTROLLER`_ section).
|
||||
- MEncoder (replaced by native encoding, see the `ENCODING`_ section).
|
||||
- OSD menu.
|
||||
- Kernel video drivers for Linux 2.4 (including VIDIX).
|
||||
- Teletext support.
|
||||
- Support for dead platforms.
|
||||
- Most built-in demuxers have been replaced by their libavformat counterparts.
|
||||
- Built-in network support has been replaced by libavformat's (which also
|
||||
supports https URLs).
|
||||
- Embedded copies of libraries (such as FFmpeg).
|
||||
|
||||
* General code cleanups (including refactoring or rewrites of many parts).
|
||||
* New build system.
|
||||
* Many bug fixes and removal of long-standing issues.
|
||||
* Generally preferring FFmpeg/Libav over internal demuxers, decoders, and
|
||||
filters.
|
||||
|
||||
Detailed Listing of User-visible Changes
|
||||
----------------------------------------
|
||||
|
||||
This listing is about changed command line switches, slave commands, and similar
|
||||
things. Completely removed features are not listed.
|
||||
|
||||
Command Line Switches
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* There is a new command line syntax, which is generally preferred over the old
|
||||
syntax. ``-optname optvalue`` becomes ``--optname=optvalue``.
|
||||
|
||||
The old syntax will not be removed. However, the new syntax is mentioned in
|
||||
all documentation and so on, and unlike the old syntax is not ambiguous,
|
||||
so it is a good thing to know about this change.
|
||||
* In general, negating switches like ``-noopt`` now have to be written as
|
||||
``-no-opt`` or ``--no-opt``.
|
||||
* Per-file options are not the default anymore. You can explicitly specify
|
||||
file-local options. See ``Usage`` section.
|
||||
* Many options have been renamed, removed or changed semantics. Some options
|
||||
that are required for a good playback experience with MPlayer are now
|
||||
superfluous or even worse than the defaults, so make sure to read the manual
|
||||
before trying to use your existing configuration with **mpv**.
|
||||
* Table of renamed/replaced switches:
|
||||
|
||||
=========================== ========================================
|
||||
Old New
|
||||
=========================== ========================================
|
||||
``-no<opt>`` ``--no-<opt>`` (add a dash)
|
||||
``-a52drc level`` ``--ad-lavc-ac3drc=level``
|
||||
``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)
|
||||
``-af volnorm`` (removed; use acompressor ffmpeg filter instead)
|
||||
``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``
|
||||
``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
|
||||
``-aspect`` ``--video-aspect``
|
||||
``-ass-bottom-margin`` ``--vf=sub=bottom:top``
|
||||
``-ass`` ``--sub-ass``
|
||||
``-audiofile-cache`` (removed; the main cache settings are used)
|
||||
``-audiofile`` ``--audio-file``
|
||||
``-benchmark`` ``--untimed`` (no stats)
|
||||
``-capture`` ``--stream-capture=<filename>``
|
||||
``-channels`` ``--audio-channels`` (changed semantics)
|
||||
``-cursor-autohide-delay`` ``--cursor-autohide``
|
||||
``-delay`` ``--audio-delay``
|
||||
``-dumpstream`` ``--stream-dump=<filename>``
|
||||
``-dvdangle`` ``--dvd-angle``
|
||||
``-endpos`` ``--length``
|
||||
``-fixed-vo`` (removed; always the default)
|
||||
``-font`` ``--osd-font``
|
||||
``-forcedsubsonly`` ``--sub-forced-only``
|
||||
``-forceidx`` ``--index``
|
||||
``-format`` ``--audio-format``
|
||||
``-fsmode-dontuse`` (removed)
|
||||
``-fstype`` ``--x11-netwm`` (changed semantics)
|
||||
``-hardframedrop`` ``--framedrop=hard``
|
||||
``-identify`` (removed; use TOOLS/mpv_identify.sh)
|
||||
``-idx`` ``--index``
|
||||
``-lavdopts ...`` ``--vd-lavc-...``
|
||||
``-lavfdopts`` ``--demuxer-lavf-...``
|
||||
``-loop 0`` ``--loop=inf``
|
||||
``-mixer-channel`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mixer`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mouse-movements`` ``--input-cursor``
|
||||
``-msgcolor`` ``--msg-color``
|
||||
``-msglevel`` ``--msg-level`` (changed semantics)
|
||||
``-msgmodule`` ``--msg-module``
|
||||
``-name`` ``--x11-name``
|
||||
``-noar`` ``--no-input-appleremote``
|
||||
``-noautosub`` ``--no-sub-auto``
|
||||
``-noconsolecontrols`` ``--no-input-terminal``
|
||||
``-nosound`` ``--no-audio``
|
||||
``-osdlevel`` ``--osd-level``
|
||||
``-panscanrange`` ``--video-zoom``, ``--video-pan-x/y``
|
||||
``-playing-msg`` ``--term-playing-msg``
|
||||
``-pp ...`` ``'--vf=lavfi=[pp=...]'``
|
||||
``-pphelp`` (See FFmpeg libavfilter documentation.)
|
||||
``-rawaudio ...`` ``--demuxer-rawaudio-...``
|
||||
``-rawvideo ...`` ``--demuxer-rawvideo-...``
|
||||
``-spugauss`` ``--sub-gauss``
|
||||
``-srate`` ``--audio-samplerate``
|
||||
``-ss`` ``--start``
|
||||
``-ssf <sub>`` ``--sws-...``
|
||||
``-stop-xscreensaver`` ``--stop-screensaver``
|
||||
``-sub-fuzziness`` ``--sub-auto``
|
||||
``-sub-text-*`` ``--sub-*``
|
||||
``-sub`` ``--sub-file``
|
||||
``-subcp`` ``--sub-codepage``
|
||||
``-subdelay`` ``--sub-delay``
|
||||
``-subfile`` ``--sub-file``
|
||||
``-subfont-*`` ``--sub-*``, ``--osd-*``
|
||||
``-subfont-text-scale`` ``--sub-scale``
|
||||
``-subfont`` ``--sub-font``
|
||||
``-subfps`` ``--sub-fps``
|
||||
``-subpos`` ``--sub-pos``
|
||||
``-sws`` ``--sws-scaler``
|
||||
``-tvscan`` ``--tv-scan``
|
||||
``-use-filename-title`` ``--title='${filename}'``
|
||||
``-vc ffh264vdpau`` (etc.) ``--hwdec=vdpau``
|
||||
``-vobsub`` ``--sub-file`` (pass the .idx file)
|
||||
``-x W``, ``-y H`` ``--geometry=WxH`` + ``--no-keepaspect``
|
||||
``-xineramascreen`` ``--screen`` (different values)
|
||||
``-xy W`` ``--autofit=W``
|
||||
``-zoom`` Inverse available as ``--video-unscaled``
|
||||
``dvdnav://`` Removed.
|
||||
``dvd://1`` ``dvd://0`` (0-based offset)
|
||||
=========================== ========================================
|
||||
|
||||
.. note::
|
||||
|
||||
``-opt val`` becomes ``--opt=val``.
|
||||
|
||||
.. note::
|
||||
|
||||
Quite some video filters, video outputs, audio filters, audio outputs, had
|
||||
changes in their option parsing. These aren't mentioned in the table above.
|
||||
|
||||
Also, some video and audio filters have been removed, and you have to use
|
||||
libavfilter (using ``--vf=lavfi=[...]`` or ``--af=lavfi=[...]``) to get
|
||||
them back.
|
||||
|
||||
input.conf and Slave Commands
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Table of renamed input commands:
|
||||
|
||||
This lists only commands that are not always gracefully handled by the
|
||||
internal legacy translation layer. If an input.conf contains any legacy
|
||||
commands, a warning will be printed when starting the player. The warnings
|
||||
also show the replacement commands.
|
||||
|
||||
Properties containing ``_`` to separate words use ``-`` instead.
|
||||
|
||||
+--------------------------------+----------------------------------------+
|
||||
| Old | New |
|
||||
+================================+========================================+
|
||||
| ``pt_step 1 [0|1]`` | ``playlist-next [weak|force]`` |
|
||||
| | (translation layer cannot deal with |
|
||||
| | whitespace) |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``pt_step -1 [0|1]`` | ``playlist-prev [weak|force] (same)`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``switch_ratio [<ratio>]`` | ``set video-aspect <ratio>`` |
|
||||
| | |
|
||||
| | ``set video-aspect 0`` (reset aspect) |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``step_property_osd <prop>`` | ``cycle <prop> <step>`` (wraps), |
|
||||
| ``<step> <dir>`` | ``add <prop> <step>`` (clamps). |
|
||||
| | ``<dir>`` parameter unsupported. Use |
|
||||
| | a negative ``<step>`` instead. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``step_property <prop>`` | Prefix ``cycle`` or ``add`` with |
|
||||
| ``<step> <dir>`` | ``no-osd``: ``no-osd cycle <prop>`` |
|
||||
| | ``<step>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``osd_show_property_text`` | ``show-text <text>`` |
|
||||
| ``<text>`` | The property expansion format string |
|
||||
| | syntax slightly changed. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``osd_show_text`` | Now does the same as |
|
||||
| | ``osd_show_property_text``. Use the |
|
||||
| | ``raw`` prefix to disable property |
|
||||
| | expansion. |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``show_tracks`` | ``show-text ${track-list}`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``show_chapters`` | ``show-text ${chapter-list}`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_start_scan`` | ``set tv-scan yes`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_channel <val>`` | ``set tv-channel <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_channel`` | ``cycle tv-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_set_channel <v1> <v2>`` | ``set dvb-channel <v1>-<v2>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_step_channel`` | ``cycle dvb-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_freq <val>`` | ``set tv-freq <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_freq`` | ``cycle tv-freq`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_norm <norm>`` | ``set tv-norm <norm>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_norm`` | ``cycle tv-norm`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
Due to lack of hardware and users using the TV/DVB/PVR features, and
|
||||
due to the need to cleanup the related command code, it's possible
|
||||
that the new commands are buggy or behave worse. This can be improved
|
||||
if testers are available. Otherwise, some of the TV code will be
|
||||
removed at some point.
|
||||
|
||||
Slave mode
|
||||
~~~~~~~~~~
|
||||
|
||||
* Slave mode was removed. A proper slave mode application needed tons of code
|
||||
and hacks to get
|
||||
it right. The main problem is that slave mode is a bad and incomplete
|
||||
interface, and to get around that, applications parsed output messages
|
||||
intended for users. It is hard to know which messages exactly are parsed by
|
||||
slave mode applications. This makes it virtually impossible to improve
|
||||
terminal output intended for users without possibly breaking something.
|
||||
|
||||
This is absolutely insane, and since initial improvements to **mpv** quickly
|
||||
made slave mode incompatible to most applications, it was removed as useless
|
||||
cruft. The client API (see below) is provided instead.
|
||||
|
||||
``--identify`` was replaced by the ``TOOLS/mpv_identify.sh`` wrapper script.
|
||||
|
||||
* For some time (until including release 0.4.x), mpv supported a
|
||||
``--slave-broken`` option. The following options are equivalent:
|
||||
|
||||
::
|
||||
|
||||
--input-file=/dev/stdin --input-terminal=no
|
||||
|
||||
|
||||
Assuming the system supports ``/dev/stdin``.
|
||||
|
||||
(The option was added back in 0.5.1 and sets exactly these options. It was
|
||||
removed in 0.10.x again.)
|
||||
|
||||
* A JSON RPC protocol giving access to the client API is also supported. See
|
||||
`JSON IPC`_ for more information.
|
||||
|
||||
* **mpv** also provides a client API, which can be used to embed the player
|
||||
by loading it as shared library. (See ``libmpv/client.h`` in the sources.)
|
||||
It might also be possible to implement a custom slave mode-like protocol
|
||||
using Lua scripting.
|
||||
|
||||
Policy for Removed Features
|
||||
---------------------------
|
||||
|
||||
**mpv** is in active development. If something is in the way of more important
|
||||
development (such as fixing bugs or implementing new features), we sometimes
|
||||
remove features. Usually this happens only with old features that either seem
|
||||
to be useless, or are not used by anyone. Often these are obscure, or
|
||||
"inherited", or were marked experimental, but never received any particular
|
||||
praise by any users.
|
||||
|
||||
Sometimes, features are replaced by something new. The new code will be either
|
||||
simpler or more powerful, but doesn't necessarily provide everything the old
|
||||
feature did.
|
||||
|
||||
We can not exclude that we accidentally remove features that are actually
|
||||
popular. Generally, we do not know how much a specific functionality is used.
|
||||
If you miss a feature and think it should be re-added, please open an issue
|
||||
on the mpv bug tracker. Hopefully, a solution can be found. Often, it turns
|
||||
out that re-adding something is not much of a problem, or that there are
|
||||
better alternatives.
|
||||
|
||||
Why this Fork?
|
||||
--------------
|
||||
|
||||
mplayer2 is practically dead, and mpv started out as a branch containing
|
||||
new/experimental development. (Some of it was merged right *after* the fork
|
||||
was made public, seemingly as an acknowledgment that development, or at
|
||||
least merging, should have been more active.)
|
||||
|
||||
MPlayer is focused on not breaking anything, but is stuck with a horrible
|
||||
codebase resistant to cleanup. (Unless you do what mpv did - merciless and
|
||||
consequent pruning of bad, old code.) Cleanup and keeping broken things
|
||||
conflict, so the kind of development mpv strives for can't be done within
|
||||
MPlayer due to clashing development policies.
|
||||
|
||||
Additionally, mplayer2 already had lots of changes over MPlayer, which would
|
||||
have needed to be backported to the MPlayer codebase. This would not only
|
||||
have been hard (several years of diverging development), but also would have
|
||||
been impossible due to the aforementioned MPlayer development policy.
|
||||
+29
-75
@@ -1,110 +1,64 @@
|
||||
Release Policy
|
||||
==============
|
||||
|
||||
Once or twice a month, a new release is cut off of the master branch and is
|
||||
assigned a 0.X.Y version number, where X is incremented each time a release
|
||||
contains breaking changes, such as changed options or added/removed features,
|
||||
and Y is incremented if a release contains only bugfixes and other minor
|
||||
changes.
|
||||
Every few months, a new release is cut off of the master branch and is assigned
|
||||
a 0.X.0 version number.
|
||||
|
||||
Releases are tagged on the master branch and will not be maintained separately.
|
||||
As part of the maintenance process, minor releases are made, which are assigned
|
||||
0.X.Y version numbers. Minor releases contain bug fixes only. They never merge
|
||||
the master branch, and no features are added to it. Only the latest release is
|
||||
maintained.
|
||||
|
||||
The goal of releases is to provide Linux distributions with something to
|
||||
package. If you want the newest features, just use the master branch.
|
||||
We try our best to keep it deployable at all times.
|
||||
The goal of releases is to provide stability and an unchanged base for the sake
|
||||
of Linux distributions. If you want the newest features, just use the master
|
||||
branch, which is stable most of the time, except sometimes, when it's not.
|
||||
|
||||
Releases other than the latest release are unsupported and unmaintained.
|
||||
|
||||
Release procedure
|
||||
-----------------
|
||||
|
||||
While on master:
|
||||
- Create branch release/0.X or cherry-pick commits to the relevant branch.
|
||||
|
||||
- Update the `RELEASE_NOTES` file.
|
||||
- Create and/or update the ``RELEASE_NOTES`` file.
|
||||
|
||||
- Update the `VERSION` file.
|
||||
- Create and/or update the ``VERSION`` file.
|
||||
|
||||
- Update `DOCS/client-api-changes.rst` and `DOCS/interface-changes.rst`
|
||||
(in particular, update the last version numbers if necessary)
|
||||
- Update ``DOCS/client-api-changes.rst`` (on major releases).
|
||||
|
||||
- Commit changes.
|
||||
- Create tag v0.X.Y.
|
||||
|
||||
- Create signed tag v0.X.Y.
|
||||
- Push branch and tag to GitHub.
|
||||
|
||||
- Add -UNKNOWN suffix to version in `VERSION` file.
|
||||
|
||||
- Commit changes, push branch and tag to GitHub.
|
||||
|
||||
- Create a new GitHub release using the content of `RELEASE_NOTES` related to
|
||||
- Create a new GitHub release using the content of ``RELEASE_NOTES`` related to
|
||||
the new version.
|
||||
|
||||
Release notes template
|
||||
----------------------
|
||||
|
||||
Here is a template that can be used for writing the `RELEASE_NOTES` file.
|
||||
Here is a template that can be used for writing the ``RELEASE_NOTES`` file.
|
||||
|
||||
```markdown
|
||||
Release 0.X.Y
|
||||
=============
|
||||
|
||||
Features
|
||||
--------
|
||||
Changes
|
||||
-------
|
||||
|
||||
New
|
||||
~~~
|
||||
- List of changes.
|
||||
|
||||
- List of new features
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
Removed
|
||||
~~~~~~~
|
||||
- List of bug fixes.
|
||||
|
||||
- List of removed features
|
||||
New features
|
||||
------------
|
||||
|
||||
Deprecated
|
||||
~~~~~~~~~~
|
||||
|
||||
- List of deprecated features
|
||||
|
||||
Behavior
|
||||
--------
|
||||
|
||||
- List of user-visible changes in behavior
|
||||
|
||||
Options and Commands
|
||||
--------------------
|
||||
|
||||
Added
|
||||
~~~~~
|
||||
|
||||
- List of added options and commands
|
||||
|
||||
Changed
|
||||
~~~~~~~
|
||||
|
||||
- List of changed options and commands
|
||||
|
||||
Renamed
|
||||
~~~~~~~
|
||||
|
||||
- List of renamed options and commands
|
||||
|
||||
Deprecated
|
||||
~~~~~~~~~~
|
||||
|
||||
- List of deprecated options and commands
|
||||
|
||||
Removed
|
||||
~~~~~~~
|
||||
|
||||
- List of removed options and commands
|
||||
|
||||
Fixes and Minor Enhancements
|
||||
----------------------------
|
||||
|
||||
- List of fixes and minor enhancements
|
||||
- List of new features.
|
||||
|
||||
This listing is not complete. There are many more bug fixes and changes. The
|
||||
complete change log can be viewed by running `git log <start>..<end>` in
|
||||
complete change log can be viewed by running ``git log <start>..<end>`` in
|
||||
the git repository.
|
||||
```
|
||||
|
||||
@@ -112,6 +66,6 @@ Note that the "Release 0.X.Y" title should be removed when creating a new GitHub
|
||||
release.
|
||||
|
||||
When creating a new point release its changes should be added on top of the
|
||||
`RELEASE_NOTES` file (with the appropriate title) so that all the changes in
|
||||
the current 0.X branch will be included. This way the `RELEASE_NOTES` file
|
||||
``RELEASE_NOTES`` file (with the appropriate title) so that all the changes in
|
||||
the current 0.X branch will be included. This way the ``RELEASE_NOTES`` file
|
||||
can be used by distributors as changelog for point releases too.
|
||||
+66
-59
@@ -1,4 +1,4 @@
|
||||
This file intends to give a big picture overview of how mpv is structured.
|
||||
This file intends to give a big picture of how mpv is structured.
|
||||
|
||||
player/*.c:
|
||||
Essentially makes up the player applications, including the main() function
|
||||
@@ -31,41 +31,39 @@ player/*.c:
|
||||
* loop, or exit if no next file or quit is requested
|
||||
(see enum stop_play_reason)
|
||||
* call exit_player_with_rc()
|
||||
* run_playloop():
|
||||
* calls fill_audio_out_buffers()
|
||||
This checks whether new audio needs to be decoded, and pushes it
|
||||
to the AO.
|
||||
* calls write_video()
|
||||
Decode new video, and push it to the VO.
|
||||
* determines whether playback of the current file has ended
|
||||
* determines when to start playback after seeks
|
||||
* and calls a whole lot of other stuff
|
||||
(Really, this function does everything.)
|
||||
|
||||
Things worth saying about the playback core:
|
||||
- most state is in MPContext (core.h), which is not available to the
|
||||
- the currently played tracks are in sh_video and sh_audio
|
||||
- the timeline stuff is used only with MKV ordered chapters (and some other
|
||||
minor features: cue, edl)
|
||||
- most state is in MPContext (mp_core.h), which is not available to the
|
||||
subsystems
|
||||
- the currently played tracks are in mpctx->current_tracks, and decoder
|
||||
state in track.d_video/d_audio/d_sub
|
||||
- the other subsystems rarely call back into the frontend, and the frontend
|
||||
polls them instead (probably a good thing)
|
||||
- one exceptions are wakeup callbacks, which notify a "higher" component
|
||||
of a changed situation in a subsystem
|
||||
|
||||
I like to call the player/*.c files the "frontend".
|
||||
|
||||
ta.h & ta.c:
|
||||
Hierarchical memory manager inspired by talloc from Samba. It's like a
|
||||
malloc() with more features. Most importantly, each talloc allocation can
|
||||
have a parent, and if the parent is free'd, all children will be free'd as
|
||||
well. The parent is an arbitrary talloc allocation. It's either set by the
|
||||
allocation call by passing a talloc parent, usually as first argument to the
|
||||
allocation function. It can also be set or reset later by other calls (at
|
||||
least talloc_steal()). A talloc allocation that is used as parent is often
|
||||
called a talloc context.
|
||||
talloc.h & talloc.c:
|
||||
Hierarchical memory manager copied from Samba. It's like a malloc() with
|
||||
more features. Most importantly, each talloc allocation can have a parent,
|
||||
and if the parent is free'd, all children will be free'd as well. The
|
||||
parent is an arbitrary talloc allocation. It's either set by the allocation
|
||||
call by passing a talloc parent, usually as first argument to the allocation
|
||||
function. It can also be set or reset later by other calls (at least
|
||||
talloc_steal()). A talloc allocation that is used as parent is often called
|
||||
a talloc context.
|
||||
|
||||
Lots of code still uses malloc() proper, and you should be careful what
|
||||
type of allocation you're dealing with when returning or free'ing an
|
||||
allocation. (Needless to say, talloc_free() and free() are completely
|
||||
different things.)
|
||||
|
||||
The copy in mpv has been modified to abort on OOM conditions. An
|
||||
allocation call will never return NULL.
|
||||
|
||||
One very useful feature of talloc is fast tracking of memory leaks. ("Fast"
|
||||
as in it doesn't require valgrind.) You can enable it by setting the
|
||||
as in it doesn't require valgrind.) You can enable it by passing the option
|
||||
--leak-report as first parameter, or better, setting the
|
||||
MPV_LEAK_REPORT environment variable to "1":
|
||||
export MPV_LEAK_REPORT=1
|
||||
This will list all unfree'd allocations on exit.
|
||||
@@ -73,14 +71,16 @@ ta.h & ta.c:
|
||||
Documentation can be found here:
|
||||
http://git.samba.org/?p=samba.git;a=blob;f=lib/talloc/talloc.h;hb=HEAD
|
||||
|
||||
For some reason, we're still using API-compatible wrappers instead of TA
|
||||
directly. The talloc wrapper has only a subset of the functionality, and
|
||||
in particular the wrappers abort() on memory allocation failure.
|
||||
|
||||
Note: unlike tcmalloc, jemalloc, etc., talloc() is not actually a malloc
|
||||
replacement. It works on top of system malloc and provides additional
|
||||
features that are supposed to make memory management easier.
|
||||
|
||||
Warning: actually, we're not using talloc anymore. talloc in mpv has been
|
||||
replaced by a custom re-implementation (TA in ta/). It provides
|
||||
some talloc emulation (just the parts needed by mpv). We will get
|
||||
rid of the talloc emulation later and use TA natively.
|
||||
(See ta/README for details.)
|
||||
|
||||
player/command.c:
|
||||
This contains the implementation for client API commands and properties.
|
||||
Properties are essentially dynamic variables changed by certain commands.
|
||||
@@ -103,15 +103,15 @@ options/options.h, options/options.c
|
||||
options.c. Most default values for options and MPOpts are in
|
||||
mp_default_opts at the end of options.c.
|
||||
|
||||
MPOpts is unfortunately quite monolithic, and virtually accessed by
|
||||
MPOpts is unfortunarely quite monolithic, and virtually accessed by
|
||||
everything.But some components (like video outputs and video filters) have
|
||||
their own sub-option tables separate from MPOpts.
|
||||
|
||||
The actual option parser is spread over m_option.c, m_config.c, and
|
||||
parse_commandline.c, and uses the option table in options.c.
|
||||
parser-mpcmd.c, and uses the option table in options.c.
|
||||
|
||||
input/input.c:
|
||||
This translates keyboard input coming from VOs and other sources (such
|
||||
This translates keyboard input comming from libvo and other sources (such
|
||||
as remote control devices like Apple IR or client API commands) to the
|
||||
key bindings listed in the user's (or the builtin) input.conf and turns
|
||||
them into items of type struct mp_cmd. These commands are queued, and read
|
||||
@@ -122,7 +122,7 @@ input/input.c:
|
||||
of input commands somewhere else.
|
||||
|
||||
common/msg.h:
|
||||
All terminal output must go through mp_msg().
|
||||
All terminal output should go through mp_msg().
|
||||
|
||||
stream/*:
|
||||
File input is implemented here. stream.h/.c provides a simple stream based
|
||||
@@ -149,7 +149,8 @@ demux/:
|
||||
|
||||
Most demuxers have been removed from this fork, and the only important and
|
||||
"actual" demuxers left are demux_mkv.c and demux_lavf.c (uses libavformat).
|
||||
There are some pseudo demuxers like demux_cue.c.
|
||||
There are some pseudo demuxers like demux_cue.c, which exist only to invoke
|
||||
other frontend code (tl_cue.c in this case).
|
||||
|
||||
The main interface is in demux.h. The stream headers are in stheader.h.
|
||||
There is a stream header for each audio/video/sub stream, and each of them
|
||||
@@ -163,8 +164,8 @@ video/:
|
||||
internally.
|
||||
|
||||
video/decode/:
|
||||
vd_*.c are video decoders. (There's only vd_lavc.c left.) dec_video.c
|
||||
handles most of connecting the frontend with the actual decoder.
|
||||
vd_*.c are video decoders. (There's only vd_lavc.c left.) dec_video.c/vd.c
|
||||
handle most of connecting the frontend with the actual decoder.
|
||||
|
||||
video/filter/:
|
||||
vf_*.c and vf.c form the video filter chain. They are fed by the video
|
||||
@@ -180,33 +181,31 @@ video/out/:
|
||||
vo_opengl can pick a windowing system at runtime, e.g. the same binary can
|
||||
provide both X11 and Cocoa support on OSX.
|
||||
|
||||
VOs can be reconfigured at runtime. A vo_reconfig() call can change the video
|
||||
VOs can be reconfigured at runtime. A config() call can change the video
|
||||
resolution and format, without destroying the window.
|
||||
|
||||
vo_opengl should be taken as reference.
|
||||
vo_vdpau and vo_opengl should be taken as reference.
|
||||
|
||||
audio/:
|
||||
format.h/format.c define the uncompressed audio formats. (As well as some
|
||||
compressed formats used for spdif.)
|
||||
|
||||
audio/decode/:
|
||||
ad_*.c and dec_audio.c handle audio decoding. ad_lavc.c is the
|
||||
ad_*.c and dec_audio.c/ad.c handle audio decoding. ad_lavc.c is the
|
||||
decoder using ffmpeg. ad_spdif.c is not really a decoder, but is used for
|
||||
compressed audio passthrough.
|
||||
|
||||
audio/filter/:
|
||||
Audio filter chain. af_lavrresample is inserted if any form of conversion
|
||||
between audio formats is needed.
|
||||
between audio formats is needed. (af_convert24.c and af_convertsignendian.c
|
||||
are also used for some formats not directly supported by FFmpeg.)
|
||||
|
||||
audio/out/:
|
||||
Audio outputs.
|
||||
|
||||
Unlike VOs, AOs can't be reconfigured on a format change. On audio format
|
||||
changes, the AO will simply be closed and re-opened.
|
||||
|
||||
There are wrappers to support for two types of audio APIs: push.c and
|
||||
pull.c. ao.c calls into one of these. They contain generic code to deal
|
||||
with the data flow these APIs impose.
|
||||
Unlike VOs, AOs can't be reconfigured on a format change. Without
|
||||
--gapless-audio, even playing a new file will close and re-open the audio
|
||||
device.
|
||||
|
||||
Note that mpv synchronizes the video to the audio. That's the reason
|
||||
why buggy audio drivers can have a bad influence on playback quality.
|
||||
@@ -219,23 +218,31 @@ sub/:
|
||||
the OSD text renderer (which uses libass, and takes care of all the tricky
|
||||
fontconfig/freetype API usage and text layouting).
|
||||
|
||||
The VOs call osd.c to render OSD and subtitle (via e.g. osd_draw()). osd.c
|
||||
in turn asks dec_sub.c for subtitle overlay bitmaps, which relays the
|
||||
request to one of the sd_*.c subtitle decoders/renderers.
|
||||
|
||||
Subtitle loading is in demux/. The MPlayer subreader.c is mostly gone - parts
|
||||
of it survive in demux_subreader.c. It's used as last fallback, or to handle
|
||||
some text subtitle types on Libav. It should go away eventually. Normally,
|
||||
subtitles are loaded via demux_lavf.c.
|
||||
Subtitle loading is now in demux/ instead. demux_libass.c wraps loading
|
||||
.ass subtitles via libass. demux_lavf.c loads most subtitle types via
|
||||
FFmpeg. demux_subreader.c is the old MPlayer code. It's used as last
|
||||
fallback, or to handle some text subtitle types on Libav. (It also can
|
||||
load UTF-16 encoded subtitles without requiring the use of -sub-codepage.)
|
||||
demux_subreader.c should eventually go away (maybe).
|
||||
|
||||
The subtitles are passed to dec_sub.c and the subtitle decoders in sd_*.c
|
||||
as they are demuxed. All text subtitles are rendered by sd_ass.c. If text
|
||||
subtitles are not in the ASS format, the libavcodec subtitle converters are
|
||||
used (lavc_conv.c).
|
||||
subtitles are not in the ASS format, subtitle converters are inserted, for
|
||||
example sd_srt.c, which is used to convert SRT->ASS. sd_srt.c is also used
|
||||
as general converter for text->ASS (to prevent interpretation of text as
|
||||
ASS tags).
|
||||
|
||||
Text subtitles can be preloaded, in which case they are read fully as soon
|
||||
as the subtitle is selected. In this case, they are effectively stored in
|
||||
sd_ass.c's internal state.
|
||||
as the subtitle is selected, and then effectively stored in an ASS_Track.
|
||||
It's used for external text subtitles, and required to make codepage
|
||||
detection as well as timing postprocessing work. (Timing postprocessing
|
||||
removes tiny gaps or overlaps between subtitle events.)
|
||||
|
||||
player/timeline/:
|
||||
A timeline is the abstraction used by loadfile.c to combine several files
|
||||
into one seemingly linear video. It's mainly used for ordered chapters
|
||||
playback. The high level code to find and load other files containing the
|
||||
segments for playing an ordered chapters file is in tl_matroska.c.
|
||||
|
||||
etc/:
|
||||
The file input.conf is actually integrated into the mpv binary by the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
waf build system overview
|
||||
=========================
|
||||
|
||||
mpv's new build system is based on waf and it should completely replace the
|
||||
mpv's new build system is based on waf and it should completly replace the
|
||||
custom ./configure + Makefile based system inherited from MPlayer.
|
||||
|
||||
Goals and the choice of waf
|
||||
@@ -20,9 +20,8 @@ shortcomings:
|
||||
part is this pieces are spread apart in the configure and copy pasted for
|
||||
any single case. That brings us to..
|
||||
|
||||
2) --enable-feature has to be overridden by the user and helps them understand that
|
||||
they have libraries missing and should install them for the feature to be
|
||||
enabled.
|
||||
2) --enable-feature has to override the user and help him understand that he
|
||||
has libraries missing and should install them for the feature to be enabled.
|
||||
|
||||
3) Must be customizable, hackable, pleasant to the developer eyes and to work
|
||||
with in general.
|
||||
@@ -65,7 +64,7 @@ This defines a feature called ``vdpau`` which can be enabled or disabled by
|
||||
the users with configure flags (that's the meaning of ``--``). This feature
|
||||
depends on another feature whose name is ``x11``, and the autodetection check
|
||||
consists of running ``pkg-config`` and looking for ``vdpau`` with version
|
||||
``>= 0.2``. If the check succeeds a ``#define HAVE_VDPAU 1`` will be added to
|
||||
``>= 0.2``. If the check succeds a ``#define HAVE_VDPAU 1`` will be added to
|
||||
``config.h``, if not ``#define HAVE_VDPAU 0`` will be added.
|
||||
|
||||
The defines names are automatically prepended with ``HAVE_``, capitalized and
|
||||
@@ -146,7 +145,7 @@ mpv's custom build step on top of waf
|
||||
|
||||
Build step is pretty much vanilla waf. The only difference being that the list
|
||||
of source files can contain both strings or tuples. If a tuple is found,
|
||||
the second element in the tuple will be used to match the features detected
|
||||
the second element in the tuple will the used to match the features detected
|
||||
in the configure step (the ``name`` field described above). If this feature
|
||||
was not enabled during configure, the source file will not be compiled in.
|
||||
|
||||
|
||||
@@ -1,73 +1,24 @@
|
||||

|
||||
mpv
|
||||
===
|
||||
|
||||
## mpv
|
||||
[](https://travis-ci.org/mpv-player/mpv)
|
||||
|
||||
--------------
|
||||
Overview
|
||||
--------
|
||||
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Downloads](#downloads)
|
||||
* [Changelog](#changelog)
|
||||
* [Compilation](#compilation)
|
||||
* [FFmpeg vs. Libav](#ffmpeg-vs-libav)
|
||||
* [Release cycle](#release-cycle)
|
||||
* [Bug reports](#bug-reports)
|
||||
* [Contributing](#contributing)
|
||||
* [Relation to MPlayer and mplayer2](#relation-to-mplayer-and-mplayer2)
|
||||
* [Wiki](https://github.com/mpv-player/mpv/wiki)
|
||||
* [FAQ](https://github.com/mpv-player/mpv/wiki/FAQ)
|
||||
* [Man pages](http://mpv.io/manual/master/)
|
||||
* [Contact](#contact)
|
||||
* [License](#license)
|
||||
|
||||
## Overview
|
||||
|
||||
|
||||
**mpv** is a media player based on MPlayer and mplayer2. It supports a wide
|
||||
**mpv** is a movie player based on MPlayer and mplayer2. It supports a wide
|
||||
variety of video file formats, audio and video codecs, and subtitle types.
|
||||
|
||||
Releases can be found on the [release list][releases].
|
||||
|
||||
## System requirements
|
||||
|
||||
- A not too ancient Linux, or Windows Vista or later, or OSX 10.8 or later.
|
||||
- A somewhat capable CPU. Hardware decoding might sometimes help if the CPU
|
||||
is too slow to decode video realtime, but must be explicitly enabled with
|
||||
the `--hwdec` option.
|
||||
- A not too crappy GPU. mpv is not intended to be used with bad GPUs. There are
|
||||
many caveats with drivers or system compositors causing tearing, stutter,
|
||||
etc. On Windows, you might want to make sure the graphics drivers are
|
||||
current. In some cases, ancient fallback video output methods can help
|
||||
(such as `--vo=xv` on Linux), but this use is not recommended or supported.
|
||||
|
||||
|
||||
## Downloads
|
||||
|
||||
|
||||
For semi-official builds and third-party packages please see
|
||||
[mpv.io](http://mpv.io/installation/).
|
||||
|
||||
## Changelog
|
||||
|
||||
|
||||
There is no complete changelog; however, changes to the player core interface
|
||||
are listed in the [interface changelog][interface-changes].
|
||||
|
||||
Changes to the C API are documented in the [client API changelog][api-changes].
|
||||
|
||||
The [release list][releases] has a summary of most of the important changes
|
||||
on every release.
|
||||
|
||||
Changes to the default key bindings are indicated in
|
||||
[restore-old-bindings.conf][restore-old-bindings].
|
||||
|
||||
## Compilation
|
||||
If you are wondering what's different from mplayer2 and MPlayer you can read
|
||||
more about the [changes][changes].
|
||||
|
||||
Compilation
|
||||
-----------
|
||||
|
||||
Compiling with full features requires development files for several
|
||||
external libraries. Below is a list of some important requirements.
|
||||
|
||||
The mpv build system uses *waf*, but we don't store it in your source tree. The
|
||||
The mpv build system uses *waf* but we don't store it in your source tree. The
|
||||
script './bootstrap.py' will download the latest version of waf that was tested
|
||||
with the build system.
|
||||
|
||||
@@ -86,166 +37,103 @@ To build the software you can use `./waf build`: the result of the compilation
|
||||
will be located in `build/mpv`. You can use `./waf install` to install mpv
|
||||
to the *prefix* after it is compiled.
|
||||
|
||||
Example:
|
||||
|
||||
./bootstrap.py
|
||||
./waf configure
|
||||
./waf
|
||||
./waf install
|
||||
NOTE: Using the old build system (with `./old-configure`) should still work,
|
||||
but will be removed in a future version of mpv.
|
||||
|
||||
Essential dependencies (incomplete list):
|
||||
|
||||
- gcc or clang
|
||||
- X development headers (xlib, xrandr, xext, xscrnsaver, xinerama, libvdpau,
|
||||
libGL, GLX, EGL, xv, ...)
|
||||
- Audio output development headers (libasound/ALSA, pulseaudio)
|
||||
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavfilter
|
||||
and either libswresample or libavresample)
|
||||
At least FFmpeg 3.2.2 or Libav 12 is required.
|
||||
For hardware decoding with vaapi and vdpau, FFmpeg 3.3 or Libav git is
|
||||
required.
|
||||
- zlib
|
||||
- iconv (normally provided by the system libc)
|
||||
- libass (OSD, OSC, text subtitles)
|
||||
- Lua (optional, required for the OSC pseudo-GUI and youtube-dl integration)
|
||||
- libjpeg (optional, used for screenshots only)
|
||||
- uchardet (optional, for subtitle charset detection)
|
||||
- vdpau and vaapi libraries for hardware decoding on Linux (optional)
|
||||
(FFmpeg 3.3 or Libav git is also required.)
|
||||
- X development headers (xlib, X extensions, libvdpau, libGL, libXv, ...)
|
||||
- Audio output development headers (libasound, pulseaudio)
|
||||
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavresample)
|
||||
At least FFmpeg 2.1.4 or Libav 10 is required.
|
||||
- libjpeg (for screenshots)
|
||||
- libquvi if you want to play Youtube videos directly
|
||||
|
||||
Libass dependencies:
|
||||
|
||||
- gcc or clang, yasm on x86 and x86_64
|
||||
- fribidi, freetype, fontconfig development headers (for libass)
|
||||
- harfbuzz (optional, required for correct rendering of combining characters,
|
||||
particularly for correct rendering of non-English text on OSX, and
|
||||
Arabic/Indic scripts on any platform)
|
||||
|
||||
FFmpeg dependencies:
|
||||
|
||||
- gcc or clang, yasm on x86 and x86_64
|
||||
- OpenSSL or GnuTLS (have to be explicitly enabled when compiling FFmpeg)
|
||||
- libx264/libmp3lame/libfdk-aac if you want to use encoding (have to be
|
||||
explicitly enabled when compiling FFmpeg)
|
||||
- OpenSSL (has to be explicitly enabled when compiling ffmpeg)
|
||||
- libx264/libmp3lame/libfdk-aac if you want to use encoding (has to be
|
||||
explicitly enabled when compiling ffmpeg)
|
||||
- Libav also works, but some features will not work. (See section below.)
|
||||
|
||||
Most of the above libraries are available in suitable versions on normal
|
||||
Linux distributions. However, FFmpeg is an exception (distro versions may be
|
||||
too old to work well or at all). For that reason you may want to use
|
||||
the separately available build wrapper ([mpv-build][mpv-build]) that first
|
||||
compiles FFmpeg libraries and libass, and then compiles the player statically
|
||||
linked against those.
|
||||
Linux distributions. However FFmpeg is an exception (distro versions may be
|
||||
too old to work at all or work well). For that reason you may want to use
|
||||
the separately available build wrapper ([mpv-build][mpv-build]) that first compiles FFmpeg
|
||||
libraries and libass, and then compiles the player statically linked against
|
||||
those.
|
||||
|
||||
If you want to build a Windows binary, you either have to use MSYS2 and MinGW,
|
||||
or cross-compile from Linux with MinGW. See
|
||||
[Windows compilation][windows_compilation].
|
||||
|
||||
|
||||
## FFmpeg vs. Libav
|
||||
If you are running Mac OSX and using homebrew we provide [homebrew-mpv][homebrew-mpv], an up
|
||||
to date formula that compiles mpv with sensible dependencies and defaults for
|
||||
OSX.
|
||||
|
||||
FFmpeg vs. Libav
|
||||
----------------
|
||||
|
||||
Generally, mpv should work with the latest release as well as the git version
|
||||
of both FFmpeg and Libav. But FFmpeg is preferred, and some mpv features work
|
||||
with FFmpeg only (subtitle formats in particular).
|
||||
with FFmpeg only. See the [wiki article][ffmpeg_vs_libav] about the issue.
|
||||
|
||||
|
||||
## Preferred FFmpeg version
|
||||
Release cycle
|
||||
-------------
|
||||
|
||||
Every few months, a new release is cut off of the master branch and is assigned
|
||||
a 0.X.0 version number.
|
||||
|
||||
Using the latest FFmpeg release (or FFmpeg git master) is strongly recommended.
|
||||
Older versions are unsupported, even if the build system still happens to
|
||||
accept them. The main reason mpv still builds with older FFmpeg versions is to
|
||||
evade arguing with people (users, distros) who insist on using older FFmpeg
|
||||
versions for no rational reason.
|
||||
As part of the maintenance process, minor releases are made, which are assigned
|
||||
0.X.Y version numbers. Minor releases contain bug fixes only. They never merge
|
||||
the master branch, and no features are added to it. Only the latest release is
|
||||
maintained.
|
||||
|
||||
If you want to use a stable FFmpeg release, use the latest release, which has
|
||||
most likely the best maintenance out of all stable releases. Older releases
|
||||
are for distros, and at best receive basic changes, like fixing critical security
|
||||
issues or build fixes, and at worst are completely abandoned.
|
||||
|
||||
## FFmpeg ABI compatibility
|
||||
|
||||
mpv does not support linking against FFmpeg versions it was not built with, even
|
||||
if the linked version is supposedly ABI-compatible with the version it was
|
||||
compiled against. Expect malfunctions, crashes, and security issues if you
|
||||
do it anyway.
|
||||
|
||||
The reason for not supporting this is because it creates far too much complexity
|
||||
with little to no benefit, coupled with absurd and unusable FFmpeg API
|
||||
artifacts.
|
||||
|
||||
Newer mpv versions will refuse to start if runtime and compile time FFmpeg
|
||||
library versions mismatch.
|
||||
|
||||
## Release cycle
|
||||
|
||||
Every other month, an arbitrary git snapshot is made, and is assigned
|
||||
a 0.X.0 version number. No further maintenance is done.
|
||||
|
||||
The goal of releases is to make Linux distributions happy. Linux distributions
|
||||
are also expected to apply their own patches in case of bugs and security
|
||||
issues.
|
||||
The goal of releases is to provide stability and an unchanged base for the sake
|
||||
of Linux distributions. If you want the newest features, just use the master
|
||||
branch, which is stable most of the time, except sometimes, when it's not.
|
||||
|
||||
Releases other than the latest release are unsupported and unmaintained.
|
||||
|
||||
See the [release policy document][release-policy] for more information.
|
||||
|
||||
## Bug reports
|
||||
|
||||
Bug reports
|
||||
-----------
|
||||
|
||||
Please use the [issue tracker][issue-tracker] provided by GitHub to send us bug
|
||||
reports or feature requests. Follow the template's instructions or the issue
|
||||
will likely be ignored or closed as invalid.
|
||||
|
||||
Using the bug tracker as place for simple questions is fine but IRC is
|
||||
recommended (see [Contact](#Contact) below).
|
||||
|
||||
## Contributing
|
||||
reports or feature requests.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
For small changes you can just send us pull requests through GitHub. For bigger
|
||||
changes come and talk to us on IRC before you start working on them. It will
|
||||
make code review easier for both parties later on.
|
||||
|
||||
You can check [the wiki](https://github.com/mpv-player/mpv/wiki/Stuff-to-do)
|
||||
or the [issue tracker](https://github.com/mpv-player/mpv/issues?q=is%3Aopen+is%3Aissue+label%3A%22feature+request%22)
|
||||
for ideas on what you could contribute with.
|
||||
Contact
|
||||
-------
|
||||
|
||||
## Relation to MPlayer and mplayer2
|
||||
These forms of contact are meant to ask questions about mpv usage, give
|
||||
feedback on mpv and discuss it's development.
|
||||
|
||||
mpv is a fork of MPlayer. Much has changed, and in general, mpv should be
|
||||
considered a completely new program, rather than a MPlayer drop-in replacement.
|
||||
If possible, please avoid posting bugs here and use the [issue tracker][issue-tracker]
|
||||
instead.
|
||||
|
||||
For details see [FAQ entry](https://github.com/mpv-player/mpv/wiki/FAQ#How_is_mpv_related_to_MPlayer).
|
||||
- **Users IRC Channel**: `#mpv-player` on `irc.freenode.net`
|
||||
- **Users Mailing List**: `mpv-users@googlegroups.com` ([Archive / Subscribe][mpv-users]).
|
||||
- **Devel Mailing List**: `mpv-devel@googlegroups.com` ([Archive / Subscribe][mpv-devel])
|
||||
|
||||
If you are wondering what's different from mplayer2 and MPlayer, an incomplete
|
||||
and largely unmaintained list of changes is located [here][mplayer-changes].
|
||||
To contact the `mpv` team in private write to `mpv-team@googlegroups.com`.
|
||||
|
||||
## Contact
|
||||
|
||||
|
||||
Most activity happens on the IRC channel and the github issue tracker.
|
||||
|
||||
- **GitHub issue tracker**: [issue tracker][issue-tracker] (report bugs here)
|
||||
- **User IRC Channel**: `#mpv` on `irc.freenode.net`
|
||||
- **Developer IRC Channel**: `#mpv-devel` on `irc.freenode.net`
|
||||
|
||||
To contact the `mpv` team in private write to `mpv-team@googlegroups.com`. Use
|
||||
only if discretion is required.
|
||||
|
||||
[releases]: https://github.com/mpv-player/mpv/releases
|
||||
[changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/man/changes.rst
|
||||
[mpv-build]: https://github.com/mpv-player/mpv-build
|
||||
[homebrew-mpv]: https://github.com/mpv-player/homebrew-mpv
|
||||
[issue-tracker]: https://github.com/mpv-player/mpv/issues
|
||||
[mpv-users]: https://groups.google.com/forum/?hl=en#!forum/mpv-users
|
||||
[mpv-devel]: https://groups.google.com/forum/?hl=en#!forum/mpv-devel
|
||||
[ffmpeg_vs_libav]: https://github.com/mpv-player/mpv/wiki/FFmpeg-versus-Libav
|
||||
[release-policy]: https://github.com/mpv-player/mpv/blob/master/DOCS/release-policy.md
|
||||
[windows_compilation]: https://github.com/mpv-player/mpv/blob/master/DOCS/compile-windows.md
|
||||
[mplayer-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/mplayer-changes.rst
|
||||
[interface-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/interface-changes.rst
|
||||
[api-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/client-api-changes.rst
|
||||
[restore-old-bindings]: https://github.com/mpv-player/mpv/blob/master/etc/restore-old-bindings.conf
|
||||
|
||||
## License
|
||||
|
||||
|
||||
Mostly GPLv2 or later. See [details.](https://github.com/mpv-player/mpv/blob/master/Copyright)
|
||||
+111
-2709
File diff suppressed because it is too large.
Load diff
Whitespace-only changes.
@@ -1,22 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
set -e
|
||||
|
||||
export DEST_OS=win32
|
||||
export CC=gcc
|
||||
export PKG_CONFIG=/usr/bin/pkg-config
|
||||
export PERL=/usr/bin/perl
|
||||
export PYTHON=/usr/bin/python3
|
||||
|
||||
"$PYTHON" bootstrap.py
|
||||
"$PYTHON" waf configure \
|
||||
--check-c-compiler=gcc \
|
||||
--disable-cdda \
|
||||
--enable-egl-angle \
|
||||
--enable-jpeg \
|
||||
--enable-lcms2 \
|
||||
--enable-libarchive \
|
||||
--enable-libass \
|
||||
--enable-lua \
|
||||
--enable-rubberband \
|
||||
--enable-uchardet
|
||||
"$PYTHON" waf build
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
set -e
|
||||
|
||||
case $MSYSTEM in
|
||||
MINGW32)
|
||||
export MINGW_PACKAGE_PREFIX=mingw-w64-i686
|
||||
;;
|
||||
MINGW64)
|
||||
export MINGW_PACKAGE_PREFIX=mingw-w64-x86_64
|
||||
;;
|
||||
esac
|
||||
|
||||
# Write an empty fonts.conf to speed up fc-cache
|
||||
export FONTCONFIG_FILE=/dummy-fonts.conf
|
||||
cat >"$FONTCONFIG_FILE" <<EOF
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig></fontconfig>
|
||||
EOF
|
||||
|
||||
# Install build dependencies for mpv
|
||||
pacman -S --noconfirm --needed \
|
||||
$MINGW_PACKAGE_PREFIX-gcc \
|
||||
$MINGW_PACKAGE_PREFIX-angleproject-git \
|
||||
$MINGW_PACKAGE_PREFIX-ffmpeg \
|
||||
$MINGW_PACKAGE_PREFIX-lcms2 \
|
||||
$MINGW_PACKAGE_PREFIX-libarchive \
|
||||
$MINGW_PACKAGE_PREFIX-libass \
|
||||
$MINGW_PACKAGE_PREFIX-libjpeg-turbo \
|
||||
$MINGW_PACKAGE_PREFIX-lua51 \
|
||||
$MINGW_PACKAGE_PREFIX-rubberband \
|
||||
$MINGW_PACKAGE_PREFIX-uchardet
|
||||
|
||||
# Delete unused packages to reduce space used in the Appveyor cache
|
||||
pacman -Sc --noconfirm
|
||||
@@ -19,7 +19,6 @@ def is_user_lib(objfile, libname):
|
||||
not "libSystem." in libname and \
|
||||
not "libc." in libname and \
|
||||
not "libgcc." in libname and \
|
||||
not os.path.basename(libname) == 'Python' and \
|
||||
not os.path.basename(objfile) in libname
|
||||
|
||||
def otool(objfile):
|
||||
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#! /usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# Convert the contents of a file into a C string constant.
|
||||
# Note that the compiler will implicitly add an extra 0 byte at the end
|
||||
# of every string, so code using the string may need to remove that to get
|
||||
# the exact contents of the original file.
|
||||
# FIXME: why not a char array?
|
||||
|
||||
# treat only alphanumeric and not-" punctuation as safe
|
||||
my $unsafe_chars = qr{[^][A-Za-z0-9!#%&'()*+,./:;<=>?^_{|}~ -]};
|
||||
|
||||
for my $file (@ARGV) {
|
||||
open my $fh, '<:raw', $file or next;
|
||||
print "/* Generated from $file */\n";
|
||||
while (<$fh>) {
|
||||
# replace unsafe chars with their equivalent octal escapes
|
||||
s/($unsafe_chars)/\\@{[sprintf '%03o', ord($1)]}/gos;
|
||||
print "\"$_\"\n"
|
||||
}
|
||||
close $fh;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Convert the contents of a file into a C string constant.
|
||||
# Note that the compiler will implicitly add an extra 0 byte at the end
|
||||
# of every string, so code using the string may need to remove that to get
|
||||
# the exact contents of the original file.
|
||||
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import sys
|
||||
|
||||
# Indexing a byte string yields int on Python 3.x, and a str on Python 2.x
|
||||
def pord(c):
|
||||
return ord(c) if type(c) == str else c
|
||||
|
||||
def file2string(infilename, infile, outfile):
|
||||
outfile.write("// Generated from %s\n\n" % infilename)
|
||||
|
||||
conv = ['\\' + ("%03o" % c) for c in range(256)]
|
||||
safe_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" \
|
||||
"0123456789!#%&'()*+,-./:;<=>?[]^_{|}~ "
|
||||
|
||||
for c in safe_chars:
|
||||
conv[ord(c)] = c
|
||||
for c, esc in ("\nn", "\tt", r"\\", '""'):
|
||||
conv[ord(c)] = '\\' + esc
|
||||
for line in infile:
|
||||
outfile.write('"' + ''.join(conv[pord(c)] for c in line) + '"\n')
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open(sys.argv[1], 'rb') as infile:
|
||||
file2string(sys.argv[1], infile, sys.stdout)
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script is expected to be called as TOOLS/gen-osd-font.sh (it will access
|
||||
# TOOLS/mpv-osd-symbols.sfdir), and it will write sub/osd_font.otf.
|
||||
|
||||
# Needs fontforge with python scripting
|
||||
|
||||
fontforge -lang=py -c 'f=open(argv[1]); f.generate(argv[2])' \
|
||||
TOOLS/mpv-osd-symbols.sfdir sub/osd_font.otf
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script is expected to be called as TOOLS/gen-x11-icon.sh (it will access
|
||||
# etc/mpv-icon...), and it will write video/out/x11_icon.bin.
|
||||
|
||||
conv() {
|
||||
echo
|
||||
identify -format "icon: %w %h" $1
|
||||
convert $1 -depth 8 rgba:-
|
||||
}
|
||||
|
||||
(echo "# File generated by gen-x11-icon.sh" ;
|
||||
conv etc/mpv-icon-8bit-16x16.png ;
|
||||
conv etc/mpv-icon-8bit-32x32.png ;
|
||||
conv etc/mpv-icon-8bit-64x64.png) | gzip -c > video/out/x11_icon.bin
|
||||
+59
-56
@@ -1,15 +1,23 @@
|
||||
#!/bin/sh
|
||||
|
||||
: "${MPV:=mpv}"
|
||||
: "${ILDETECT_MPV:=$MPV}"
|
||||
: "${ILDETECT_MPVFLAGS:=--start=35% --length=35}"
|
||||
: "${ILDETECT_DRY_RUN:=}"
|
||||
: "${ILDETECT_QUIET:=}"
|
||||
: "${ILDETECT_RUN_INTERLACED_ONLY:=}"
|
||||
: "${ILDETECT_FORCE_RUN:=}"
|
||||
case "$0" in
|
||||
*/*)
|
||||
MYDIR=${0%/*}
|
||||
;;
|
||||
*)
|
||||
MYDIR=.
|
||||
;;
|
||||
esac
|
||||
|
||||
# This script uses ffmpeg's "idet" filter for interlace detection. In the
|
||||
# long run this should replace ildetect.sh+ildetect.so.
|
||||
: ${MPV:=mpv}
|
||||
: ${ILDETECT_MPV:=$MPV}
|
||||
: ${ILDETECT_MPV:=$MPV}
|
||||
: ${ILDETECT_MPVFLAGS:=--start=35% --length=35}
|
||||
: ${ILDETECT_DRY_RUN:=}
|
||||
: ${ILDETECT_QUIET:=}
|
||||
: ${ILDETECT_RUN_INTERLACED_ONLY:=}
|
||||
: ${ILDETECT_FORCE_RUN:=}
|
||||
: ${MAKE:=make}
|
||||
|
||||
# exit status:
|
||||
# 0 progressive
|
||||
@@ -26,62 +34,57 @@ testfun()
|
||||
--o= --vo=null --no-audio --untimed \
|
||||
$ILDETECT_MPVFLAGS \
|
||||
| { if [ -n "$ILDETECT_QUIET" ]; then cat; else tee /dev/stderr; fi } \
|
||||
| grep "Parsed_idet_0: Multi frame detection: "
|
||||
| grep "Parsed_idet_0: Multi frame detection: " | tail -n 1
|
||||
}
|
||||
|
||||
judge()
|
||||
{
|
||||
tff=0
|
||||
bff=0
|
||||
progressive=0
|
||||
undetermined=0
|
||||
while read -r _ _ _ _ _ _ tff1 _ bff1 _ progressive1 _ undetermined1 _; do
|
||||
case "$tff1$bff1$progressive1$undetermined1" in
|
||||
*[!0-9]*)
|
||||
printf >&2 'ERROR: Unrecognized idet output: %s\n' "$out"
|
||||
exit 16
|
||||
;;
|
||||
esac
|
||||
tff=$((tff + tff1))
|
||||
bff=$((bff + bff1))
|
||||
progressive=$((progressive + progressive1))
|
||||
undetermined=$((undetermined + undetermined1))
|
||||
done <<EOF
|
||||
$(testfun "$@" | sed 's/:/: /g')
|
||||
EOF
|
||||
out=`testfun "$@"`
|
||||
|
||||
tff=${out##* TFF:}; tff=${tff%% *}
|
||||
bff=${out##* BFF:}; bff=${bff%% *}
|
||||
progressive=${out##* Progressive:}; progressive=${progressive%% *}
|
||||
undetermined=${out##* Undetermined:}; undetermined=${undetermined%% *}
|
||||
|
||||
case "$tff$bff$progressive$undetermined" in
|
||||
*[!0-9]*)
|
||||
echo >&2 "ERROR: Unrecognized idet output: $out"
|
||||
exit 16
|
||||
;;
|
||||
esac
|
||||
|
||||
interlaced=$((bff + tff))
|
||||
determined=$((interlaced + progressive))
|
||||
|
||||
if [ "$undetermined" -gt "$determined" ] || [ "$determined" -lt 250 ]; then
|
||||
if [ $undetermined -gt $determined ] || [ $determined -lt 250 ]; then
|
||||
echo >&2 "ERROR: Less than 50% or 250 frames are determined."
|
||||
[ -n "$ILDETECT_FORCE_RUN" ] || exit 8
|
||||
echo >&2 "Assuming interlacing."
|
||||
if [ "$tff" -gt $((bff * 10)) ]; then
|
||||
verdict="interlaced-tff"
|
||||
elif [ "$bff" -gt $((tff * 10)) ]; then
|
||||
verdict="interlaced-bff"
|
||||
if [ $tff -gt $((bff * 10)) ]; then
|
||||
verdict=interlaced-tff
|
||||
elif [ $bff -gt $((tff * 10)) ]; then
|
||||
verdict=interlaced-bff
|
||||
else
|
||||
verdict="interlaced"
|
||||
verdict=interlaced
|
||||
fi
|
||||
elif [ $((interlaced * 20)) -gt "$progressive" ]; then
|
||||
elif [ $((interlaced * 20)) -gt $progressive ]; then
|
||||
# At least 5% of the frames are interlaced!
|
||||
if [ "$tff" -gt $((bff * 10)) ]; then
|
||||
verdict="interlaced-tff"
|
||||
elif [ "$bff" -gt $((tff * 10)) ]; then
|
||||
verdict="interlaced-bff"
|
||||
if [ $tff -gt $((bff * 10)) ]; then
|
||||
verdict=interlaced-tff
|
||||
elif [ $bff -gt $((tff * 10)) ]; then
|
||||
verdict=interlaced-bff
|
||||
else
|
||||
echo >&2 "ERROR: Content is interlaced, but can't determine field order."
|
||||
[ -n "$ILDETECT_FORCE_RUN" ] || exit 8
|
||||
echo >&2 "Assuming interlacing with default field order."
|
||||
verdict="interlaced"
|
||||
verdict=interlaced
|
||||
fi
|
||||
else
|
||||
# Likely progressive
|
||||
verdict="progressive"
|
||||
# Likely progrssive.
|
||||
verdict=progressive
|
||||
fi
|
||||
|
||||
printf '%s\n' "$verdict"
|
||||
echo "$verdict"
|
||||
}
|
||||
|
||||
judge "$@" --vf-clr
|
||||
@@ -91,43 +94,43 @@ case "$verdict" in
|
||||
[ -n "$ILDETECT_RUN_INTERLACED_ONLY" ] || \
|
||||
$ILDETECT_MPV "$@"
|
||||
r=$?
|
||||
[ $r -eq 0 ] || exit $((r | 16))
|
||||
[ $r -eq 0 ] || exit $(($r | 16))
|
||||
exit 0
|
||||
;;
|
||||
interlaced-tff)
|
||||
judge "$@" --vf-clr --vf-pre=lavfi=\[setfield=tff\],pullup
|
||||
judge "$@" --vf-clr --vf-pre=pullup --field-dominance=top
|
||||
case "$verdict" in
|
||||
progressive)
|
||||
[ -n "$ILDETECT_DRY_RUN" ] || \
|
||||
$ILDETECT_MPV "$@" --vf-pre=lavfi=\[setfield=tff\],pullup
|
||||
$ILDETECT_MPV "$@" --vf-pre=pullup --field-dominance=top
|
||||
r=$?
|
||||
[ $r -eq 0 ] || exit $((r | 16))
|
||||
[ $r -eq 0 ] || exit $(($r | 16))
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
[ -n "$ILDETECT_DRY_RUN" ] || \
|
||||
$ILDETECT_MPV "$@" --vf-pre=lavfi=\[setfield=tff\],yadif
|
||||
$ILDETECT_MPV "$@" --vf-pre=yadif --field-dominance=top
|
||||
r=$?
|
||||
[ $r -eq 0 ] || exit $((r | 16))
|
||||
[ $r -eq 0 ] || exit $(($r | 16))
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
interlaced-bff)
|
||||
judge "$@" --vf-clr --vf-pre=lavfi=\[setfield=bff\],pullup
|
||||
judge "$@" --vf-clr --vf-pre=pullup --field-dominance=bottom
|
||||
case "$verdict" in
|
||||
progressive)
|
||||
[ -n "$ILDETECT_DRY_RUN" ] || \
|
||||
$ILDETECT_MPV "$@" --vf-pre=lavfi=\[setfield=bff\],pullup
|
||||
$ILDETECT_MPV "$@" --vf-pre=pullup --field-dominance=bottom
|
||||
r=$?
|
||||
[ $r -eq 0 ] || exit $((r | 16))
|
||||
[ $r -eq 0 ] || exit $(($r | 16))
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
[ -n "$ILDETECT_DRY_RUN" ] || \
|
||||
$ILDETECT_MPV "$@" --vf-pre=lavfi=\[setfield=bff\],yadif
|
||||
$ILDETECT_MPV "$@" --vf-pre=yadif --field-dominance=bottom
|
||||
r=$?
|
||||
[ $r -eq 0 ] || exit $((r | 16))
|
||||
[ $r -eq 0 ] || exit $(($r | 16))
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
@@ -139,14 +142,14 @@ case "$verdict" in
|
||||
[ -n "$ILDETECT_DRY_RUN" ] || \
|
||||
$ILDETECT_MPV "$@" --vf-pre=pullup
|
||||
r=$?
|
||||
[ $r -eq 0 ] || exit $((r | 16))
|
||||
[ $r -eq 0 ] || exit $(($r | 16))
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
[ -n "$ILDETECT_DRY_RUN" ] || \
|
||||
$ILDETECT_MPV "$@" --vf-pre=yadif
|
||||
r=$?
|
||||
[ $r -eq 0 ] || exit $((r | 16))
|
||||
[ $r -eq 0 ] || exit $(($r | 16))
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
use 5.008;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# ABSTRACT: Module collection to parse Matroska files.
|
||||
package Parse::Matroska;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
C<use>s L<Parse::Matroska::Reader>. See the documentation
|
||||
of the modules mentioned in L</"SEE ALSO"> for more information
|
||||
in how to use this module.
|
||||
|
||||
It's intended for this module to contain high-level interfaces
|
||||
to the other modules in the distribution.
|
||||
|
||||
=head1 SOURCE CODE
|
||||
|
||||
L<https://github.com/Kovensky/Parse-Matroska>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Parse::Matroska::Reader>, L<Parse::Matroska::Element>,
|
||||
L<Parse::Matroska::Definitions>.
|
||||
|
||||
=cut
|
||||
|
||||
use Parse::Matroska::Reader;
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,351 @@
|
||||
use 5.008;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# ABSTRACT: internal EBML grammar definitions
|
||||
package Parse::Matroska::Definitions;
|
||||
|
||||
use Parse::Matroska::Utils qw{uniq uncamelize};
|
||||
|
||||
use Exporter;
|
||||
our @ISA = qw{Exporter};
|
||||
our @EXPORT_OK = qw{elem_by_hexid %EBML_DEFINITION %MATROSKA_DEFINITION};
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Parse::Matroska::Definitions qw{elem_by_hexid};
|
||||
my $ebml_id = elem_by_hexid('1a45dfa3');
|
||||
print "EBML ID $ebml_id->{elid}'s name: $ebml_id->{name}";
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Contains the definition of the EBML grammar as expected in
|
||||
Matroska files. This module is meant mostly for internal use.
|
||||
|
||||
As this was extended from a script in mpv-player, some data
|
||||
generated is apparently useless for regular module users
|
||||
but is still relevant to the mpv-player script. Such data
|
||||
is annotated as being for mpv compatibility.
|
||||
|
||||
=head1 NOTE
|
||||
|
||||
The API of this module is not yet considered stable.
|
||||
|
||||
=head1 GLOBALS
|
||||
|
||||
These global variables are considered B<immutable>.
|
||||
|
||||
=head2 @Parse::Matroska::Definitions::global_elem_list
|
||||
|
||||
A global list of known matroska elements. Useful for
|
||||
mpv's matroska script, used for generating C headers
|
||||
that parse matroska.
|
||||
|
||||
=head2 %Parse::Matroska::Definitions::global_elem_dict
|
||||
|
||||
A global hash of known matroska elements. Used internally
|
||||
by L</elem_by_hexid($id)>.
|
||||
|
||||
=cut
|
||||
|
||||
@Parse::Matroska::Definitions::global_elem_list = ();
|
||||
%Parse::Matroska::Definitions::global_elem_dict = ();
|
||||
|
||||
=head2 %EBML_DEFINITION
|
||||
|
||||
Optionally-importable hash of known EBML IDs belonging
|
||||
to the EBML generic grammar.
|
||||
|
||||
=head2 %MATROSKA_DEFINITION
|
||||
|
||||
Optionally-importable hash of known EBML IDs belonging
|
||||
to the Matroska-specific grammar.
|
||||
|
||||
=cut
|
||||
|
||||
our %EBML_DEFINITION = define_ebml();
|
||||
our %MATROSKA_DEFINITION = define_matroska();
|
||||
|
||||
=method elem_by_hexid($id)
|
||||
|
||||
Returns an EBML Element Definition corresponding to the provided
|
||||
hexadecimal string. Returns C<undef> if the element is unknown.
|
||||
|
||||
=cut
|
||||
sub elem_by_hexid {
|
||||
my ($elid) = @_;
|
||||
return $Parse::Matroska::Definitions::global_elem_dict{$elid};
|
||||
}
|
||||
|
||||
################################################
|
||||
### Helper functions for document definition ###
|
||||
################################################
|
||||
|
||||
# used by elem when setting the 'valname' key
|
||||
use constant TYPE_MAP => {
|
||||
uint => 'uint64_t',
|
||||
str => 'struct bstr',
|
||||
binary => 'struct bstr',
|
||||
ebml_id => 'uint32_t',
|
||||
float => 'double',
|
||||
sint => 'int64_t',
|
||||
};
|
||||
|
||||
# this will be localized to "MATROSKA" or "EBML" on the elem declarations
|
||||
our $ELEM_DEFINE_TYPE = undef;
|
||||
|
||||
=method elem($name,$elid,$valtype)
|
||||
|
||||
NOTE: never call this function yourself; it changes data structures
|
||||
that are considered immutable outside of this package.
|
||||
|
||||
Internal API function that generates the EBML Element Definitions.
|
||||
|
||||
This API function returns an array which first element is C<$elid>
|
||||
and the second is a generated hash. The generated hash is stored
|
||||
in the @global_elem_list and %global_elem_dict.
|
||||
|
||||
The generated hash contains:
|
||||
|
||||
=for :list
|
||||
= name
|
||||
The EBML Element's name, given through C<$name>.
|
||||
= elid
|
||||
The EBML Element's hex id, given through C<$elid>. Used for lookups by L</elem_by_hexid($id)>.
|
||||
= valtype
|
||||
The EBML Element's type, given through C<$valtype>, except when C<$valtype> is an arrayref.
|
||||
= multiple
|
||||
If C<$name> ends with a C<*>, this is set as true and strips the C<*> from L</name>. Used to
|
||||
mark elements that may be repeated.
|
||||
= subelements
|
||||
An arrayref of elements that may be children of this element, given through C<$valtype> if it
|
||||
is an arrayref. Sets L</valtype> to C<sub> if there are subelements.
|
||||
= subids
|
||||
An arrayref listing all the L</elid>s of subelements, C<uniq>ified.
|
||||
|
||||
The following elements are for mpv compatibility:
|
||||
|
||||
=for :list
|
||||
= definename
|
||||
Name used for generating C #defines.
|
||||
= fieldname
|
||||
Name used for generating C struct fields.
|
||||
= structname
|
||||
Name used for generating C struct names.
|
||||
= ebmltype
|
||||
A pre-#defined constant to describe the element's type.
|
||||
= valname
|
||||
Typename used when declaring a struct field referring to this element.
|
||||
|
||||
=cut
|
||||
sub elem {
|
||||
my %e = (name => shift, elid => shift, valtype => shift);
|
||||
|
||||
# strip * from name, set 'multiple' if there was one
|
||||
$e{multiple} = scalar $e{name} =~ s/\*$//;
|
||||
|
||||
# ELEM_DEFINE_TYPE is either MATROSKA or EBML
|
||||
$e{definename} = "${ELEM_DEFINE_TYPE}_ID_".uc($e{name});
|
||||
$e{fieldname} = uncamelize $e{name};
|
||||
$e{structname} = "ebml_$e{fieldname}";
|
||||
|
||||
if (ref $e{valtype} eq 'HASH') {
|
||||
$e{subelements} = $e{valtype};
|
||||
$e{subids} = uniq map { $_->{elid} } values %{$e{subelements}};
|
||||
$e{valtype} = 'sub';
|
||||
$e{ebmltype} = 'EBML_TYPE_SUBELEMENTS';
|
||||
$e{valname} = "struct $e{structname}";
|
||||
} else {
|
||||
$e{ebmltype} = "EBML_TYPE_\U$e{valtype}";
|
||||
die "Unrecognized value type $e{valtype}" unless
|
||||
defined ($e{valname} = TYPE_MAP->{$e{valtype}});
|
||||
}
|
||||
my $e = \%e;
|
||||
push @Parse::Matroska::Definitions::global_elem_list, $e;
|
||||
$Parse::Matroska::Definitions::global_elem_dict{$e{elid}} = $e;
|
||||
return ($e{elid}, $e);
|
||||
}
|
||||
|
||||
#############################################
|
||||
### EBML and Matroska document definitons ###
|
||||
#############################################
|
||||
|
||||
=method define_ebml
|
||||
|
||||
Internal function that defines the EBML generic grammar.
|
||||
|
||||
Must not be called from outside the package.
|
||||
|
||||
=cut
|
||||
sub define_ebml {
|
||||
local $ELEM_DEFINE_TYPE = 'EBML';
|
||||
return (
|
||||
elem('EBML', '1a45dfa3', {
|
||||
elem('EBMLVersion', '4286', 'uint'),
|
||||
elem('EBMLReadVersion', '42f7', 'uint'),
|
||||
elem('EBMLMaxIDLength', '42f2', 'uint'),
|
||||
elem('EBMLMaxSizeLength', '42f3', 'uint'),
|
||||
elem('DocType', '4282', 'str'),
|
||||
elem('DocTypeVersion', '4287', 'uint'),
|
||||
elem('DocTypeReadVersion', '4285', 'uint'),
|
||||
}),
|
||||
|
||||
elem('CRC32', 'bf', 'binary'),
|
||||
elem('Void', 'ec', 'binary'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
=method define_matroska
|
||||
|
||||
Internal function that defines the Matroska-specific EBML grammar.
|
||||
|
||||
Must not be called from outside the package.
|
||||
|
||||
=cut
|
||||
sub define_matroska {
|
||||
local $ELEM_DEFINE_TYPE = 'MATROSKA';
|
||||
return (
|
||||
elem('Segment', '18538067', {
|
||||
elem('SeekHead*', '114d9b74', {
|
||||
elem('Seek*', '4dbb', {
|
||||
elem('SeekID', '53ab', 'ebml_id'),
|
||||
elem('SeekPosition', '53ac', 'uint'),
|
||||
}),
|
||||
}),
|
||||
|
||||
elem('Info*', '1549a966', {
|
||||
elem('SegmentUID', '73a4', 'binary'),
|
||||
elem('PrevUID', '3cb923', 'binary'),
|
||||
elem('NextUID', '3eb923', 'binary'),
|
||||
elem('TimecodeScale', '2ad7b1', 'uint'),
|
||||
elem('DateUTC', '4461', 'sint'),
|
||||
elem('Title', '7ba9', 'str'),
|
||||
elem('MuxingApp', '4d80', 'str'),
|
||||
elem('WritingApp', '5741', 'str'),
|
||||
elem('Duration', '4489', 'float'),
|
||||
}),
|
||||
|
||||
elem('Cluster*', '1f43b675', {
|
||||
elem('Timecode', 'e7', 'uint'),
|
||||
elem('BlockGroup*', 'a0', {
|
||||
elem('Block', 'a1', 'binary'),
|
||||
elem('BlockDuration', '9b', 'uint'),
|
||||
elem('ReferenceBlock*', 'fb', 'sint'),
|
||||
}),
|
||||
elem('SimpleBlock*', 'a3', 'binary'),
|
||||
}),
|
||||
|
||||
elem('Tracks*', '1654ae6b', {
|
||||
elem('TrackEntry*', 'ae', {
|
||||
elem('TrackNumber', 'd7', 'uint'),
|
||||
elem('TrackUID', '73c5', 'uint'),
|
||||
elem('TrackType', '83', 'uint'),
|
||||
elem('FlagEnabled', 'b9', 'uint'),
|
||||
elem('FlagDefault', '88', 'uint'),
|
||||
elem('FlagForced', '55aa', 'uint'),
|
||||
elem('FlagLacing', '9c', 'uint'),
|
||||
elem('MinCache', '6de7', 'uint'),
|
||||
elem('MaxCache', '6df8', 'uint'),
|
||||
elem('DefaultDuration', '23e383', 'uint'),
|
||||
elem('TrackTimecodeScale', '23314f', 'float'),
|
||||
elem('MaxBlockAdditionID', '55ee', 'uint'),
|
||||
elem('Name', '536e', 'str'),
|
||||
elem('Language', '22b59c', 'str'),
|
||||
elem('CodecID', '86', 'str'),
|
||||
elem('CodecPrivate', '63a2', 'binary'),
|
||||
elem('CodecName', '258688', 'str'),
|
||||
elem('CodecDecodeAll', 'aa', 'uint'),
|
||||
elem('Video', 'e0', {
|
||||
elem('FlagInterlaced', '9a', 'uint'),
|
||||
elem('PixelWidth', 'b0', 'uint'),
|
||||
elem('PixelHeight', 'ba', 'uint'),
|
||||
elem('DisplayWidth', '54b0', 'uint'),
|
||||
elem('DisplayHeight', '54ba', 'uint'),
|
||||
elem('DisplayUnit', '54b2', 'uint'),
|
||||
elem('FrameRate', '2383e3', 'float'),
|
||||
elem('ColourSpace', '2eb524', 'binary'),
|
||||
}),
|
||||
elem('Audio', 'e1', {
|
||||
elem('SamplingFrequency', 'b5', 'float'),
|
||||
elem('OutputSamplingFrequency', '78b5', 'float'),
|
||||
elem('Channels', '9f', 'uint'),
|
||||
elem('BitDepth', '6264', 'uint'),
|
||||
}),
|
||||
elem('ContentEncodings', '6d80', {
|
||||
elem('ContentEncoding*', '6240', {
|
||||
elem('ContentEncodingOrder', '5031', 'uint'),
|
||||
elem('ContentEncodingScope', '5032', 'uint'),
|
||||
elem('ContentEncodingType', '5033', 'uint'),
|
||||
elem('ContentCompression', '5034', {
|
||||
elem('ContentCompAlgo', '4254', 'uint'),
|
||||
elem('ContentCompSettings', '4255', 'binary'),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
||||
elem('Cues', '1c53bb6b', {
|
||||
elem('CuePoint*', 'bb', {
|
||||
elem('CueTime', 'b3', 'uint'),
|
||||
elem('CueTrackPositions*', 'b7', {
|
||||
elem('CueTrack', 'f7', 'uint'),
|
||||
elem('CueClusterPosition', 'f1', 'uint'),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
||||
elem('Attachments', '1941a469', {
|
||||
elem('AttachedFile*', '61a7', {
|
||||
elem('FileDescription', '467e', 'str'),
|
||||
elem('FileName', '466e', 'str'),
|
||||
elem('FileMimeType', '4660', 'str'),
|
||||
elem('FileData', '465c', 'binary'),
|
||||
elem('FileUID', '46ae', 'uint'),
|
||||
}),
|
||||
}),
|
||||
|
||||
elem('Chapters', '1043a770', {
|
||||
elem('EditionEntry*', '45b9', {
|
||||
elem('EditionUID', '45bc', 'uint'),
|
||||
elem('EditionFlagHidden', '45bd', 'uint'),
|
||||
elem('EditionFlagDefault', '45db', 'uint'),
|
||||
elem('EditionFlagOrdered', '45dd', 'uint'),
|
||||
elem('ChapterAtom*', 'b6', {
|
||||
elem('ChapterUID', '73c4', 'uint'),
|
||||
elem('ChapterTimeStart', '91', 'uint'),
|
||||
elem('ChapterTimeEnd', '92', 'uint'),
|
||||
elem('ChapterFlagHidden', '98', 'uint'),
|
||||
elem('ChapterFlagEnabled', '4598', 'uint'),
|
||||
elem('ChapterSegmentUID', '6e67', 'binary'),
|
||||
elem('ChapterSegmentEditionUID', '6ebc', 'uint'),
|
||||
elem('ChapterDisplay*', '80', {
|
||||
elem('ChapString', '85', 'str'),
|
||||
elem('ChapLanguage*', '437c', 'str'),
|
||||
elem('ChapCountry*', '437e', 'str'),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
elem('Tags*', '1254c367', {
|
||||
elem('Tag*', '7373', {
|
||||
elem('Targets', '63c0', {
|
||||
elem('TargetTypeValue', '68ca', 'uint'),
|
||||
elem('TargetTrackUID', '63c5', 'uint'),
|
||||
elem('TargetEditionUID', '63c9', 'uint'),
|
||||
elem('TargetChapterUID', '63c4', 'uint'),
|
||||
elem('TargetAttachmentUID', '63c6', 'uint'),
|
||||
}),
|
||||
elem('SimpleTag*', '67c8', {
|
||||
elem('TagName', '45a3', 'str'),
|
||||
elem('TagLanguage', '447a', 'str'),
|
||||
elem('TagString', '4487', 'str'),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,331 @@
|
||||
use 5.008;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# ABSTRACT: a mid-level representation of an EBML element
|
||||
package Parse::Matroska::Element;
|
||||
|
||||
use Carp;
|
||||
use List::Util qw{first};
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Parse::Matroska::Reader;
|
||||
my $reader = Parse::Matroska::Reader->new($path);
|
||||
my $elem = $reader->read_element;
|
||||
|
||||
print "ID: $elem->{elid}\n";
|
||||
print "Name: $elem->{name}\n";
|
||||
print "Length: $elem->{content_len}\n";
|
||||
print "Type: $elem->{type}\n";
|
||||
print "Child count: ", scalar(@{$elem->all_children}), "\n";
|
||||
if ($elem->{type} eq 'sub') {
|
||||
while (my $chld = $elem->next_child) {
|
||||
print "Child Name: $chld->{name}\n";
|
||||
}
|
||||
} else {
|
||||
print "Value: ", $elem->get_value, "\n";
|
||||
}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Represents a single Matroska element as decoded by
|
||||
L<Parse::Matroska::Reader>. This is essentially a hash
|
||||
augmented with functions for delay-loading of binary
|
||||
values and children elements.
|
||||
|
||||
=head1 NOTE
|
||||
|
||||
The API of this module is not yet considered stable.
|
||||
|
||||
=attr elid
|
||||
|
||||
The EBML Element ID, suitable for passing to
|
||||
L<Parse::Matroska::Definitions/elem_by_hexid>.
|
||||
|
||||
=attr name
|
||||
|
||||
The EBML Element's name.
|
||||
|
||||
=attr type
|
||||
|
||||
The EBML Element's type. Can be C<uint>, C<sint>,
|
||||
C<float>, C<ebml_id>, C<str> or C<binary>. See L</value>
|
||||
for details.
|
||||
|
||||
Equivalent to
|
||||
C<elem_by_hexid($elem-E<gt>{value})-E<gt>{valtype}>.
|
||||
|
||||
=attr value
|
||||
|
||||
The EBML Element's value. Should be obtained through
|
||||
L</get_value>.
|
||||
|
||||
Is an unicode string if the L</type> is C<str>, that is,
|
||||
the string has already been decoded by L<Encode/decode>.
|
||||
|
||||
Is C<undef> if the L</type> is C<binary> and the contents
|
||||
were delay-loaded and not yet read. L</get_value> will
|
||||
do the delayed load if needed.
|
||||
|
||||
Is an arrayref if the L</type> is C<sub>, containing
|
||||
the children nodes that were already loaded.
|
||||
|
||||
Is a hashref if the L</type> is C<ebml_id>, containing
|
||||
the referred element's information as defined in
|
||||
L<Parse::Matroska::Definitions>. Calling
|
||||
C<elem_by_hexid($elem-E<gt>{value}-E<gt>{elid})> will
|
||||
return the same object as $elem->{value}.
|
||||
|
||||
=attr full_len
|
||||
|
||||
The entire length of this EBML Element, including
|
||||
the header's.
|
||||
|
||||
=attr size_len
|
||||
|
||||
The length of the size marker. Used when calculating
|
||||
L</full_len> from L</content_len>
|
||||
|
||||
=attr content_len
|
||||
|
||||
The length of the contents of this EBML Element,
|
||||
which excludes the header.
|
||||
|
||||
=attr reader
|
||||
|
||||
A weakened reference to the associated
|
||||
L<Parse::Matroska::Reader>.
|
||||
|
||||
=method new(%hash)
|
||||
|
||||
Creates a new Element initialized with the hash
|
||||
given as argument.
|
||||
|
||||
=cut
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = {};
|
||||
bless $self, $class;
|
||||
|
||||
$self->initialize(@_);
|
||||
return $self;
|
||||
}
|
||||
|
||||
=method initialize(%hash)
|
||||
|
||||
Called by L</new> on initialization.
|
||||
|
||||
=cut
|
||||
sub initialize {
|
||||
my ($self, %args) = @_;
|
||||
for (keys %args) {
|
||||
$self->{$_} = $args{$_};
|
||||
}
|
||||
$self->{depth} = 0 unless $self->{depth};
|
||||
}
|
||||
|
||||
=method skip
|
||||
|
||||
Called by the user to ignore the contents of this EBML node.
|
||||
Needed when ignoring the children of a node.
|
||||
|
||||
=cut
|
||||
sub skip {
|
||||
my ($self) = @_;
|
||||
my $reader = $self->{reader};
|
||||
return unless $reader; # we don't have to skip if there's no reader
|
||||
my $pos = $reader->getpos;
|
||||
croak "Too late to skip, reads were already done"
|
||||
if $pos ne $self->{data_pos};
|
||||
$reader->skip($self->{content_len});
|
||||
}
|
||||
|
||||
=method get_value($keep_bin)
|
||||
|
||||
Returns the value contained by this EBML element.
|
||||
|
||||
If the element has children, returns an arrayref to
|
||||
the children elements that were already encountered.
|
||||
|
||||
If the element's type is C<binary> and the value was
|
||||
delay-loaded, does the reading now.
|
||||
|
||||
If $keep_bin is true, the delay-loaded data is kept
|
||||
as the L</value>, otherwise, further calls to
|
||||
C<get_value> will reread the data from the L</reader>.
|
||||
|
||||
=cut
|
||||
sub get_value {
|
||||
my ($self, $keep_bin) = @_;
|
||||
|
||||
return undef if $self->{type} eq 'skip';
|
||||
return $self->{value} if $self->{value};
|
||||
|
||||
my $reader = $self->{reader} or
|
||||
croak "The associated Reader has been deleted";
|
||||
|
||||
# delay-loaded 'binary'
|
||||
if ($self->{type} eq 'binary') {
|
||||
croak "Cannot seek in the current Reader" unless $self->{data_pos};
|
||||
# seek to the data position...
|
||||
$reader->setpos($self->{data_pos});
|
||||
# read the data, keeping it in value if requested
|
||||
if ($keep_bin) {
|
||||
$self->{value} = $reader->readlen($self->{content_len});
|
||||
return $self->{value};
|
||||
} else {
|
||||
return $reader->readlen($self->{content_len});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=method next_child($read_bin)
|
||||
|
||||
Builtin iterator; reads and returns the next child element.
|
||||
Always returns undef if the type isn't C<sub>.
|
||||
|
||||
Returns undef at the end of the iterator and resets itself to
|
||||
point to the first element; so calling L</next_child($read_bin)>
|
||||
after the iterator returned C<undef> will return the first child.
|
||||
|
||||
The optional C<$read_bin> parameter has the children elements
|
||||
not delay-load their value if their type is C<binary>.
|
||||
|
||||
If all children elements have already been read, return
|
||||
each element in-order as would be given by
|
||||
L</all_children($recurse,$read_bin)>.
|
||||
|
||||
=cut
|
||||
sub next_child {
|
||||
my ($self, $read_bin) = @_;
|
||||
return unless $self->{type} eq 'sub';
|
||||
|
||||
if ($self->{_all_children_read}) {
|
||||
my $idx = $self->{_last_child} ||= 0;
|
||||
if ($idx == @{$self->{value}}) {
|
||||
# reset the iterator, returning undef once
|
||||
$self->{_last_child} = 0;
|
||||
return;
|
||||
}
|
||||
my $ret = $self->{value}->[$idx];
|
||||
|
||||
++$idx;
|
||||
$self->{_last_child} = $idx;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
my $len = defined $self->{remaining_len}
|
||||
? $self->{remaining_len}
|
||||
: $self->{content_len};
|
||||
|
||||
if ($len == 0) {
|
||||
# we've read all children; switch into $self->{value} iteration mode
|
||||
$self->{_all_children_read} = 1;
|
||||
# return undef since the iterator will reset
|
||||
return;
|
||||
}
|
||||
|
||||
$self->{pos_offset} ||= 0;
|
||||
my $pos = $self->{data_pos};
|
||||
my $reader = $self->{reader} or croak "The associated reader has been deleted";
|
||||
$reader->setpos($pos);
|
||||
$reader->{fh}->seek($self->{pos_offset}, 1) if $pos;
|
||||
|
||||
my $chld = $reader->read_element($read_bin);
|
||||
return undef unless defined $chld;
|
||||
$self->{pos_offset} += $chld->{full_len};
|
||||
|
||||
$self->{remaining_len} = $len - $chld->{full_len};
|
||||
|
||||
if ($self->{remaining_len} < 0) {
|
||||
croak "Child elements consumed $self->{remaining_len} more bytes than parent $self->{name} contained";
|
||||
}
|
||||
|
||||
$chld->{depth} = $self->{depth} + 1;
|
||||
$self->{value} ||= [];
|
||||
|
||||
push @{$self->{value}}, $chld;
|
||||
|
||||
return $chld;
|
||||
}
|
||||
|
||||
=method all_children($recurse,$read_bin)
|
||||
|
||||
Calls L</populate_children($recurse,$read_bin)> on self
|
||||
and returns an arrayref with the children nodes.
|
||||
|
||||
Both C<$recurse> and C<$read_bin> are optional and default
|
||||
to false.
|
||||
|
||||
=cut
|
||||
sub all_children {
|
||||
my ($self, $recurse, $read_bin) = @_;
|
||||
$self->populate_children($recurse, $read_bin);
|
||||
return $self->{value};
|
||||
}
|
||||
|
||||
=method children_by_name($name)
|
||||
|
||||
Searches in the already read children elements for all
|
||||
elements with the EBML name C<$name>. Returns an array
|
||||
containing all found elements. On scalar context,
|
||||
returns only the first element found.
|
||||
|
||||
Croaks if the element's C<type> isn't C<sub>.
|
||||
|
||||
=cut
|
||||
sub children_by_name {
|
||||
my ($self, $name) = @_;
|
||||
return unless defined wantarray; # don't do work if work isn't wanted
|
||||
croak "Element can't have children" unless $self->{type} eq 'sub';
|
||||
|
||||
my @found = grep { $_->{name} eq $name } @{$self->{value}};
|
||||
return @found if wantarray; # list
|
||||
return shift @found if defined wantarray; # scalar
|
||||
}
|
||||
|
||||
=method populate_children($recurse,$read_bin)
|
||||
|
||||
Populates the internal array of children elements, that is,
|
||||
requests that the associated L<Matroska::Parser::Reader> reads
|
||||
all children elements. Returns itself.
|
||||
|
||||
Returns false if the element's C<type> isn't C<sub>.
|
||||
|
||||
If C<$recurse> is provided and is true, the method will call
|
||||
itself in the children elements with the same parameters it
|
||||
received; this will build a full EBML tree.
|
||||
|
||||
If C<$read_bin> is provided and is true, disables delay-loading
|
||||
of the contents of C<binary>-type nodes, reading the contents
|
||||
to memory.
|
||||
|
||||
If both C<$recurse> and C<$read_bin> are true, entire EBML trees
|
||||
can be loaded without requiring seeks, thus behaving correctly
|
||||
on unseekable streams. If C<$read_bin> is false, the entire EBML
|
||||
tree is still loaded, but calling L</get_value> on C<binary>-type
|
||||
nodes will produce an error on unseekable streams.
|
||||
|
||||
=cut
|
||||
sub populate_children {
|
||||
my ($self, $recurse, $read_bin) = @_;
|
||||
|
||||
return unless $self->{type} eq 'sub';
|
||||
|
||||
if (@{$self->{value}} && $recurse) {
|
||||
# only recurse
|
||||
foreach (@{$self->{value}}) {
|
||||
$_->populate_children($recurse, $read_bin);
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
while (my $chld = $self->next_child($read_bin)) {
|
||||
$chld->populate_children($recurse, $read_bin) if $recurse;
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,426 @@
|
||||
use 5.008;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# ABSTRACT: a low-level reader for EBML files
|
||||
package Parse::Matroska::Reader;
|
||||
|
||||
use Parse::Matroska::Definitions qw{elem_by_hexid};
|
||||
use Parse::Matroska::Element;
|
||||
|
||||
use Carp;
|
||||
use Scalar::Util qw{openhandle weaken};
|
||||
use IO::Handle;
|
||||
use IO::File;
|
||||
use List::Util qw{first};
|
||||
use Encode;
|
||||
|
||||
use constant BIGINT_TRY => 'Pari,GMP,FastCalc';
|
||||
use Math::BigInt try => BIGINT_TRY;
|
||||
use Math::BigRat try => BIGINT_TRY;
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Parse::Matroska::Reader;
|
||||
my $reader = Parse::Matroska::Reader->new($path);
|
||||
$reader->close;
|
||||
$reader->open(\$string_with_matroska_data);
|
||||
|
||||
my $elem = $reader->read_element;
|
||||
print "Element ID: $elem->{elid}\n";
|
||||
print "Element name: $elem->{name}\n";
|
||||
if ($elem->{type} ne 'sub') {
|
||||
print "Element value: $elem->get_value\n";
|
||||
} else {
|
||||
while (my $child = $elem->next_child) {
|
||||
print "Child element: $child->{name}\n";
|
||||
}
|
||||
}
|
||||
$reader->close;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Reads EBML data, which is used in Matroska files.
|
||||
This is a low-level reader which is meant to be used as a backend
|
||||
for higher level readers. TODO: write the high level readers :)
|
||||
|
||||
=head1 NOTE
|
||||
|
||||
The API of this module is not yet considered stable.
|
||||
|
||||
=method new
|
||||
|
||||
Creates a new reader.
|
||||
Calls L</open($arg)> with its arguments if provided.
|
||||
|
||||
=cut
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = {};
|
||||
bless $self, $class;
|
||||
|
||||
$self->open(@_) if @_;
|
||||
return $self;
|
||||
}
|
||||
|
||||
=method open($arg)
|
||||
|
||||
Creates the internal filehandle. The argument can be:
|
||||
|
||||
=for :list
|
||||
* An open filehandle or L<IO::Handle> object.
|
||||
The filehandle is not C<dup()>ed, so calling L</close> in this
|
||||
object will close the given filehandle as well.
|
||||
* A scalar containing a path to a file.
|
||||
* On perl v5.14 or newer, a scalarref pointing to EBML data.
|
||||
For similar functionality in older perls, give an L<IO::String> object
|
||||
or the handle to an already C<open>ed scalarref.
|
||||
|
||||
=cut
|
||||
sub open {
|
||||
my ($self, $arg) = @_;
|
||||
$self->{fh} = openhandle($arg) || IO::File->new($arg, "<:raw")
|
||||
or croak "Can't open $arg: $!";
|
||||
}
|
||||
|
||||
=method close
|
||||
|
||||
Closes the internal filehandle.
|
||||
|
||||
=cut
|
||||
sub close {
|
||||
my ($self) = @_;
|
||||
$self->{fh}->close;
|
||||
delete $self->{fh};
|
||||
}
|
||||
|
||||
# equivalent to $self->readlen(1), possibly faster
|
||||
sub _getc {
|
||||
my ($self) = @_;
|
||||
my $c = $self->{fh}->getc;
|
||||
croak "Can't do read of length 1: $!" if !defined $c && $!;
|
||||
return $c;
|
||||
}
|
||||
|
||||
=method readlen($length)
|
||||
|
||||
Reads C<$length> bytes from the internal filehandle.
|
||||
|
||||
=cut
|
||||
sub readlen {
|
||||
my ($self, $len) = @_;
|
||||
my $data;
|
||||
my $readlen = $self->{fh}->read($data, $len);
|
||||
croak "Can't do read of length $len: $!"
|
||||
unless defined $readlen;
|
||||
return $data;
|
||||
}
|
||||
|
||||
# converts a byte string into an integer
|
||||
# we do so by converting the integer into a hex string (big-endian)
|
||||
# and then reading the hex-string into an integer
|
||||
sub _bin2int($) {
|
||||
my ($bin) = @_;
|
||||
# if the length is larger than 3
|
||||
# the resulting integer might be larger than INT_MAX
|
||||
if (length($bin) > 3) {
|
||||
return Math::BigInt->from_hex(unpack("H*", $bin));
|
||||
}
|
||||
return hex(unpack("H*", $bin));
|
||||
}
|
||||
|
||||
# creates a floating-point number with the given mantissa and exponent
|
||||
sub _ldexp {
|
||||
my ($mantissa, $exponent) = @_;
|
||||
my $r = new Math::BigRat($mantissa);
|
||||
return $r * Math::BigRat->new(2)**$exponent;
|
||||
}
|
||||
|
||||
# NOTE: the read_* functions are hard to read because they're ports
|
||||
# of even harder to read python functions.
|
||||
# TODO: make them readable
|
||||
|
||||
=method read_id
|
||||
|
||||
Reads an EBML ID atom in hexadecimal string format, suitable
|
||||
for passing to L<Parse::Matroska::Definitions/elem_by_hexid($id)>.
|
||||
|
||||
=cut
|
||||
sub read_id {
|
||||
my ($self) = @_;
|
||||
my $t = $self->_getc;
|
||||
return undef unless defined $t;
|
||||
my $i = 0;
|
||||
my $mask = 1<<7;
|
||||
|
||||
if (ord($t) == 0) {
|
||||
croak "Matroska Syntax error: first byte of ID was \\0"
|
||||
}
|
||||
until (ord($t) & $mask) {
|
||||
++$i;
|
||||
$mask >>= 1;
|
||||
}
|
||||
# return hex string of the bytes we just read
|
||||
return unpack "H*", ($t . $self->readlen($i));
|
||||
}
|
||||
|
||||
=method read_size
|
||||
|
||||
Reads an EBML Data Size atom, which immediately follows
|
||||
an EBML ID atom.
|
||||
|
||||
This returns an array consisting of:
|
||||
|
||||
=for :list
|
||||
0. The length of the Data Size atom.
|
||||
1. The value encoded in the Data Size atom, which is the length of all the data following it.
|
||||
|
||||
=cut
|
||||
sub read_size {
|
||||
my ($self) = @_;
|
||||
my $t = $self->_getc;
|
||||
my $i = 0;
|
||||
my $mask = 1<<7;
|
||||
|
||||
if (ord($t) == 0) {
|
||||
croak "Matroska Syntax error: first byte of data size was \\0"
|
||||
}
|
||||
until (ord($t) & $mask) {
|
||||
++$i;
|
||||
$mask >>= 1;
|
||||
}
|
||||
$t = $t & chr($mask-1); # strip length bits (keep only significant bits)
|
||||
return ($i+1, _bin2int $t . $self->readlen($i));
|
||||
}
|
||||
|
||||
=method read_str($length)
|
||||
|
||||
Reads a string of length C<$length> bytes from the internal filehandle.
|
||||
The string is already L<Encode/decode>d from C<UTF-8>, which is the
|
||||
standard Matroska string encoding.
|
||||
|
||||
=cut
|
||||
{
|
||||
my $utf8 = find_encoding("UTF-8");
|
||||
sub read_str {
|
||||
my ($self, $length) = @_;
|
||||
return $utf8->decode($self->readlen($length));
|
||||
}
|
||||
}
|
||||
|
||||
=method read_uint($length)
|
||||
|
||||
Reads an unsigned integer of length C<$length> bytes
|
||||
from the internal filehandle.
|
||||
|
||||
Returns a L<Math::BigInt> object if C<$length> is greater
|
||||
than 4.
|
||||
|
||||
=cut
|
||||
sub read_uint {
|
||||
my ($self, $length) = @_;
|
||||
return _bin2int $self->readlen($length);
|
||||
}
|
||||
|
||||
=method read_sint($length)
|
||||
|
||||
Reads a signed integer of length C<$length> bytes
|
||||
from the internal filehandle.
|
||||
|
||||
Returns a L<Math::BigInt> object if C<$length> is greater
|
||||
than 4.
|
||||
|
||||
=cut
|
||||
sub read_sint {
|
||||
my ($self, $length) = @_;
|
||||
my $i = $self->read_uint($length);
|
||||
|
||||
# Apply 2's complement to the unsigned int
|
||||
my $mask = int(2 ** ($length * 8 - 1));
|
||||
# if the most significant bit is set...
|
||||
if ($i & $mask) {
|
||||
# subtract the MSB twice
|
||||
$i -= 2 * $mask;
|
||||
}
|
||||
return $i;
|
||||
}
|
||||
|
||||
=method read_float($length)
|
||||
|
||||
Reads an IEEE floating point number of length C<$length>
|
||||
bytes from the internal filehandle.
|
||||
|
||||
Only lengths C<4> and C<8> are supported (C C<float> and C<double>).
|
||||
|
||||
=cut
|
||||
{
|
||||
my $b1 = new Math::BigInt 1;
|
||||
|
||||
sub read_float {
|
||||
my ($self, $length) = @_;
|
||||
my $i = new Math::BigInt $self->read_uint($length)->bstr;
|
||||
my $f;
|
||||
|
||||
# These evil expressions reinterpret an unsigned int as IEEE binary floats
|
||||
if ($length == 4) {
|
||||
$f = _ldexp(($i & ((1<<23) - 1)) + (1<<23), ($i>>23 & ((1<<8) - 1)) - 150);
|
||||
$f = -$f if $i & ($b1<<31);
|
||||
} elsif ($length == 8) {
|
||||
$f = _ldexp(($i & (($b1<<52) - 1)) + ($b1<<52), ($i>>52 & ((1<<12) - 1)) - 1075);
|
||||
$f = -$f if $i & ($b1<<63);
|
||||
} else {
|
||||
croak "Matroska Syntax error: unsupported IEEE float byte size $length";
|
||||
}
|
||||
|
||||
return $f;
|
||||
}
|
||||
}
|
||||
|
||||
=method read_ebml_id($length)
|
||||
|
||||
Reads an EBML ID when it's encoded as the data inside another
|
||||
EBML element, that is, when the enclosing element's C<type> is
|
||||
C<ebml_id>.
|
||||
|
||||
This returns a hashref with the EBML element description as
|
||||
defined in L<Parse::Matroska::Definitions>.
|
||||
|
||||
=cut
|
||||
sub read_ebml_id {
|
||||
my ($self, $length) = @_;
|
||||
return elem_by_hexid(unpack("H*", $self->readlen($length)));
|
||||
}
|
||||
|
||||
=method skip($length)
|
||||
|
||||
Skips C<$length> bytes in the internal filehandle.
|
||||
|
||||
=cut
|
||||
sub skip {
|
||||
my ($self, $len) = @_;
|
||||
return if $self->{fh}->can('seek') && $self->{fh}->seek($len, 1);
|
||||
$self->readlen($len);
|
||||
return;
|
||||
}
|
||||
|
||||
=method getpos
|
||||
|
||||
Wrapper for L<IO::Seekable/$io-E<gt>getpos> in the internal filehandle.
|
||||
|
||||
Returns undef if the internal filehandle can't C<getpos>.
|
||||
|
||||
=cut
|
||||
sub getpos {
|
||||
my ($self) = @_;
|
||||
return undef unless $self->{fh}->can('getpos');
|
||||
return $self->{fh}->getpos;
|
||||
}
|
||||
|
||||
=method setpos($pos)
|
||||
|
||||
Wrapper for L<IO::Seekable/$io-E<gt>setpos> in the internal filehandle.
|
||||
|
||||
Returns C<undef> if the internal filehandle can't C<setpos>.
|
||||
|
||||
Croaks if C<setpos> does not seek to the requested position,
|
||||
that is, if calling C<getpos> does not yield the same object
|
||||
as the C<$pos> argument.
|
||||
|
||||
=cut
|
||||
sub setpos {
|
||||
my ($self, $pos) = @_;
|
||||
return undef unless $pos && $self->{fh}->can('setpos');
|
||||
|
||||
my $ret = $self->{fh}->setpos($pos);
|
||||
croak "Cannot seek to correct position"
|
||||
unless $self->getpos eq $pos;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
=method read_element($read_bin)
|
||||
|
||||
Reads a full EBML element from the internal filehandle.
|
||||
|
||||
Returns a L<Parse::Matroska::Element> object initialized with
|
||||
the read data. If C<read_bin> is not present or is false, will
|
||||
delay-load the contents of C<binary> type elements, that is,
|
||||
they will only be loaded when calling C<get_value> on the
|
||||
returned L<Parse::Matroska::Element> object.
|
||||
|
||||
Does not read the children of the element if its type is
|
||||
C<sub>. Look into the L<Parse::Matroska::Element> interface
|
||||
for details in how to read children elements.
|
||||
|
||||
Pass a true C<$read_bin> if the stream being read is not
|
||||
seekable (C<getpos> is undef) and the contents of C<binary>
|
||||
elements is desired, otherwise seeking errors or internal
|
||||
filehandle corruption might occur.
|
||||
|
||||
=cut
|
||||
sub read_element {
|
||||
my ($self, $read_bin) = @_;
|
||||
return undef if $self->{fh}->eof;
|
||||
|
||||
my $elem_pos = $self->getpos;
|
||||
|
||||
my $elid = $self->read_id;
|
||||
my $elem_def = elem_by_hexid($elid);
|
||||
my ($size_len, $content_len) = $self->read_size;
|
||||
my $full_len = length($elid)/2 + $size_len + $content_len;
|
||||
|
||||
my $elem = Parse::Matroska::Element->new(
|
||||
elid => $elid,
|
||||
name => $elem_def && $elem_def->{name},
|
||||
type => $elem_def && $elem_def->{valtype},
|
||||
size_len => $size_len,
|
||||
content_len => $content_len,
|
||||
full_len => $full_len,
|
||||
reader => $self,
|
||||
elem_pos => $elem_pos,
|
||||
data_pos => $self->getpos,
|
||||
);
|
||||
weaken($elem->{reader});
|
||||
|
||||
if (defined $elem_def) {
|
||||
if ($elem->{type} eq 'sub') {
|
||||
$elem->{value} = [];
|
||||
} elsif ($elem->{type} eq 'str') {
|
||||
$elem->{value} = $self->read_str($content_len);
|
||||
} elsif ($elem->{type} eq 'ebml_id') {
|
||||
$elem->{value} = $self->read_ebml_id($content_len);
|
||||
} elsif ($elem->{type} eq 'uint') {
|
||||
$elem->{value} = $self->read_uint($content_len);
|
||||
} elsif ($elem->{type} eq 'sint') {
|
||||
$elem->{value} = $self->read_sint($content_len);
|
||||
} elsif ($elem->{type} eq 'float') {
|
||||
$elem->{value} = $self->read_float($content_len);
|
||||
} elsif ($elem->{type} eq 'skip') {
|
||||
$self->skip($content_len);
|
||||
} elsif ($elem->{type} eq 'binary') {
|
||||
if ($read_bin) {
|
||||
$elem->{value} = $self->readlen($content_len);
|
||||
} else {
|
||||
$self->skip($content_len);
|
||||
}
|
||||
} else {
|
||||
die "Matroska Definition error: type $elem->{valtype} unknown"
|
||||
}
|
||||
} else {
|
||||
$self->skip($content_len);
|
||||
}
|
||||
return $elem;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 CAVEATS
|
||||
|
||||
Children elements have to be processed as soon as an element
|
||||
with children is found, or their children ignored with
|
||||
L<Parse::Matroska::Element/skip>. Not doing so doesn't cause
|
||||
errors but results in an invalid structure, with constant C<0>
|
||||
depth.
|
||||
|
||||
To work correctly in unseekable streams, either the contents
|
||||
of C<binary>-type elements has to be ignored or the C<read_bin>
|
||||
flag to C<read_element> has to be true.
|
||||
@@ -0,0 +1,37 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# ABSTRACT: internally-used helper functions
|
||||
package Parse::Matroska::Utils;
|
||||
|
||||
use Exporter;
|
||||
our @ISA = qw{Exporter};
|
||||
our @EXPORT_OK = qw{uniq uncamelize};
|
||||
|
||||
=method uniq(@array)
|
||||
|
||||
The same as L<List::MoreUtils/"uniq LIST">.
|
||||
Included to avoid depending on it since it's
|
||||
not a core module.
|
||||
|
||||
=cut
|
||||
sub uniq(@) {
|
||||
my %seen;
|
||||
return grep { !$seen{$_}++ } @_;
|
||||
}
|
||||
|
||||
=method uncamelize($string)
|
||||
|
||||
Converts a "StringLikeTHIS" into a
|
||||
"string_like_this".
|
||||
|
||||
=cut
|
||||
sub uncamelize($) {
|
||||
local $_ = shift;
|
||||
# lc followed by UC: lc_UC
|
||||
s/(?<=[a-z])([A-Z])/_\L$1/g;
|
||||
# UC followed by two lc: _UClclc
|
||||
s/([A-Z])(?=[a-z]{2})/_\L$1/g;
|
||||
# strip leading _ that the second regexp might add; lowercase all
|
||||
s/^_//; lc
|
||||
}
|
||||
+10
-11
@@ -4,17 +4,16 @@ mpv lua scripts
|
||||
The lua scripts in this folder can be loaded on a one-time basis by
|
||||
adding the option
|
||||
|
||||
--script=/path/to/script.lua
|
||||
--lua=/path/to/script.lua
|
||||
|
||||
to mpv's command line.
|
||||
|
||||
Where appropriate, they may also be placed in ~/.config/mpv/scripts/ from
|
||||
where they will be automatically loaded when mpv starts.
|
||||
|
||||
This is only a small selection of internally maintained scripts. Some of them
|
||||
are just for testing mpv internals, or serve as examples. An extensive
|
||||
user-edited list of 3rd party scripts is available here:
|
||||
|
||||
https://github.com/mpv-player/mpv/wiki/User-Scripts
|
||||
|
||||
(Anyone can add their own scripts to that list.)
|
||||
Unless otherwise specified, they are also suitable for inclusion in
|
||||
the `~/.mpv/lua` directory where they will be loaded every time mpv
|
||||
starts, obviating the need to load them with the above `--lua=...`
|
||||
argument. This is acceptable as they do only basic argument parsing
|
||||
and key-binding registration, until those bound keys are actually
|
||||
pressed. They should therefore not interfere with normal playback
|
||||
(unless you have a conflicting user-defined key-binding, in which
|
||||
case, you may want to modify either the `mp.add_key_binding()` calls
|
||||
in the scripts, or your keybinding).
|
||||
@@ -1,126 +0,0 @@
|
||||
-- This script adds control to the dynamic range compression ffmpeg
|
||||
-- filter including key bindings for adjusting parameters.
|
||||
--
|
||||
-- See https://ffmpeg.org/ffmpeg-filters.html#acompressor for explanation
|
||||
-- of the parameteres.
|
||||
--
|
||||
-- Default key bindings:
|
||||
-- n: Toggle dynamic range compression on or off
|
||||
-- F1/Shift+F1: Increase/Decrease threshold parameter
|
||||
-- F2/Shift+F2: Increase/Decrease ratio parameter
|
||||
-- F3/Shift+F3: Increase/Decrease knee parameter
|
||||
-- F4/Shift+F4: Increase/Decrease makeup gain parameter
|
||||
-- F5/Shift+F5: Increase/Decrease attack parameter
|
||||
-- F6/Shift+F6: Increase/Decrease release parameter
|
||||
--
|
||||
-- To change key bindings in input.conf use:
|
||||
-- BINDING script-message-to acompressor toggle-acompressor
|
||||
-- BINDING script-message-to acompressor update-param PARAM INCREMENT
|
||||
-- BINDING is the key binding to use, PARAM is either 'attack', 'release',
|
||||
-- 'threshold', 'ratio', 'knee' or 'makeup' and INCREMENT is a signed floating
|
||||
-- point value to add to the current parameter value.
|
||||
--
|
||||
-- You may also just adjust default parameters to your liking in this table.
|
||||
local params = {
|
||||
-- 'hide' defines wether the parameter should be hidden from OSD display (it will still be included in ffmpeg filter graph).
|
||||
-- 'input_format' is used to parse the value back from a obtained filter graph.
|
||||
-- 'output_format' defines how the value shall be formatted for creating the filter graph.
|
||||
{ name = 'Attack', value= 20, min=0.01, max=2000, hide= 20, input_format='attack=(%d+[.%d+]*)', output_format='%g' },
|
||||
{ name = 'Release', value=250, min=0.01, max=9000, hide=250, input_format='release=(%d+[.%d+]*)', output_format='%g' },
|
||||
{ name = 'Threshold', value=-25, min= -30, max= 0, hide=nil, input_format='threshold=(-%d+[.%d+]*)dB', output_format='%gdB' },
|
||||
{ name = 'Ratio', value= 3, min= 1, max= 20, hide=nil, input_format='ratio=(%d+[.%d+]*)', output_format='%g' },
|
||||
{ name = 'Knee', value= 2, min= 1, max= 10, hide= 2, input_format='knee=(%d+[.%d+]*)dB', output_format='%gdB' },
|
||||
{ name = 'Makeup', value= 8, min= 0, max= 24, hide=nil, input_format='makeup=(%d+[.%d+]*)dB', output_format='%gdB' }
|
||||
}
|
||||
|
||||
-- Defines the mpv filter label to be used. This allows us to easily add/replace/remove it, so
|
||||
-- it should be left so something meaningful and unique.
|
||||
local filter_label = 'acompressor'
|
||||
|
||||
local function update_filter()
|
||||
local graph = {}
|
||||
local pretty = {}
|
||||
|
||||
for _,param in pairs(params) do
|
||||
graph[#graph+1] = string.format('%s=' .. param.output_format, string.lower(param.name), param.value)
|
||||
if param.hide ~= param.value then
|
||||
pretty[#pretty+1] = string.format('%s: ' .. param.output_format, param.name, param.value)
|
||||
end
|
||||
end
|
||||
|
||||
if #pretty == 0 then
|
||||
pretty = ''
|
||||
else
|
||||
pretty = '\n(' .. table.concat(pretty, ', ') .. ')'
|
||||
end
|
||||
|
||||
mp.command(string.format('no-osd af add @%s:lavfi=[acompressor=%s]; show-text "Dynamic range compressor: enabled%s" 4000', filter_label, table.concat(graph, ':'), pretty))
|
||||
end
|
||||
|
||||
local function read_filter()
|
||||
local graph = nil
|
||||
local af = mp.get_property_native('af', {})
|
||||
|
||||
for i = 1, #af do
|
||||
if af[i]['name'] == 'lavfi' and af[i]['label'] == 'acompressor' then
|
||||
graph = af[i]['params']['graph']
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if graph == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
for _,param in pairs(params) do
|
||||
local value = tonumber(string.match(graph, param.input_format))
|
||||
if value ~= nil and value >= param.min and value <= param.max then
|
||||
param.value = value
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function toggle_acompressor()
|
||||
if read_filter() then
|
||||
mp.command(string.format('no-osd af del @%s; show-text "Dynamic range compressor: disabled"', filter_label))
|
||||
else
|
||||
update_filter()
|
||||
end
|
||||
end
|
||||
|
||||
local function update_param(name, increment)
|
||||
-- The current filter values could come from a watch_later config.
|
||||
-- read_filter() will parse them, so that we don't clobber those with our default values.
|
||||
read_filter()
|
||||
for _,param in pairs(params) do
|
||||
if string.lower(param.name) == string.lower(name) then
|
||||
param.value = math.max(param.min, math.min(param.value + increment, param.max))
|
||||
update_filter()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
mp.msg.error('Unknown parameter "' .. name .. '"')
|
||||
end
|
||||
|
||||
mp.add_key_binding("n", "toggle-acompressor", toggle_acompressor)
|
||||
mp.register_script_message('update-param', update_param)
|
||||
|
||||
mp.add_key_binding("F1", 'acompressor-inc-threshold', function() update_param('threshold', -5); end, { repeatable = true })
|
||||
mp.add_key_binding("Shift+F1", 'acompressor-dec-threshold', function() update_param('Threshold', 5); end, { repeatable = true })
|
||||
|
||||
mp.add_key_binding("F2", 'acompressor-inc-ratio', function() update_param('Ratio', 1); end, { repeatable = true })
|
||||
mp.add_key_binding("Shift+F2", 'acompressor-dec-ratio', function() update_param('Ratio', -1); end, { repeatable = true })
|
||||
|
||||
mp.add_key_binding("F3", 'acompressor-inc-knee', function() update_param('Knee', 1); end, { repeatable = true })
|
||||
mp.add_key_binding("Shift+F3", 'acompressor-dec-knee', function() update_param('Knee', -1); end, { repeatable = true })
|
||||
|
||||
mp.add_key_binding("F4", 'acompressor-inc-makeup', function() update_param('Makeup', 1); end, { repeatable = true })
|
||||
mp.add_key_binding("Shift+F4", 'acompressor-dec-makeup', function() update_param('Makeup', -1); end, { repeatable = true })
|
||||
|
||||
mp.add_key_binding("F5", 'acompressor-inc-attack', function() update_param('Attack', 10); end, { repeatable = true })
|
||||
mp.add_key_binding("Shift+F5", 'acompressor-dec-attack', function() update_param('Attack', -10); end, { repeatable = true })
|
||||
|
||||
mp.add_key_binding("F6", 'acompressor-inc-release', function() update_param('Release', 10); end, { repeatable = true })
|
||||
mp.add_key_binding("Shift+F6", 'acompressor-dec-release', function() update_param('Release', -10); end, { repeatable = true })
|
||||
@@ -1,20 +0,0 @@
|
||||
-- Handles the edge case where previous attempts to init audio have failed, but
|
||||
-- might start working due to a newly added device. This is required in
|
||||
-- particular for ao=wasapi, since the internal IMMNotificationClient code that
|
||||
-- normally triggers ao-reload will not be running in this case.
|
||||
|
||||
function do_reload()
|
||||
mp.command("ao-reload")
|
||||
reloading = nil
|
||||
end
|
||||
|
||||
function on_audio_device_list_change()
|
||||
if mp.get_property("current-ao") == "null" and not reloading then
|
||||
mp.msg.verbose("audio-device-list changed: reloading audio")
|
||||
-- avoid calling ao-reload too often
|
||||
reloading = mp.add_timeout(0.5, do_reload)
|
||||
end
|
||||
end
|
||||
|
||||
mp.set_property("options/audio-fallback-to-null", "yes")
|
||||
mp.observe_property("audio-device-list", "native", on_audio_device_list_change)
|
||||
@@ -1,13 +0,0 @@
|
||||
local utils = require("mp.utils")
|
||||
|
||||
mp.observe_property("audio-device-list", "native", function(name, val)
|
||||
print("Audio device list changed:")
|
||||
for index, e in ipairs(val) do
|
||||
print(" - '" .. e.name .. "' (" .. e.description .. ")")
|
||||
end
|
||||
end)
|
||||
|
||||
mp.observe_property("audio-out-detected-device", "native", function(name, val)
|
||||
print("Detected audio device changed:")
|
||||
print(" - '" .. val)
|
||||
end)
|
||||
+19
-19
@@ -21,7 +21,7 @@
|
||||
-- The default delay between insertion of the cropdetect and
|
||||
-- crop filters may be overridden by adding
|
||||
--
|
||||
-- --script-opts=autocrop.detect_seconds=<number of seconds>
|
||||
-- --lua-opts=autocrop.detect_seconds=<number of seconds>
|
||||
--
|
||||
-- to mpv's arguments. This may be desirable to allow cropdetect more
|
||||
-- time to collect data.
|
||||
@@ -42,11 +42,11 @@ function del_filter_if_present(label)
|
||||
-- error if the filter doesn't exist
|
||||
local vfs = mp.get_property_native("vf")
|
||||
for i,vf in pairs(vfs) do
|
||||
if vf["label"] == label then
|
||||
table.remove(vfs, i)
|
||||
mp.set_property_native("vf", vfs)
|
||||
return true
|
||||
end
|
||||
if vf["label"] == label then
|
||||
table.remove(vfs, i)
|
||||
mp.set_property_native("vf", vfs)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
@@ -65,10 +65,10 @@ function autocrop_start()
|
||||
|
||||
-- insert the cropdetect filter
|
||||
ret=mp.command(
|
||||
string.format(
|
||||
'vf add @%s:lavfi=graph="cropdetect=limit=24:round=2:reset=0"',
|
||||
cropdetect_label
|
||||
)
|
||||
string.format(
|
||||
'vf add @%s:lavfi=graph="cropdetect=limit=24:round=2:reset=0"',
|
||||
cropdetect_label
|
||||
)
|
||||
)
|
||||
-- wait to gather data
|
||||
timer=mp.add_timeout(detect_seconds, do_crop)
|
||||
@@ -77,15 +77,15 @@ end
|
||||
function do_crop()
|
||||
-- get the metadata
|
||||
local cropdetect_metadata = mp.get_property_native(
|
||||
string.format("vf-metadata/%s", cropdetect_label)
|
||||
string.format("vf-metadata/%s", cropdetect_label)
|
||||
)
|
||||
-- use it to crop if its valid
|
||||
if cropdetect_metadata then
|
||||
if cropdetect_metadata["lavfi.cropdetect.w"]
|
||||
and cropdetect_metadata["lavfi.cropdetect.h"]
|
||||
and cropdetect_metadata["lavfi.cropdetect.x"]
|
||||
and cropdetect_metadata["lavfi.cropdetect.y"]
|
||||
then
|
||||
if cropdetect_metadata["lavfi.cropdetect.w"]
|
||||
and cropdetect_metadata["lavfi.cropdetect.h"]
|
||||
and cropdetect_metadata["lavfi.cropdetect.x"]
|
||||
and cropdetect_metadata["lavfi.cropdetect.y"]
|
||||
then
|
||||
mp.command(string.format("vf add @%s:crop=%s:%s:%s:%s",
|
||||
crop_label,
|
||||
cropdetect_metadata["lavfi.cropdetect.w"],
|
||||
@@ -94,9 +94,9 @@ function do_crop()
|
||||
cropdetect_metadata["lavfi.cropdetect.y"]))
|
||||
else
|
||||
mp.msg.error(
|
||||
"Got empty crop data. You might need to increase detect_seconds."
|
||||
)
|
||||
end
|
||||
"Got empty crop data. You might need to increase detect_seconds."
|
||||
)
|
||||
end
|
||||
else
|
||||
mp.msg.error(
|
||||
"No crop data. Was the cropdetect filter successfully inserted?"
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
-- This script uses the lavfi idet filter to automatically insert the
|
||||
-- appropriate deinterlacing filter based on a short section of the
|
||||
-- currently playing video.
|
||||
--
|
||||
-- It registers the key-binding ctrl+d, which when pressed, inserts the filters
|
||||
-- ``vf=lavfi=idet,pullup,vf=lavfi=idet``. After 4 seconds, it removes these
|
||||
-- filters and decides whether the content is progressive, interlaced, or
|
||||
-- telecined and the interlacing field dominance.
|
||||
--
|
||||
-- Based on this information, it may set mpv's ``deinterlace`` property (which
|
||||
-- usually inserts the yadif filter), or insert the ``pullup`` filter if the
|
||||
-- content is telecined. It also sets mpv's ``field-dominance`` property.
|
||||
--
|
||||
-- OPTIONS:
|
||||
-- The default detection time may be overridden by adding
|
||||
--
|
||||
-- --script-opts=autodeint.detect_seconds=<number of seconds>
|
||||
--
|
||||
-- to mpv's arguments. This may be desirable to allow idet more
|
||||
-- time to collect data.
|
||||
--
|
||||
-- To see counts of the various types of frames for each detection phase,
|
||||
-- the verbosity can be increased with
|
||||
--
|
||||
-- --msg-level autodeint=v
|
||||
--
|
||||
-- This script requires a recent version of ffmpeg for which the idet
|
||||
-- filter adds the required metadata.
|
||||
|
||||
require "mp.msg"
|
||||
|
||||
script_name = mp.get_script_name()
|
||||
detect_label = string.format("%s-detect", script_name)
|
||||
pullup_label = string.format("%s", script_name)
|
||||
ivtc_detect_label = string.format("%s-ivtc-detect", script_name)
|
||||
|
||||
-- number of seconds to gather cropdetect data
|
||||
detect_seconds = tonumber(mp.get_opt(string.format("%s.detect_seconds", script_name)))
|
||||
if not detect_seconds then
|
||||
detect_seconds = 4
|
||||
end
|
||||
|
||||
function del_filter_if_present(label)
|
||||
-- necessary because mp.command('vf del @label:filter') raises an
|
||||
-- error if the filter doesn't exist
|
||||
local vfs = mp.get_property_native("vf")
|
||||
|
||||
for i,vf in pairs(vfs) do
|
||||
if vf["label"] == label then
|
||||
table.remove(vfs, i)
|
||||
mp.set_property_native("vf", vfs)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function start_detect()
|
||||
-- exit if detection is already in progress
|
||||
if timer then
|
||||
mp.msg.warn("already detecting!")
|
||||
return
|
||||
end
|
||||
|
||||
mp.set_property("deinterlace","no")
|
||||
del_filter_if_present(pullup_label)
|
||||
|
||||
-- insert the detection filter
|
||||
local cmd = string.format('vf add @%s:lavfi=graph="idet",@%s:pullup,@%s:lavfi=graph="idet"',
|
||||
detect_label, pullup_label, ivtc_detect_label)
|
||||
if not mp.command(cmd) then
|
||||
mp.msg.error("failed to insert detection filters")
|
||||
return
|
||||
end
|
||||
|
||||
-- wait to gather data
|
||||
timer = mp.add_timeout(detect_seconds, select_filter)
|
||||
end
|
||||
|
||||
function stop_detect()
|
||||
del_filter_if_present(detect_label)
|
||||
del_filter_if_present(ivtc_detect_label)
|
||||
timer = nil
|
||||
end
|
||||
|
||||
progressive, interlaced_tff, interlaced_bff, interlaced = 0, 1, 2, 3, 4
|
||||
|
||||
function judge(label)
|
||||
-- get the metadata
|
||||
local result = mp.get_property_native(string.format("vf-metadata/%s", label))
|
||||
num_tff = tonumber(result["lavfi.idet.multiple.tff"])
|
||||
num_bff = tonumber(result["lavfi.idet.multiple.bff"])
|
||||
num_progressive = tonumber(result["lavfi.idet.multiple.progressive"])
|
||||
num_undetermined = tonumber(result["lavfi.idet.multiple.undetermined"])
|
||||
num_interlaced = num_tff + num_bff
|
||||
num_determined = num_interlaced + num_progressive
|
||||
|
||||
mp.msg.verbose(label.." progressive = "..num_progressive)
|
||||
mp.msg.verbose(label.." interlaced-tff = "..num_tff)
|
||||
mp.msg.verbose(label.." interlaced-bff = "..num_bff)
|
||||
mp.msg.verbose(label.." undetermined = "..num_undetermined)
|
||||
|
||||
if num_determined < num_undetermined then
|
||||
mp.msg.warn("majority undetermined frames")
|
||||
end
|
||||
if num_progressive > 20*num_interlaced then
|
||||
return progressive
|
||||
elseif num_tff > 10*num_bff then
|
||||
return interlaced_tff
|
||||
elseif num_bff > 10*num_tff then
|
||||
return interlaced_bff
|
||||
else
|
||||
return interlaced
|
||||
end
|
||||
end
|
||||
|
||||
function select_filter()
|
||||
-- handle the first detection filter results
|
||||
verdict = judge(detect_label)
|
||||
if verdict == progressive then
|
||||
mp.msg.info("progressive: doing nothing")
|
||||
stop_detect()
|
||||
return
|
||||
elseif verdict == interlaced_tff then
|
||||
mp.set_property("field-dominance", "top")
|
||||
elseif verdict == interlaced_bff then
|
||||
mp.set_property("field-dominance", "bottom")
|
||||
elseif verdict == interlaced then
|
||||
mp.set_property("field-dominance", "auto")
|
||||
end
|
||||
|
||||
-- handle the ivtc detection filter results
|
||||
verdict = judge(ivtc_detect_label)
|
||||
if verdict == progressive then
|
||||
mp.msg.info(string.format("telecinied with %s field dominance: using pullup", mp.get_property("field-dominance")))
|
||||
stop_detect()
|
||||
else
|
||||
mp.msg.info(string.format("interlaced with %s field dominance: setting deinterlace property", mp.get_property("field-dominance")))
|
||||
del_filter_if_present(pullup_label)
|
||||
mp.set_property("deinterlace","yes")
|
||||
stop_detect()
|
||||
end
|
||||
end
|
||||
|
||||
mp.add_key_binding("ctrl+d", script_name, start_detect)
|
||||
+12
-86
@@ -4,26 +4,8 @@
|
||||
-- alphabetically, and adds entries before and after the current file to
|
||||
-- the internal playlist. (It stops if the it would add an already existing
|
||||
-- playlist entry at the same position - this makes it "stable".)
|
||||
-- Add at most 5000 * 2 files when starting a file (before + after).
|
||||
MAXENTRIES = 5000
|
||||
|
||||
local options = require 'mp.options'
|
||||
|
||||
o = {
|
||||
disabled = false
|
||||
}
|
||||
options.read_options(o)
|
||||
|
||||
function Set (t)
|
||||
local set = {}
|
||||
for _, v in pairs(t) do set[v] = true end
|
||||
return set
|
||||
end
|
||||
|
||||
EXTENSIONS = Set {
|
||||
'mkv', 'avi', 'mp4', 'ogv', 'webm', 'rmvb', 'flv', 'wmv', 'mpeg', 'mpg', 'm4v', '3gp',
|
||||
'mp3', 'wav', 'ogv', 'flac', 'm4a', 'wma',
|
||||
}
|
||||
-- Add at most 5 * 2 files when starting a file (before + after).
|
||||
MAXENTRIES = 5
|
||||
|
||||
mputils = require 'mp.utils'
|
||||
|
||||
@@ -32,69 +14,18 @@ function add_files_at(index, files)
|
||||
local oldcount = mp.get_property_number("playlist-count", 1)
|
||||
for i = 1, #files do
|
||||
mp.commandv("loadfile", files[i], "append")
|
||||
mp.commandv("playlist-move", oldcount + i - 1, index + i - 1)
|
||||
end
|
||||
end
|
||||
|
||||
function get_extension(path)
|
||||
match = string.match(path, "%.([^%.]+)$" )
|
||||
if match == nil then
|
||||
return "nomatch"
|
||||
else
|
||||
return match
|
||||
end
|
||||
end
|
||||
|
||||
table.filter = function(t, iter)
|
||||
for i = #t, 1, -1 do
|
||||
if not iter(t[i]) then
|
||||
table.remove(t, i)
|
||||
end
|
||||
mp.commandv("playlist_move", oldcount + i - 1, index + i - 1)
|
||||
end
|
||||
end
|
||||
|
||||
function find_and_add_entries()
|
||||
local path = mp.get_property("path", "")
|
||||
local dir, filename = mputils.split_path(path)
|
||||
if o.disabled or #dir == 0 then
|
||||
if #dir == 0 then
|
||||
return
|
||||
end
|
||||
local pl_count = mp.get_property_number("playlist-count", 1)
|
||||
if (pl_count > 1 and autoload == nil) or
|
||||
(pl_count == 1 and EXTENSIONS[string.lower(get_extension(filename))] == nil) then
|
||||
return
|
||||
else
|
||||
autoload = true
|
||||
end
|
||||
|
||||
local files = mputils.readdir(dir, "files")
|
||||
if files == nil then
|
||||
return
|
||||
end
|
||||
table.filter(files, function (v, k)
|
||||
if string.match(v, "^%.") then
|
||||
return false
|
||||
end
|
||||
local ext = get_extension(v)
|
||||
if ext == nil then
|
||||
return false
|
||||
end
|
||||
return EXTENSIONS[string.lower(ext)]
|
||||
end)
|
||||
table.sort(files, function (a, b)
|
||||
local len = string.len(a) - string.len(b)
|
||||
if len ~= 0 then -- case for ordering filename ending with such as X.Y.Z
|
||||
local ext = string.len(get_extension(a)) + 1
|
||||
a = string.sub(a, 1, -ext)
|
||||
b = string.sub(b, 1, -ext)
|
||||
end
|
||||
return string.lower(a) < string.lower(b)
|
||||
end)
|
||||
|
||||
if dir == "." then
|
||||
dir = ""
|
||||
end
|
||||
|
||||
table.sort(files)
|
||||
local pl = mp.get_property_native("playlist", {})
|
||||
local pl_current = mp.get_property_number("playlist-pos", 0) + 1
|
||||
-- Find the current pl entry (dir+"/"+filename) in the sorted dir list
|
||||
@@ -108,36 +39,31 @@ function find_and_add_entries()
|
||||
if current == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local append = {[-1] = {}, [1] = {}}
|
||||
for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1
|
||||
for dir = -1, 1, 2 do -- 2 iterations, with dir = -1 and +1
|
||||
for i = 1, MAXENTRIES do
|
||||
local file = files[current + i * direction]
|
||||
local pl_e = pl[pl_current + i * direction]
|
||||
local file = files[current + i * dir]
|
||||
local pl_e = pl[pl_current + i * dir]
|
||||
if file == nil or file[1] == "." then
|
||||
break
|
||||
end
|
||||
|
||||
local filepath = dir .. file
|
||||
if pl_e then
|
||||
-- If there's a playlist entry, and it's the same file, stop.
|
||||
if pl_e.filename == filepath then
|
||||
if pl_e.filename == file then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if direction == -1 then
|
||||
if dir == -1 then
|
||||
if pl_current == 1 then -- never add additional entries in the middle
|
||||
mp.msg.info("Prepending " .. file)
|
||||
table.insert(append[-1], 1, filepath)
|
||||
table.insert(append[-1], 1, file)
|
||||
end
|
||||
else
|
||||
mp.msg.info("Adding " .. file)
|
||||
table.insert(append[1], filepath)
|
||||
table.insert(append[1], file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
add_files_at(pl_current + 1, append[1])
|
||||
add_files_at(pl_current, append[-1])
|
||||
end
|
||||
|
||||
@@ -20,9 +20,9 @@ pullup_label = string.format("%s-pullup", script_name)
|
||||
|
||||
function pullup_on()
|
||||
for i,vf in pairs(mp.get_property_native('vf')) do
|
||||
if vf['label'] == pullup_label then
|
||||
return "yes"
|
||||
end
|
||||
if vf['label'] == pullup_label then
|
||||
return "yes"
|
||||
end
|
||||
end
|
||||
return "no"
|
||||
end
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
-- This script enables live control of the dynamic range compression
|
||||
-- (drc) audio filter while the video is playing back. This can be
|
||||
-- useful to avoid having to stop and restart mpv to adjust filter
|
||||
-- parameters. See the entry for "drc" under the "AUDIO FILTERS"
|
||||
-- section of the man page for a complete description of the filter.
|
||||
--
|
||||
-- This script registers the key-binding "\" to toggle the filter between
|
||||
--
|
||||
-- * off
|
||||
-- * method=1 (single-sample smoothing)
|
||||
-- * method=2 (multi-sample smoothing)
|
||||
--
|
||||
-- It registers the keybindings ctrl+9/ctrl+0 to decrease/increase the
|
||||
-- target ampltiude. These keys will insert the filter at the default
|
||||
-- target amplitude of 0.25 if it was not previously present.
|
||||
--
|
||||
-- OSD feedback of the current filter state is displayed on pressing
|
||||
-- each bound key.
|
||||
|
||||
script_name = mp.get_script_name()
|
||||
|
||||
function print_state(params)
|
||||
if params then
|
||||
mp.osd_message(script_name..":\n"
|
||||
.."method = "..params["method"].."\n"
|
||||
.."target = "..params["target"])
|
||||
else
|
||||
mp.osd_message(script_name..":\noff")
|
||||
end
|
||||
end
|
||||
|
||||
function get_index_of_drc(afs)
|
||||
for i,af in pairs(afs) do
|
||||
if af["label"] == script_name then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function append_drc(afs)
|
||||
afs[#afs+1] = {
|
||||
name = "drc",
|
||||
label = script_name,
|
||||
params = {
|
||||
method = "1",
|
||||
target = "0.25"
|
||||
}
|
||||
}
|
||||
print_state(afs[#afs]["params"])
|
||||
end
|
||||
|
||||
function modify_or_create_af(fun)
|
||||
afs = mp.get_property_native("af")
|
||||
i = get_index_of_drc(afs)
|
||||
if not i then
|
||||
append_drc(afs)
|
||||
else
|
||||
fun(afs, i)
|
||||
end
|
||||
mp.set_property_native("af", afs)
|
||||
end
|
||||
|
||||
function drc_toggle_method_handler()
|
||||
modify_or_create_af(
|
||||
function (afs, i)
|
||||
new_method=(afs[i]["params"]["method"]+1)%3
|
||||
if new_method == 0 then
|
||||
table.remove(afs, i)
|
||||
print_state(nil)
|
||||
else
|
||||
afs[i]["params"]["method"] = tostring((afs[i]["params"]["method"])%2+1)
|
||||
print_state(afs[i]["params"])
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
function drc_scale_target(factor)
|
||||
modify_or_create_af(
|
||||
function (afs)
|
||||
afs[i]["params"]["target"] = tostring(afs[i]["params"]["target"]*factor)
|
||||
print_state(afs[i]["params"])
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
function drc_louder_handler()
|
||||
drc_scale_target(2.0)
|
||||
end
|
||||
|
||||
function drc_quieter_handler()
|
||||
drc_scale_target(0.5)
|
||||
end
|
||||
|
||||
-- toggle between off, method 1 and method 2
|
||||
mp.add_key_binding("\\", "drc_toggle_method", drc_toggle_method_handler)
|
||||
-- increase or decrease target volume
|
||||
mp.add_key_binding("ctrl+9", "drc_quieter", drc_quieter_handler)
|
||||
mp.add_key_binding("ctrl+0", "drc_louder", drc_louder_handler)
|
||||
+10
-16
@@ -1,22 +1,16 @@
|
||||
-- Test script for property change notification mechanism.
|
||||
-- Note that watching/reading some properties can be very expensive, or
|
||||
-- require the player to synchronously wait on network (when playing
|
||||
-- remote files), so you should in general only watch properties you
|
||||
-- are interested in.
|
||||
|
||||
local utils = require("mp.utils")
|
||||
|
||||
function observe(name)
|
||||
mp.observe_property(name, "native", function(name, val)
|
||||
print("property '" .. name .. "' changed to '" ..
|
||||
utils.to_string(val) .. "'")
|
||||
end)
|
||||
function format_property_val(v)
|
||||
if type(v) == "table" then
|
||||
return mp.format_table(v) -- undocumented function; might be removed
|
||||
else
|
||||
return tostring(v)
|
||||
end
|
||||
end
|
||||
|
||||
for i,name in ipairs(mp.get_property_native("property-list")) do
|
||||
observe(name)
|
||||
end
|
||||
|
||||
for i,name in ipairs(mp.get_property_native("options")) do
|
||||
observe("options/" .. name)
|
||||
mp.observe_property(name, "native", function(name, val)
|
||||
print("property '" .. name .. "' changed to '" ..
|
||||
format_property_val(val) .. "'")
|
||||
end)
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
--makes mpv disable ontop when pausing and re-enable it again when resuming playback
|
||||
--please note that this won't do anything if ontop was not enabled before pausing
|
||||
|
||||
local was_ontop = false
|
||||
|
||||
mp.observe_property("pause", "bool", function(name, value)
|
||||
local ontop = mp.get_property_native("ontop")
|
||||
if value then
|
||||
if ontop then
|
||||
mp.set_property_native("ontop", false)
|
||||
was_ontop = true
|
||||
end
|
||||
else
|
||||
if was_ontop and not ontop then
|
||||
mp.set_property_native("ontop", true)
|
||||
end
|
||||
was_ontop = false
|
||||
end
|
||||
end)
|
||||
@@ -1,20 +0,0 @@
|
||||
-- This script pauses playback when minimizing the window, and resumes playback
|
||||
-- if it's brought back again. If the player was already paused when minimizing,
|
||||
-- then try not to mess with the pause state.
|
||||
|
||||
local did_minimize = false
|
||||
|
||||
mp.observe_property("window-minimized", "bool", function(name, value)
|
||||
local pause = mp.get_property_native("pause")
|
||||
if value == true then
|
||||
if pause == false then
|
||||
mp.set_property_native("pause", true)
|
||||
did_minimize = true
|
||||
end
|
||||
elseif value == false then
|
||||
if did_minimize and (pause == true) then
|
||||
mp.set_property_native("pause", false)
|
||||
end
|
||||
did_minimize = false
|
||||
end
|
||||
end)
|
||||
@@ -1,7 +1,5 @@
|
||||
-- Rebuild the terminal status line as a lua script
|
||||
-- Be aware that this will require more cpu power!
|
||||
-- Also, this is based on a rather old version of the
|
||||
-- builtin mpv status line.
|
||||
|
||||
-- Add a string to the status line
|
||||
function atsl(s)
|
||||
@@ -30,7 +28,7 @@ function update_status_line()
|
||||
atsl(mp.get_property_osd("time-pos"))
|
||||
|
||||
atsl(" / ");
|
||||
atsl(mp.get_property_osd("duration"));
|
||||
atsl(mp.get_property_osd("length"));
|
||||
|
||||
atsl(" (")
|
||||
atsl(mp.get_property_osd("percent-pos", -1))
|
||||
|
||||
Executable
+169
@@ -0,0 +1,169 @@
|
||||
#! /usr/bin/env perl
|
||||
|
||||
# Generate C definitions for parsing Matroska files.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/lib";
|
||||
use Parse::Matroska::Definitions;
|
||||
use Parse::Matroska::Reader;
|
||||
|
||||
use Getopt::Long;
|
||||
use List::Util qw{max};
|
||||
|
||||
my @global_elem_list = @Parse::Matroska::Definitions::global_elem_list;
|
||||
|
||||
Getopt::Long::Configure(qw{auto_version auto_help});
|
||||
my %opt;
|
||||
GetOptions(\%opt,
|
||||
"generate-header",
|
||||
"generate-definitions",
|
||||
"full",
|
||||
);
|
||||
|
||||
if ($opt{"generate-header"}) {
|
||||
generate_c_header();
|
||||
} elsif ($opt{"generate-definitions"}) {
|
||||
generate_c_definitions();
|
||||
} else {
|
||||
for (@ARGV) {
|
||||
my $reader = Parse::Matroska::Reader->new($_ eq '-' ? \*STDIN : $_) or die $!;
|
||||
while (my $elem = $reader->read_element($_ eq '-')) {
|
||||
process_elem($elem, $_ eq '-');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Generate declarations for libmpdemux/ebml_types.h
|
||||
sub generate_c_header {
|
||||
print "/* Generated by TOOLS/matroska.pl, do not edit manually */\n\n";
|
||||
|
||||
# Write a #define for the ElementID of each known element
|
||||
for my $el (@global_elem_list) {
|
||||
printf "#define %-40s 0x%s\n", $el->{definename}, $el->{elid};
|
||||
}
|
||||
print "\n";
|
||||
|
||||
# Define a struct for each ElementID that has child elements
|
||||
for my $el (@global_elem_list) {
|
||||
next unless $el->{subelements};
|
||||
print "\nstruct $el->{structname} {\n";
|
||||
|
||||
# Figure out the length of the longest variable name
|
||||
# Used for pretty-printing in the next step
|
||||
my $l = max(map { length $_->{valname} } values %{$el->{subelements}});
|
||||
|
||||
# Output each variable, with pointers for array (multiple) elements
|
||||
for my $subel (sort { $a->{definename} cmp $b->{definename} } values %{$el->{subelements}}) {
|
||||
printf " %-${l}s %s%s;\n",
|
||||
$subel->{valname}, $subel->{multiple}?'*':' ', $subel->{fieldname};
|
||||
}
|
||||
print "\n";
|
||||
|
||||
# Output a counter variable for each element
|
||||
# (presence/absence for scalars, item count for arrays)
|
||||
for my $subel (values %{$el->{subelements}}) {
|
||||
print " int n_$subel->{fieldname};\n"
|
||||
}
|
||||
print "};\n";
|
||||
}
|
||||
print "\n";
|
||||
|
||||
# Output extern references for ebml_elem_desc structs for each of the elements
|
||||
# These are defined by generate_c_definitions
|
||||
for my $el (@global_elem_list) {
|
||||
next unless $el->{subelements};
|
||||
print "extern const struct ebml_elem_desc $el->{structname}_desc;\n";
|
||||
}
|
||||
print "\n";
|
||||
|
||||
# Output the max number of sub-elements a known element might have
|
||||
printf "#define MAX_EBML_SUBELEMENTS %d\n",
|
||||
max(map { scalar keys %{$_->{subelements}} }
|
||||
grep { $_->{subelements} } @global_elem_list);
|
||||
}
|
||||
|
||||
# Generate definitions for libmpdemux/ebml_defs.c
|
||||
sub generate_c_definitions {
|
||||
print "/* Generated by TOOLS/matroska.pl, do not edit manually */\n\n";
|
||||
# ebml_defs.c uses macros declared in ebml.c
|
||||
for my $el (@global_elem_list) {
|
||||
print "\n";
|
||||
if ($el->{subelements}) {
|
||||
# set N for the next macros
|
||||
print "#define N $el->{fieldname}\n";
|
||||
|
||||
# define a struct ebml_$N_desc and gets ready to define fields
|
||||
# this secretly opens two scopes; hence the }}; at the end
|
||||
print "E_S(\"$el->{name}\", ".scalar(keys %{$el->{subelements}}).")\n";
|
||||
|
||||
# define a field for each subelement
|
||||
# also does lots of macro magic, but doesn't open a scope
|
||||
for my $subel (sort { $a->{definename} cmp $b->{definename} } values %{$el->{subelements}}) {
|
||||
print "F($subel->{definename}, $subel->{fieldname}, ".
|
||||
($subel->{multiple}?'1':'0').")\n";
|
||||
}
|
||||
# close the struct
|
||||
print "}};\n";
|
||||
|
||||
# unset N since we've used it
|
||||
print "#undef N\n";
|
||||
} else {
|
||||
print "E(\"$el->{name}\", $el->{fieldname}, $el->{ebmltype})\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub repr {
|
||||
my @ret;
|
||||
foreach (@_) {
|
||||
if (/'/) {
|
||||
s/"/\\"/g;
|
||||
push @ret, "\"$_\"";
|
||||
} else {
|
||||
push @ret, "'$_'";
|
||||
}
|
||||
}
|
||||
return @ret if wantarray;
|
||||
return pop @ret if defined wantarray;
|
||||
return;
|
||||
}
|
||||
|
||||
sub process_elem {
|
||||
my ($elem, $read_bin) = @_;
|
||||
unless ($opt{full}) {
|
||||
if ($elem->{name} eq 'Cluster' || $elem->{name} eq 'Cues') {
|
||||
$elem->skip;
|
||||
return;
|
||||
}
|
||||
}
|
||||
die unless $elem;
|
||||
|
||||
if ($elem->{type} ne 'skip') {
|
||||
print "$elem->{depth} $elem->{elid} $elem->{name} size: $elem->{content_len} value: ";
|
||||
}
|
||||
|
||||
if ($elem->{type} eq 'sub') {
|
||||
print "subelements:\n";
|
||||
while (my $chld = $elem->next_child($read_bin)) {
|
||||
process_elem($chld);
|
||||
}
|
||||
} elsif ($elem->{type} eq 'binary') {
|
||||
my $t = "<skipped $elem->{content_len} bytes>";
|
||||
if ($elem->{content_len} < 20) {
|
||||
$t = unpack "H*", $elem->get_value;
|
||||
}
|
||||
print "binary $t\n";
|
||||
delete $elem->{value};
|
||||
} elsif ($elem->{type} eq 'ebml_id') {
|
||||
print "binary $elem->{value}->{elid} (".($elem->{value}->{name}||"UNKNOWN").")\n";
|
||||
} elsif ($elem->{type} eq 'skip') {
|
||||
# skip
|
||||
} elsif ($elem->{type} eq 'str') {
|
||||
print "string ". repr($elem->get_value) . "\n";
|
||||
} else {
|
||||
print "$elem->{type} ". $elem->get_value ."\n";
|
||||
}
|
||||
}
|
||||
@@ -1,470 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate C definitions for parsing Matroska files.
|
||||
Can also be used to directly parse Matroska files and display their contents.
|
||||
"""
|
||||
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# for compatibility with Python 2.x
|
||||
from __future__ import print_function
|
||||
|
||||
elements_ebml = (
|
||||
'EBML, 1a45dfa3, sub', (
|
||||
'EBMLVersion, 4286, uint',
|
||||
'EBMLReadVersion, 42f7, uint',
|
||||
'EBMLMaxIDLength, 42f2, uint',
|
||||
'EBMLMaxSizeLength, 42f3, uint',
|
||||
'DocType, 4282, str',
|
||||
'DocTypeVersion, 4287, uint',
|
||||
'DocTypeReadVersion, 4285, uint',
|
||||
),
|
||||
|
||||
'CRC32, bf, binary',
|
||||
'Void, ec, binary',
|
||||
)
|
||||
|
||||
elements_matroska = (
|
||||
'Segment, 18538067, sub', (
|
||||
|
||||
'SeekHead*, 114d9b74, sub', (
|
||||
'Seek*, 4dbb, sub', (
|
||||
'SeekID, 53ab, ebml_id',
|
||||
'SeekPosition, 53ac, uint',
|
||||
),
|
||||
),
|
||||
|
||||
'Info*, 1549a966, sub', (
|
||||
'SegmentUID, 73a4, binary',
|
||||
'PrevUID, 3cb923, binary',
|
||||
'NextUID, 3eb923, binary',
|
||||
'TimecodeScale, 2ad7b1, uint',
|
||||
'DateUTC, 4461, sint',
|
||||
'Title, 7ba9, str',
|
||||
'MuxingApp, 4d80, str',
|
||||
'WritingApp, 5741, str',
|
||||
'Duration, 4489, float',
|
||||
),
|
||||
|
||||
'Cluster*, 1f43b675, sub', (
|
||||
'Timecode, e7, uint',
|
||||
'BlockGroup*, a0, sub', (
|
||||
'Block, a1, binary',
|
||||
'BlockDuration, 9b, uint',
|
||||
'ReferenceBlock*, fb, sint',
|
||||
'DiscardPadding, 75A2, sint',
|
||||
'BlockAdditions, 75A1, sub', (
|
||||
'BlockMore*, A6, sub', (
|
||||
'BlockAddID, EE, uint',
|
||||
'BlockAdditional, A5, binary',
|
||||
),
|
||||
),
|
||||
),
|
||||
'SimpleBlock*, a3, binary',
|
||||
),
|
||||
|
||||
'Tracks*, 1654ae6b, sub', (
|
||||
'TrackEntry*, ae, sub', (
|
||||
'TrackNumber, d7, uint',
|
||||
'TrackUID, 73c5, uint',
|
||||
'TrackType, 83, uint',
|
||||
'FlagEnabled, b9, uint',
|
||||
'FlagDefault, 88, uint',
|
||||
'FlagForced, 55aa, uint',
|
||||
'FlagLacing, 9c, uint',
|
||||
'MinCache, 6de7, uint',
|
||||
'MaxCache, 6df8, uint',
|
||||
'DefaultDuration, 23e383, uint',
|
||||
'TrackTimecodeScale, 23314f, float',
|
||||
'MaxBlockAdditionID, 55ee, uint',
|
||||
'Name, 536e, str',
|
||||
'Language, 22b59c, str',
|
||||
'CodecID, 86, str',
|
||||
'CodecPrivate, 63a2, binary',
|
||||
'CodecName, 258688, str',
|
||||
'CodecDecodeAll, aa, uint',
|
||||
'CodecDelay, 56aa, uint',
|
||||
'SeekPreRoll, 56bb, uint',
|
||||
'Video, e0, sub', (
|
||||
'FlagInterlaced, 9a, uint',
|
||||
'PixelWidth, b0, uint',
|
||||
'PixelHeight, ba, uint',
|
||||
'DisplayWidth, 54b0, uint',
|
||||
'DisplayHeight, 54ba, uint',
|
||||
'DisplayUnit, 54b2, uint',
|
||||
'FrameRate, 2383e3, float',
|
||||
'ColourSpace, 2eb524, binary',
|
||||
'StereoMode, 53b8, uint',
|
||||
'Colour, 55b0, sub', (
|
||||
'MatrixCoefficients, 55B1, uint',
|
||||
'BitsPerChannel, 55B2, uint',
|
||||
'ChromaSubsamplingHorz, 55B3, uint',
|
||||
'ChromaSubsamplingVert, 55B4, uint',
|
||||
'CbSubsamplingHorz, 55B5, uint',
|
||||
'CbSubsamplingVert, 55B6, uint',
|
||||
'ChromaSitingHorz, 55B7, uint',
|
||||
'ChromaSitingVert, 55B8, uint',
|
||||
'Range, 55B9, uint',
|
||||
'TransferCharacteristics, 55BA, uint',
|
||||
'Primaries, 55BB, uint',
|
||||
'MaxCLL, 55BC, uint',
|
||||
'MaxFALL, 55BD, uint',
|
||||
'MasteringMetadata, 55D0, sub', (
|
||||
'PrimaryRChromaticityX, 55D1, float',
|
||||
'PrimaryRChromaticityY, 55D2, float',
|
||||
'PrimaryGChromaticityX, 55D3, float',
|
||||
'PrimaryGChromaticityY, 55D4, float',
|
||||
'PrimaryBChromaticityX, 55D5, float',
|
||||
'PrimaryBChromaticityY, 55D6, float',
|
||||
'WhitePointChromaticityX, 55D7, float',
|
||||
'WhitePointChromaticityY, 55D8, float',
|
||||
'LuminanceMax, 55D9, float',
|
||||
'LuminanceMin, 55DA, float',
|
||||
),
|
||||
),
|
||||
),
|
||||
'Audio, e1, sub', (
|
||||
'SamplingFrequency, b5, float',
|
||||
'OutputSamplingFrequency, 78b5, float',
|
||||
'Channels, 9f, uint',
|
||||
'BitDepth, 6264, uint',
|
||||
),
|
||||
'ContentEncodings, 6d80, sub', (
|
||||
'ContentEncoding*, 6240, sub', (
|
||||
'ContentEncodingOrder, 5031, uint',
|
||||
'ContentEncodingScope, 5032, uint',
|
||||
'ContentEncodingType, 5033, uint',
|
||||
'ContentCompression, 5034, sub', (
|
||||
'ContentCompAlgo, 4254, uint',
|
||||
'ContentCompSettings, 4255, binary',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
'Cues, 1c53bb6b, sub', (
|
||||
'CuePoint*, bb, sub', (
|
||||
'CueTime, b3, uint',
|
||||
'CueTrackPositions*, b7, sub', (
|
||||
'CueTrack, f7, uint',
|
||||
'CueClusterPosition, f1, uint',
|
||||
'CueRelativePosition, f0, uint',
|
||||
'CueDuration, b2, uint',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
'Attachments, 1941a469, sub', (
|
||||
'AttachedFile*, 61a7, sub', (
|
||||
'FileDescription, 467e, str',
|
||||
'FileName, 466e, str',
|
||||
'FileMimeType, 4660, str',
|
||||
'FileData, 465c, binary',
|
||||
'FileUID, 46ae, uint',
|
||||
),
|
||||
),
|
||||
|
||||
'Chapters, 1043a770, sub', (
|
||||
'EditionEntry*, 45b9, sub', (
|
||||
'EditionUID, 45bc, uint',
|
||||
'EditionFlagHidden, 45bd, uint',
|
||||
'EditionFlagDefault, 45db, uint',
|
||||
'EditionFlagOrdered, 45dd, uint',
|
||||
'ChapterAtom*, b6, sub', (
|
||||
'ChapterUID, 73c4, uint',
|
||||
'ChapterTimeStart, 91, uint',
|
||||
'ChapterTimeEnd, 92, uint',
|
||||
'ChapterFlagHidden, 98, uint',
|
||||
'ChapterFlagEnabled, 4598, uint',
|
||||
'ChapterSegmentUID, 6e67, binary',
|
||||
'ChapterSegmentEditionUID, 6ebc, uint',
|
||||
'ChapterDisplay*, 80, sub', (
|
||||
'ChapString, 85, str',
|
||||
'ChapLanguage*, 437c, str',
|
||||
'ChapCountry*, 437e, str',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'Tags*, 1254c367, sub', (
|
||||
'Tag*, 7373, sub', (
|
||||
'Targets, 63c0, sub', (
|
||||
'TargetTypeValue, 68ca, uint',
|
||||
'TargetTrackUID, 63c5, uint',
|
||||
'TargetEditionUID, 63c9, uint',
|
||||
'TargetChapterUID, 63c4, uint',
|
||||
'TargetAttachmentUID, 63c6, uint',
|
||||
),
|
||||
'SimpleTag*, 67c8, sub', (
|
||||
'TagName, 45a3, str',
|
||||
'TagLanguage, 447a, str',
|
||||
'TagString, 4487, str'
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
import sys
|
||||
from math import ldexp
|
||||
from binascii import hexlify
|
||||
|
||||
def byte2num(s):
|
||||
return int(hexlify(s), 16)
|
||||
|
||||
class EOF(Exception): pass
|
||||
|
||||
def camelcase_to_words(name):
|
||||
parts = []
|
||||
start = 0
|
||||
for i in range(1, len(name)):
|
||||
if name[i].isupper() and (name[i-1].islower() or
|
||||
name[i+1:i+2].islower()):
|
||||
parts.append(name[start:i])
|
||||
start = i
|
||||
parts.append(name[start:])
|
||||
return '_'.join(parts).lower()
|
||||
|
||||
class MatroskaElement(object):
|
||||
|
||||
def __init__(self, name, elid, valtype, namespace):
|
||||
self.name = name
|
||||
self.definename = '{0}_ID_{1}'.format(namespace, name.upper())
|
||||
self.fieldname = camelcase_to_words(name)
|
||||
self.structname = 'ebml_' + self.fieldname
|
||||
self.elid = elid
|
||||
self.valtype = valtype
|
||||
if valtype == 'sub':
|
||||
self.ebmltype = 'EBML_TYPE_SUBELEMENTS'
|
||||
self.valname = 'struct ' + self.structname
|
||||
else:
|
||||
self.ebmltype = 'EBML_TYPE_' + valtype.upper()
|
||||
try:
|
||||
self.valname = {'uint': 'uint64_t', 'str': 'char *',
|
||||
'binary': 'bstr', 'ebml_id': 'uint32_t',
|
||||
'float': 'double', 'sint': 'int64_t',
|
||||
}[valtype]
|
||||
except KeyError:
|
||||
raise SyntaxError('Unrecognized value type ' + valtype)
|
||||
self.subelements = ()
|
||||
|
||||
def add_subelements(self, subelements):
|
||||
self.subelements = subelements
|
||||
self.subids = set(x[0].elid for x in subelements)
|
||||
|
||||
elementd = {}
|
||||
elementlist = []
|
||||
def parse_elems(l, namespace):
|
||||
subelements = []
|
||||
for el in l:
|
||||
if isinstance(el, str):
|
||||
name, hexid, eltype = [x.strip() for x in el.split(',')]
|
||||
hexid = hexid.lower()
|
||||
multiple = name.endswith('*')
|
||||
name = name.strip('*')
|
||||
new = MatroskaElement(name, hexid, eltype, namespace)
|
||||
elementd[hexid] = new
|
||||
elementlist.append(new)
|
||||
subelements.append((new, multiple))
|
||||
else:
|
||||
new.add_subelements(parse_elems(el, namespace))
|
||||
return subelements
|
||||
|
||||
parse_elems(elements_ebml, 'EBML')
|
||||
parse_elems(elements_matroska, 'MATROSKA')
|
||||
|
||||
def printf(out, *args):
|
||||
out.write(u' '.join([str(x) for x in args]))
|
||||
out.write(u'\n')
|
||||
|
||||
def generate_C_header(out):
|
||||
printf(out, '// Generated by TOOLS/matroska.py, do not edit manually')
|
||||
printf(out)
|
||||
|
||||
for el in elementlist:
|
||||
printf(out, '#define {0.definename:40} 0x{0.elid}'.format(el))
|
||||
|
||||
printf(out)
|
||||
|
||||
for el in reversed(elementlist):
|
||||
if not el.subelements:
|
||||
continue
|
||||
printf(out)
|
||||
printf(out, 'struct {0.structname} {{'.format(el))
|
||||
l = max(len(subel.valname) for subel, multiple in el.subelements)+1
|
||||
for subel, multiple in el.subelements:
|
||||
printf(out, ' {e.valname:{l}} {star}{e.fieldname};'.format(
|
||||
e=subel, l=l, star=' *'[multiple]))
|
||||
printf(out)
|
||||
for subel, multiple in el.subelements:
|
||||
printf(out, ' int n_{0.fieldname};'.format(subel))
|
||||
printf(out, '};')
|
||||
|
||||
for el in elementlist:
|
||||
if not el.subelements:
|
||||
continue
|
||||
printf(out, 'extern const struct ebml_elem_desc {0.structname}_desc;'.format(el))
|
||||
|
||||
printf(out)
|
||||
printf(out, '#define MAX_EBML_SUBELEMENTS', max(len(el.subelements)
|
||||
for el in elementlist))
|
||||
|
||||
|
||||
def generate_C_definitions(out):
|
||||
printf(out, '// Generated by TOOLS/matroska.py, do not edit manually')
|
||||
printf(out)
|
||||
for el in reversed(elementlist):
|
||||
printf(out)
|
||||
if el.subelements:
|
||||
printf(out, '#define N', el.fieldname)
|
||||
printf(out, 'E_S("{0}", {1})'.format(el.name, len(el.subelements)))
|
||||
for subel, multiple in el.subelements:
|
||||
printf(out, 'F({0.definename}, {0.fieldname}, {1})'.format(
|
||||
subel, int(multiple)))
|
||||
printf(out, '}};')
|
||||
printf(out, '#undef N')
|
||||
else:
|
||||
printf(out, 'E("{0.name}", {0.fieldname}, {0.ebmltype})'.format(el))
|
||||
|
||||
def read(s, length):
|
||||
t = s.read(length)
|
||||
if len(t) != length:
|
||||
raise EOF
|
||||
return t
|
||||
|
||||
def read_id(s):
|
||||
t = read(s, 1)
|
||||
i = 0
|
||||
mask = 128
|
||||
if ord(t) == 0:
|
||||
raise SyntaxError
|
||||
while not ord(t) & mask:
|
||||
i += 1
|
||||
mask >>= 1
|
||||
t += read(s, i)
|
||||
return t
|
||||
|
||||
def read_vint(s):
|
||||
t = read(s, 1)
|
||||
i = 0
|
||||
mask = 128
|
||||
if ord(t) == 0:
|
||||
raise SyntaxError
|
||||
while not ord(t) & mask:
|
||||
i += 1
|
||||
mask >>= 1
|
||||
t = bytes((ord(t) & (mask - 1),))
|
||||
t += read(s, i)
|
||||
return i+1, byte2num(t)
|
||||
|
||||
def read_str(s, length):
|
||||
return read(s, length)
|
||||
|
||||
def read_uint(s, length):
|
||||
t = read(s, length)
|
||||
return byte2num(t)
|
||||
|
||||
def read_sint(s, length):
|
||||
i = read_uint(s, length)
|
||||
mask = 1 << (length * 8 - 1)
|
||||
if i & mask:
|
||||
i -= 2 * mask
|
||||
return i
|
||||
|
||||
def read_float(s, length):
|
||||
t = read(s, length)
|
||||
i = byte2num(t)
|
||||
if length == 4:
|
||||
f = ldexp((i & 0x7fffff) + (1 << 23), (i >> 23 & 0xff) - 150)
|
||||
if i & (1 << 31):
|
||||
f = -f
|
||||
elif length == 8:
|
||||
f = ldexp((i & ((1 << 52) - 1)) + (1 << 52), (i >> 52 & 0x7ff) - 1075)
|
||||
if i & (1 << 63):
|
||||
f = -f
|
||||
else:
|
||||
raise SyntaxError
|
||||
return f
|
||||
|
||||
def parse_one(s, depth, parent, maxlen):
|
||||
elid = hexlify(read_id(s)).decode('ascii')
|
||||
elem = elementd.get(elid)
|
||||
size, length = read_vint(s)
|
||||
this_length = len(elid) / 2 + size + length
|
||||
if elem is not None:
|
||||
if elem.valtype != 'skip':
|
||||
print(" " * depth, '[' + elid + ']', elem.name, 'size:', length, 'value:', end=' ')
|
||||
if elem.valtype == 'sub':
|
||||
print('subelements:')
|
||||
while length > 0:
|
||||
length -= parse_one(s, depth + 1, elem, length)
|
||||
if length < 0:
|
||||
raise SyntaxError
|
||||
elif elem.valtype == 'str':
|
||||
print('string', repr(read_str(s, length).decode('utf8', 'replace')))
|
||||
elif elem.valtype in ('binary', 'ebml_id'):
|
||||
t = read_str(s, length)
|
||||
dec = ''
|
||||
if elem.valtype == 'ebml_id':
|
||||
idelem = elementd.get(hexlify(t).decode('ascii'))
|
||||
if idelem is None:
|
||||
dec = '(UNKNOWN)'
|
||||
else:
|
||||
dec = '({0.name})'.format(idelem)
|
||||
if len(t) < 20:
|
||||
t = hexlify(t).decode('ascii')
|
||||
else:
|
||||
t = '<{0} bytes>'.format(len(t))
|
||||
print('binary', t, dec)
|
||||
elif elem.valtype == 'uint':
|
||||
print('uint', read_uint(s, length))
|
||||
elif elem.valtype == 'sint':
|
||||
print('sint', read_sint(s, length))
|
||||
elif elem.valtype == 'float':
|
||||
print('float', read_float(s, length))
|
||||
elif elem.valtype == 'skip':
|
||||
read(s, length)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
else:
|
||||
print(" " * depth, '[' + elid + '] Unknown element! size:', length)
|
||||
read(s, length)
|
||||
return this_length
|
||||
|
||||
if __name__ == "__main__":
|
||||
def parse_toplevel(s):
|
||||
parse_one(s, 0, None, 1 << 63)
|
||||
|
||||
if sys.argv[1] == '--generate-header':
|
||||
generate_C_header(sys.stdout)
|
||||
elif sys.argv[1] == '--generate-definitions':
|
||||
generate_C_definitions(sys.stdout)
|
||||
else:
|
||||
if sys.version_info.major < 3:
|
||||
raise Exception("Dumping requires Python 3.")
|
||||
s = open(sys.argv[1], "rb")
|
||||
while 1:
|
||||
start = s.tell()
|
||||
try:
|
||||
parse_toplevel(s)
|
||||
except EOF:
|
||||
if s.tell() != start:
|
||||
raise Exception("Unexpected end of file")
|
||||
break
|
||||
@@ -1,6 +0,0 @@
|
||||
StartChar: .notdef
|
||||
Encoding: 65536 -1 0
|
||||
Width: 400
|
||||
Flags: W
|
||||
LayerCount: 2
|
||||
EndChar
|
||||
@@ -1,77 +0,0 @@
|
||||
SplineFontDB: 3.0
|
||||
FontName: mpv-osd-symbols-Regular
|
||||
FullName: mpv-osd-symbols Regular
|
||||
FamilyName: mpv-osd-symbols
|
||||
Weight: Normal
|
||||
Copyright: This is generated file.
|
||||
Version: 001.000
|
||||
ItalicAngle: 0
|
||||
UnderlinePosition: -133
|
||||
UnderlineWidth: 50
|
||||
Ascent: 800
|
||||
Descent: 200
|
||||
InvalidEm: 0
|
||||
sfntRevision: 0x00010000
|
||||
LayerCount: 2
|
||||
Layer: 0 0 "Back" 1
|
||||
Layer: 1 0 "Fore" 0
|
||||
XUID: [1021 879 -1597228462 15927]
|
||||
StyleMap: 0x0040
|
||||
FSType: 8
|
||||
OS2Version: 3
|
||||
OS2_WeightWidthSlopeOnly: 0
|
||||
OS2_UseTypoMetrics: 0
|
||||
CreationTime: 1408646554
|
||||
ModificationTime: 1492879730
|
||||
PfmFamily: 81
|
||||
TTFWeight: 400
|
||||
TTFWidth: 5
|
||||
LineGap: 0
|
||||
VLineGap: 0
|
||||
Panose: 0 0 5 0 0 0 0 0 0 0
|
||||
OS2TypoAscent: 800
|
||||
OS2TypoAOffset: 0
|
||||
OS2TypoDescent: -200
|
||||
OS2TypoDOffset: 0
|
||||
OS2TypoLinegap: 90
|
||||
OS2WinAscent: 1000
|
||||
OS2WinAOffset: 0
|
||||
OS2WinDescent: 200
|
||||
OS2WinDOffset: 0
|
||||
HheadAscent: 1000
|
||||
HheadAOffset: 0
|
||||
HheadDescent: -200
|
||||
HheadDOffset: 0
|
||||
OS2SubXSize: 650
|
||||
OS2SubYSize: 600
|
||||
OS2SubXOff: 0
|
||||
OS2SubYOff: 75
|
||||
OS2SupXSize: 650
|
||||
OS2SupYSize: 600
|
||||
OS2SupXOff: 0
|
||||
OS2SupYOff: 350
|
||||
OS2StrikeYSize: 50
|
||||
OS2StrikeYPos: 220
|
||||
OS2Vendor: 'PfEd'
|
||||
OS2CodePages: 00000001.00000000
|
||||
OS2UnicodeRanges: 00000000.00000000.00000000.00000000
|
||||
DEI: 91125
|
||||
LangName: 1033 "" "" "Regular" "1.000;PfEd;mpv-osd-symbols-Regular" "mpv-osd-symbols" "Version 1.000;PS 001.000;hotconv 1.0.70;makeotf.lib2.5.58329"
|
||||
Encoding: UnicodeBmp
|
||||
UnicodeInterp: none
|
||||
NameList: AGL For New Fonts
|
||||
DisplaySize: -72
|
||||
AntiAlias: 1
|
||||
FitToEm: 0
|
||||
WinInfo: 57600 8 2
|
||||
BeginPrivate: 8
|
||||
BlueValues 31 [-10 0 640 650 720 730 800 810]
|
||||
BlueScale 5 0.037
|
||||
BlueShift 1 0
|
||||
BlueFuzz 1 0
|
||||
StdHW 4 [65]
|
||||
StdVW 4 [65]
|
||||
StemSnapH 8 [65 800]
|
||||
StemSnapV 8 [65 150]
|
||||
EndPrivate
|
||||
EndSplineFont
|
||||
@@ -1,16 +0,0 @@
|
||||
StartChar: uniE001
|
||||
Encoding: 57345 57345 1
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 780 20G<200 200>
|
||||
VStem: 200 375<400 400 400 800>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
575 400 m 1
|
||||
200 0 l 1
|
||||
200 800 l 1
|
||||
575 400 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,22 +0,0 @@
|
||||
StartChar: uniE002
|
||||
Encoding: 57346 57346 2
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 0 800<200 350 200 350 200 500 500 650>
|
||||
VStem: 200 150<0 800 0 800> 500 150<0 800 0 800>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
350 800 m 1
|
||||
350 0 l 1
|
||||
200 0 l 1
|
||||
200 800 l 1
|
||||
350 800 l 1
|
||||
650 800 m 1
|
||||
650 0 l 1
|
||||
500 0 l 1
|
||||
500 800 l 1
|
||||
650 800 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,17 +0,0 @@
|
||||
StartChar: uniE003
|
||||
Encoding: 57347 57347 3
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 0 720<110 775 110 775>
|
||||
VStem: 110 665<0 720 0 720>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
775 720 m 1
|
||||
775 0 l 1
|
||||
110 0 l 1
|
||||
110 720 l 1
|
||||
775 720 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,20 +0,0 @@
|
||||
StartChar: uniE004
|
||||
Encoding: 57348 57348 4
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 780 20G<423 423 813 813>
|
||||
VStem: 48 765<400 400>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
423 800 m 1
|
||||
423 0 l 1
|
||||
48 400 l 1
|
||||
423 800 l 1
|
||||
813 800 m 1
|
||||
813 0 l 1
|
||||
438 400 l 1
|
||||
813 800 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,20 +0,0 @@
|
||||
StartChar: uniE005
|
||||
Encoding: 57349 57349 5
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 780 20G<95 95 485 485>
|
||||
VStem: 95 765<400 400 400 800 400 800>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
470 400 m 1
|
||||
95 0 l 1
|
||||
95 800 l 1
|
||||
470 400 l 1
|
||||
860 400 m 1
|
||||
485 0 l 1
|
||||
485 800 l 1
|
||||
860 400 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,47 +0,0 @@
|
||||
StartChar: uniE006
|
||||
Encoding: 57350 57350 6
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: -10 11<396 461 396 543> 196 171<397 461 396 462> 401 31 801 9<397 462 397 397>
|
||||
VStem: 20 9<369 434 369 513> 224 173<369 408 367 434 367 434> 363 34 397 65<367 404 367 408 367 404 606 801> 462 173<368 404 404 404> 830 10<368 433 433 433>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
430 810 m 0x9940
|
||||
656 810 840 626 840 400 c 0
|
||||
840 174 656 -10 430 -10 c 0
|
||||
204 -10 20 174 20 400 c 0
|
||||
20 626 204 810 430 810 c 0x9940
|
||||
397 606 m 1x5280
|
||||
462 606 l 1
|
||||
462 801 l 1
|
||||
397 801 l 1
|
||||
397 606 l 1x5280
|
||||
462 367 m 1
|
||||
462 404 l 1
|
||||
710 627 l 1
|
||||
683 657 l 1
|
||||
439 437 l 1
|
||||
363 592 l 1
|
||||
318 570 l 1x4280
|
||||
397 408 l 1
|
||||
397 367 l 1x44
|
||||
462 367 l 1
|
||||
224 434 m 1
|
||||
29 434 l 1
|
||||
29 369 l 1
|
||||
224 369 l 1
|
||||
224 434 l 1
|
||||
830 368 m 1
|
||||
830 433 l 1
|
||||
635 433 l 1
|
||||
635 368 l 1
|
||||
830 368 l 1
|
||||
461 196 m 1
|
||||
396 196 l 1
|
||||
396 1 l 1
|
||||
461 1 l 1
|
||||
461 196 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,21 +0,0 @@
|
||||
StartChar: uniE007
|
||||
Encoding: 57351 57351 7
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: -10 80<339 430 339 543> 730 80<339 430>
|
||||
VStem: 20 80<309 491 309 513>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
430 -10 m 0
|
||||
204 -10 20 174 20 400 c 0
|
||||
20 626 204 810 430 810 c 0
|
||||
656 810 840 626 840 400 c 0
|
||||
840 174 656 -10 430 -10 c 0
|
||||
430 70 m 1
|
||||
430 730 l 1
|
||||
248 730 100 582 100 400 c 0
|
||||
100 218 248 70 430 70 c 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,37 +0,0 @@
|
||||
StartChar: uniE008
|
||||
Encoding: 57352 57352 8
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: -10 80<339 521 339 543> 240 160<269 313 546 590> 480 160<408 452> 730 80<339 521>
|
||||
VStem: 20 80<309 491 309 513> 211 160<298 342> 350 160<538 582> 488 160<298 342> 760 80<309 491>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
430 -10 m 0xfa80
|
||||
204 -10 20 174 20 400 c 0
|
||||
20 626 204 810 430 810 c 0
|
||||
656 810 840 626 840 400 c 0
|
||||
840 174 656 -10 430 -10 c 0xfa80
|
||||
430 70 m 0
|
||||
612 70 760 218 760 400 c 0
|
||||
760 582 612 730 430 730 c 0
|
||||
248 730 100 582 100 400 c 0
|
||||
100 218 248 70 430 70 c 0
|
||||
430 480 m 0
|
||||
386 480 350 516 350 560 c 0
|
||||
350 604 386 640 430 640 c 0
|
||||
474 640 510 604 510 560 c 0
|
||||
510 516 474 480 430 480 c 0
|
||||
291 240 m 0xfd80
|
||||
247 240 211 276 211 320 c 0
|
||||
211 364 247 400 291 400 c 0
|
||||
335 400 371 364 371 320 c 0
|
||||
371 276 335 240 291 240 c 0xfd80
|
||||
568 240 m 0
|
||||
524 240 488 276 488 320 c 0
|
||||
488 364 524 400 568 400 c 0
|
||||
612 400 648 364 648 320 c 0
|
||||
648 276 612 240 568 240 c 0
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,17 +0,0 @@
|
||||
StartChar: uniE009
|
||||
Encoding: 57353 57353 9
|
||||
Width: 880
|
||||
Flags: HMW
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
716 10 m 1
|
||||
378 244 l 1
|
||||
165 244 l 1
|
||||
165 559 l 1
|
||||
379 559 l 1
|
||||
716 793 l 1
|
||||
716 10 l 1
|
||||
EndSplineSet
|
||||
Validated: 1
|
||||
EndChar
|
||||
@@ -1,50 +0,0 @@
|
||||
StartChar: uniE00A
|
||||
Encoding: 57354 57354 10
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 252 48<406 406 456 456> 375 50<57 282 57 282 578 805> 500 48<406 406> 627 20G<149 149 713 713>
|
||||
VStem: 282 48<375 375 425 425> 406 50<26 252 26 252 548 774> 530 48<375 375>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
805 375 m 1
|
||||
578 375 l 1
|
||||
574 352 565 331 553 313 c 1
|
||||
713 153 l 1
|
||||
678 118 l 1
|
||||
518 278 l 1
|
||||
500 265 479 256 456 252 c 1
|
||||
456 26 l 1
|
||||
406 26 l 1
|
||||
406 252 l 1
|
||||
383 256 362 265 343 277 c 1
|
||||
184 118 l 1
|
||||
149 153 l 1
|
||||
308 312 l 1
|
||||
295 330 286 352 282 375 c 1
|
||||
57 375 l 1
|
||||
57 425 l 1
|
||||
282 425 l 1
|
||||
286 448 295 470 308 488 c 1
|
||||
149 647 l 1
|
||||
184 682 l 1
|
||||
343 523 l 1
|
||||
362 535 383 544 406 548 c 1
|
||||
406 774 l 1
|
||||
456 774 l 1
|
||||
456 548 l 1
|
||||
479 544 500 535 518 522 c 1
|
||||
678 682 l 1
|
||||
713 647 l 1
|
||||
553 487 l 1
|
||||
565 469 574 448 578 425 c 1
|
||||
805 425 l 1
|
||||
805 375 l 1
|
||||
430 300 m 0
|
||||
485 300 530 345 530 400 c 0
|
||||
530 455 485 500 430 500 c 0
|
||||
375 500 330 455 330 400 c 0
|
||||
330 345 375 300 430 300 c 0
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,27 +0,0 @@
|
||||
StartChar: uniE00B
|
||||
Encoding: 57355 57355 11
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: -10 244<341 519 341 543> 566 54<413.5 446.5 413.5 519> 740 70<413.5 446.5>
|
||||
VStem: 20 88<354 446 354 513> 752 88<354 446>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
430 -10 m 0
|
||||
204 -10 20 174 20 400 c 0
|
||||
20 626 204 810 430 810 c 0
|
||||
656 810 840 626 840 400 c 0
|
||||
840 174 656 -10 430 -10 c 0
|
||||
430 620 m 0
|
||||
463 620 490 647 490 680 c 0
|
||||
490 713 463 740 430 740 c 0
|
||||
397 740 370 713 370 680 c 0
|
||||
370 647 397 620 430 620 c 0
|
||||
430 234 m 0
|
||||
608 234 752 308 752 400 c 0
|
||||
752 492 608 566 430 566 c 0
|
||||
252 566 108 492 108 400 c 0
|
||||
108 308 252 234 430 234 c 0
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,21 +0,0 @@
|
||||
StartChar: uniE010
|
||||
Encoding: 57360 57360 12
|
||||
Width: 334
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 0 90<221 258 221 258> 550 90<221 258 221 221>
|
||||
VStem: 76 145<90 550 90 640 90 640>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
258 640 m 1
|
||||
258 550 l 1
|
||||
221 550 l 1
|
||||
221 90 l 1
|
||||
258 90 l 1
|
||||
258 0 l 1
|
||||
76 0 l 1
|
||||
76 640 l 1
|
||||
258 640 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,17 +0,0 @@
|
||||
StartChar: uniE011
|
||||
Encoding: 57361 57361 13
|
||||
Width: 334
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 0 640<84 250 84 250>
|
||||
VStem: 84 166<0 640 0 640>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
250 640 m 1
|
||||
250 0 l 1
|
||||
84 0 l 1
|
||||
84 640 l 1
|
||||
250 640 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,21 +0,0 @@
|
||||
StartChar: uniE012
|
||||
Encoding: 57362 57362 14
|
||||
Width: 334
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 0 90<76 113 76 258 76 113> 550 90<76 113 76 258>
|
||||
VStem: 113 145<90 550 550 550>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
113 90 m 1
|
||||
113 550 l 1
|
||||
76 550 l 1
|
||||
76 640 l 1
|
||||
258 640 l 1
|
||||
258 0 l 1
|
||||
76 0 l 1
|
||||
76 90 l 1
|
||||
113 90 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,17 +0,0 @@
|
||||
StartChar: uniE013
|
||||
Encoding: 57363 57363 15
|
||||
Width: 334
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 255 130<102 232 102 232>
|
||||
VStem: 102 130<255 385 255 385>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
232 385 m 1
|
||||
232 255 l 1
|
||||
102 255 l 1
|
||||
102 385 l 1
|
||||
232 385 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,16 +0,0 @@
|
||||
StartChar: uniE101
|
||||
Encoding: 57601 57601 16
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 780 20G<222 222>
|
||||
VStem: 222 600<400 400 400 800 400 800>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
822 400 m 1
|
||||
222 0 l 1
|
||||
222 800 l 1
|
||||
822 400 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,25 +0,0 @@
|
||||
StartChar: uniE104
|
||||
Encoding: 57604 57604 17
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 0 800<3 126 3 126 3 502 3 878> 780 20G<3 126 126 126 502 502 878 878>
|
||||
VStem: 3 123<0 800 0 800>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
126 800 m 1x60
|
||||
126 0 l 1
|
||||
3 0 l 1xa0
|
||||
3 800 l 1
|
||||
126 800 l 1x60
|
||||
502 800 m 1
|
||||
502 0 l 1
|
||||
127 400 l 1
|
||||
502 800 l 1
|
||||
878 800 m 1
|
||||
878 0 l 1
|
||||
503 400 l 1
|
||||
878 800 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,25 +0,0 @@
|
||||
StartChar: uniE105
|
||||
Encoding: 57605 57605 18
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 0 800<3 3 3 379 3 755 755 878> 780 20G<3 3 379 379 755 878 878 878>
|
||||
VStem: 755 123<0 800>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
3 0 m 1x60
|
||||
3 800 l 1
|
||||
378 400 l 1
|
||||
3 0 l 1x60
|
||||
379 0 m 1xa0
|
||||
379 800 l 1
|
||||
754 400 l 1
|
||||
379 0 l 1xa0
|
||||
878 0 m 1
|
||||
755 0 l 1
|
||||
755 800 l 1
|
||||
878 800 l 1
|
||||
878 0 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,22 +0,0 @@
|
||||
StartChar: uniE106
|
||||
Encoding: 57606 57606 19
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 0 649<68.5 556.5>
|
||||
VStem: 0 880
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
880 380 m 0
|
||||
880 230 685 101 449 101 c 0
|
||||
390 101 336 107 283 118 c 1
|
||||
278 49 189 0 85 0 c 0
|
||||
52 0 24 14 0 40 c 1
|
||||
82 48 137 93 137 158 c 0
|
||||
137 163 137 168 135 172 c 0
|
||||
58 217 19 273 19 380 c 0
|
||||
19 528 258 649 449 649 c 0
|
||||
664 649 880 508 880 380 c 0
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,56 +0,0 @@
|
||||
StartChar: uniE107
|
||||
Encoding: 57607 57607 20
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 0 60<0 60 60 820> 106 50<146 343 146 343 146 390 390 641 680 735> 207 50<99 317 99 317 99 363 363 488 529 781> 580 60<60 820 60 820>
|
||||
VStem: 0 60<60 580> 99 218<207 257 207 257> 146 197<106 156 106 156> 363 125<207 257 207 257> 529 112<106 257 106 257> 680 55<106 156 106 156> 820 60<0 60 60 580>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
0 60 m 2xfde0
|
||||
0 580 l 2
|
||||
0 610 30 640 60 640 c 2
|
||||
820 640 l 2
|
||||
850 640 880 610 880 580 c 2
|
||||
880 60 l 2
|
||||
880 30 850 0 820 0 c 2
|
||||
60 0 l 2
|
||||
30 0 0 30 0 60 c 2xfde0
|
||||
60 60 m 1
|
||||
820 60 l 1
|
||||
820 580 l 1
|
||||
60 580 l 1
|
||||
60 60 l 1
|
||||
317 257 m 1
|
||||
317 207 l 1
|
||||
99 207 l 1
|
||||
99 257 l 1
|
||||
317 257 l 1
|
||||
488 257 m 1
|
||||
488 207 l 1
|
||||
363 207 l 1
|
||||
363 257 l 1
|
||||
488 257 l 1
|
||||
781 257 m 1
|
||||
781 207 l 1
|
||||
529 207 l 1
|
||||
529 257 l 1
|
||||
781 257 l 1
|
||||
343 156 m 1x4280
|
||||
343 106 l 1
|
||||
146 106 l 1
|
||||
146 156 l 1
|
||||
343 156 l 1x4280
|
||||
641 156 m 1
|
||||
641 106 l 1
|
||||
390 106 l 1
|
||||
390 156 l 1x41c0
|
||||
641 156 l 1
|
||||
735 156 m 1
|
||||
735 106 l 1
|
||||
680 106 l 1
|
||||
680 156 l 1
|
||||
735 156 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,39 +0,0 @@
|
||||
StartChar: uniE108
|
||||
Encoding: 57608 57608 21
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 80 60<0 60 60 820> 321 159<274 606 274 606> 660 60<60 820 60 820>
|
||||
VStem: 0 60<140 660> 274 332<321 480 321 480> 820 60<80 140 140 660>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
0 140 m 2
|
||||
0 660 l 2
|
||||
0 690 30 720 60 720 c 2
|
||||
820 720 l 2
|
||||
850 720 880 690 880 660 c 2
|
||||
880 140 l 2
|
||||
880 110 850 80 820 80 c 2
|
||||
60 80 l 2
|
||||
30 80 0 110 0 140 c 2
|
||||
60 140 m 1
|
||||
820 140 l 1
|
||||
820 660 l 1
|
||||
60 660 l 1
|
||||
60 140 l 1
|
||||
580 600 m 1
|
||||
760 600 l 1
|
||||
760 420 l 1
|
||||
580 600 l 1
|
||||
606 480 m 1
|
||||
606 321 l 1
|
||||
274 321 l 1
|
||||
274 480 l 1
|
||||
606 480 l 1
|
||||
300 200 m 1
|
||||
120 200 l 1
|
||||
120 380 l 1
|
||||
300 200 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,39 +0,0 @@
|
||||
StartChar: uniE109
|
||||
Encoding: 57609 57609 22
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 80 60<0 60 60 820> 296 209<285 595 285 595> 660 60<60 820 60 820>
|
||||
VStem: 0 60<140 660> 120 107<400 400 400 510> 285 310<296 505 296 505> 653 107<400 400> 820 60<80 140 140 660>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
0 140 m 2
|
||||
0 660 l 2
|
||||
0 690 30 720 60 720 c 2
|
||||
820 720 l 2
|
||||
850 720 880 690 880 660 c 2
|
||||
880 140 l 2
|
||||
880 110 850 80 820 80 c 2
|
||||
60 80 l 2
|
||||
30 80 0 110 0 140 c 2
|
||||
60 140 m 1
|
||||
820 140 l 1
|
||||
820 660 l 1
|
||||
60 660 l 1
|
||||
60 140 l 1
|
||||
227 400 m 1
|
||||
120 290 l 1
|
||||
120 510 l 1
|
||||
227 400 l 1
|
||||
760 290 m 1
|
||||
653 400 l 1
|
||||
760 510 l 1
|
||||
760 290 l 1
|
||||
595 505 m 1
|
||||
595 296 l 1
|
||||
285 296 l 1
|
||||
285 505 l 1
|
||||
595 505 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,36 +0,0 @@
|
||||
StartChar: uniE10A
|
||||
Encoding: 57610 57610 23
|
||||
Width: 1977
|
||||
GlyphClass: 2
|
||||
Flags: HMWO
|
||||
HStem: 242 248<2 155 2 156>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
398 58 m 1
|
||||
155 242 l 1
|
||||
2 242 l 1
|
||||
2 490 l 1
|
||||
156 490 l 1
|
||||
398 674 l 1
|
||||
398 58 l 1
|
||||
809 524 m 0
|
||||
814 524 819 523 823 519 c 0
|
||||
831 511 831 499 823 491 c 2
|
||||
697 365 l 1
|
||||
823 239 l 2
|
||||
830 232 830 221 823 213 c 0
|
||||
816 206 804 206 797 213 c 2
|
||||
671 339 l 1
|
||||
545 213 l 2
|
||||
538 206 525 206 518 213 c 0
|
||||
510 221 510 233 518 241 c 2
|
||||
643 367 l 1
|
||||
517 493 l 2
|
||||
510 500 510 511 517 519 c 0
|
||||
525 526 536 526 544 519 c 2
|
||||
670 393 l 1
|
||||
796 519 l 2
|
||||
799 523 804 524 809 524 c 0
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,26 +0,0 @@
|
||||
StartChar: uniE10B
|
||||
Encoding: 57611 57611 24
|
||||
Width: 1977
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 242 248<2 155 2 156>
|
||||
VStem: 603 47<326.5 405>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
650 366 m 0
|
||||
650 281 615 198 545 119 c 1
|
||||
507 142 l 1
|
||||
571 213 603 287 603 366 c 0
|
||||
603 444 571 518 507 590 c 1
|
||||
545 613 l 1
|
||||
615 534 650 452 650 366 c 0
|
||||
398 58 m 1
|
||||
155 242 l 1
|
||||
2 242 l 1
|
||||
2 490 l 1
|
||||
156 490 l 1
|
||||
398 674 l 1
|
||||
398 58 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,33 +0,0 @@
|
||||
StartChar: uniE10C
|
||||
Encoding: 57612 57612 25
|
||||
Width: 1977
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 242 248<2 155 2 156>
|
||||
VStem: 603 47<326.5 405> 717 47<316.5 416>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
764 366 m 0
|
||||
764 258 720 156 631 61 c 1
|
||||
593 84 l 1
|
||||
675 173 717 267 717 366 c 0
|
||||
717 466 675 559 593 647 c 1
|
||||
631 671 l 1
|
||||
720 578 764 476 764 366 c 0
|
||||
650 366 m 0
|
||||
650 281 615 198 545 119 c 1
|
||||
507 142 l 1
|
||||
571 213 603 287 603 366 c 0
|
||||
603 444 571 518 507 590 c 1
|
||||
545 613 l 1
|
||||
615 534 650 452 650 366 c 0
|
||||
398 58 m 1
|
||||
155 242 l 1
|
||||
2 242 l 1
|
||||
2 490 l 1
|
||||
156 490 l 1
|
||||
398 674 l 1
|
||||
398 58 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,40 +0,0 @@
|
||||
StartChar: uniE10D
|
||||
Encoding: 57613 57613 26
|
||||
Width: 1977
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 242 248<2 155 2 156> 709 20G<717 717>
|
||||
VStem: 603 47<326.5 405> 717 47<316.5 416> 830 47<304 426.5>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
877 366 m 0
|
||||
877 236 824 115 717 3 c 1
|
||||
679 27 l 1
|
||||
780 130 830 242 830 366 c 0
|
||||
830 487 780 600 679 705 c 1
|
||||
717 729 l 1
|
||||
824 617 877 496 877 366 c 0
|
||||
764 366 m 0
|
||||
764 258 720 156 631 61 c 1
|
||||
593 84 l 1
|
||||
675 173 717 267 717 366 c 0
|
||||
717 466 675 559 593 647 c 1
|
||||
631 671 l 1
|
||||
720 578 764 476 764 366 c 0
|
||||
650 366 m 0
|
||||
650 281 615 198 545 119 c 1
|
||||
507 142 l 1
|
||||
571 213 603 287 603 366 c 0
|
||||
603 444 571 518 507 590 c 1
|
||||
545 613 l 1
|
||||
615 534 650 452 650 366 c 0
|
||||
398 58 m 1
|
||||
155 242 l 1
|
||||
2 242 l 1
|
||||
2 490 l 1
|
||||
156 490 l 1
|
||||
398 674 l 1
|
||||
398 58 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,53 +0,0 @@
|
||||
StartChar: uniE10E
|
||||
Encoding: 57614 57614 27
|
||||
Width: 1977
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 49 95<806 818.5> 242 248<2 155 2 156>
|
||||
VStem: 559 47<326.5 405> 673 47<316.5 416> 767 91<90 103.5 648 652>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
720 366 m 0
|
||||
720 258 676 156 587 61 c 1
|
||||
549 84 l 1
|
||||
631 173 673 267 673 366 c 0
|
||||
673 466 631 559 549 647 c 1
|
||||
587 671 l 1
|
||||
676 578 720 476 720 366 c 0
|
||||
606 366 m 0
|
||||
606 281 571 198 501 119 c 1
|
||||
463 142 l 1
|
||||
527 213 559 287 559 366 c 0
|
||||
559 444 527 518 463 590 c 1
|
||||
501 613 l 1
|
||||
571 534 606 452 606 366 c 0
|
||||
398 58 m 1
|
||||
155 242 l 1
|
||||
2 242 l 1
|
||||
2 490 l 1
|
||||
156 490 l 1
|
||||
398 674 l 1
|
||||
398 58 l 1
|
||||
858 648 m 1
|
||||
824 238 l 2
|
||||
823 224 819 217 812 217 c 0
|
||||
805 217 801 224 800 238 c 2
|
||||
767 648 l 1
|
||||
767 652 l 2
|
||||
767 665 771 675 780 682 c 0
|
||||
789 690 800 694 812 694 c 0
|
||||
825 694 835 690 844 682 c 0
|
||||
853 675 858 665 858 652 c 2
|
||||
858 648 l 1
|
||||
858 97 m 0
|
||||
858 83 853 72 845 63 c 0
|
||||
836 53 825 49 812 49 c 0
|
||||
800 49 789 53 780 63 c 0
|
||||
771 72 767 83 767 97 c 0
|
||||
767 110 771 121 780 130 c 0
|
||||
789 140 800 144 812 144 c 0
|
||||
825 144 836 140 845 130 c 0
|
||||
853 121 858 110 858 97 c 0
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,16 +0,0 @@
|
||||
StartChar: uniE110
|
||||
Encoding: 57616 57616 28
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: MW
|
||||
HStem: 780 20G<656 656>
|
||||
VStem: 56 600<400 400>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
656 0 m 1
|
||||
56 400 l 1
|
||||
656 800 l 1
|
||||
656 0 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
@@ -1,37 +0,0 @@
|
||||
StartChar: uniE111
|
||||
Encoding: 57617 57617 29
|
||||
Width: 880
|
||||
GlyphClass: 2
|
||||
Flags: W
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
0 140 m 2
|
||||
0 660 l 2
|
||||
0 690 30 720 60 720 c 2
|
||||
820 720 l 2
|
||||
850 720 880 690 880 660 c 2
|
||||
880 140 l 2
|
||||
880 110 850 80 820 80 c 2
|
||||
60 80 l 2
|
||||
30 80 0 110 0 140 c 2
|
||||
60 140 m 1
|
||||
820 140 l 1
|
||||
820 660 l 1
|
||||
60 660 l 1
|
||||
60 140 l 1
|
||||
227 400 m 1
|
||||
120 290 l 1
|
||||
120 510 l 1
|
||||
227 400 l 1
|
||||
760 290 m 1
|
||||
653 400 l 1
|
||||
760 510 l 1
|
||||
760 290 l 1
|
||||
595 505 m 1
|
||||
595 296 l 1
|
||||
285 296 l 1
|
||||
285 505 l 1
|
||||
595 505 l 1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
+150
-126
@@ -17,133 +17,157 @@
|
||||
# When multiple files were specified, their info will be put into FOO_* for the
|
||||
# first file, FOO_1_* for the second file, FOO_2_* for the third file, etc.
|
||||
|
||||
__midentify__main() {
|
||||
|
||||
case "$0" in
|
||||
mpv_identify.sh|*/mpv_identify.sh)
|
||||
# we are NOT being sourced
|
||||
[ -n "$1" ] && set -- '' "$@"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$#" -lt 2 ]; then
|
||||
cat >&2 <<EOF
|
||||
Usage 1 (for humans only): $0 filename.mkv
|
||||
will print all property values.
|
||||
Note that this output really shouldn't be parsed, as the
|
||||
format is subject to change.
|
||||
|
||||
Usage 2 (for use by scripts): see top of this file
|
||||
|
||||
NOTE: for mkv with ordered chapters, this may
|
||||
not always identify the specified file, but the
|
||||
file providing the first chapter. Specify
|
||||
--no-ordered-chapters to prevent this.
|
||||
EOF
|
||||
return 2
|
||||
fi
|
||||
|
||||
local LF="
|
||||
"
|
||||
|
||||
local nextprefix="$1"
|
||||
shift
|
||||
|
||||
if [ -n "$nextprefix" ]; then
|
||||
# in case of error, we always want this unset
|
||||
unset "${nextprefix}path"
|
||||
fi
|
||||
|
||||
local allprops="
|
||||
filename
|
||||
path
|
||||
stream-start
|
||||
stream-end
|
||||
stream-length
|
||||
|
||||
demuxer
|
||||
|
||||
length
|
||||
chapters
|
||||
editions
|
||||
titles
|
||||
duration
|
||||
|
||||
audio
|
||||
audio-bitrate
|
||||
audio-codec
|
||||
audio-codec-name
|
||||
|
||||
video
|
||||
angle
|
||||
video-bitrate
|
||||
video-codec
|
||||
video-format
|
||||
video-aspect
|
||||
container-fps
|
||||
width
|
||||
height
|
||||
dwidth
|
||||
dheight
|
||||
|
||||
sub
|
||||
"
|
||||
# TODO add metadata support once mpv can do it
|
||||
|
||||
local propstr="X-MIDENTIFY-START:$LF"
|
||||
local key
|
||||
for key in $allprops; do
|
||||
propstr="${propstr}X-MIDENTIFY: $key \${=$key}$LF"
|
||||
key="$(printf '%s\n' "$key" | tr - _)"
|
||||
unset "$nextprefix$key"
|
||||
done
|
||||
|
||||
local fileindex=0
|
||||
local prefix=
|
||||
local line
|
||||
while IFS= read -r line; do
|
||||
case "$line" in
|
||||
X-MIDENTIFY-START:)
|
||||
if [ -n "$nextprefix" ]; then
|
||||
prefix="$nextprefix"
|
||||
if [ "$fileindex" -gt 0 ]; then
|
||||
nextprefix="${prefix%${fileindex}_}"
|
||||
fi
|
||||
fileindex="$((fileindex+1))"
|
||||
nextprefix="${nextprefix}${fileindex}_"
|
||||
for key in $allprops; do
|
||||
key="$(printf '%s\n' "$key" | tr - _)"
|
||||
unset "$nextprefix$key"
|
||||
done
|
||||
else
|
||||
if [ "$fileindex" -gt 0 ]; then
|
||||
printf '\n'
|
||||
fi
|
||||
fileindex="$((fileindex+1))"
|
||||
fi
|
||||
case "$0" in
|
||||
mpv_identify.sh|*/mpv_identify.sh)
|
||||
# we are NOT being sourced
|
||||
case "$1" in
|
||||
'')
|
||||
;;
|
||||
X-MIDENTIFY:\ *)
|
||||
local key="${line#X-MIDENTIFY: }"
|
||||
local value="${key#* }"
|
||||
key="${key%% *}"
|
||||
key="$(printf '%s\n' "$key" | tr - _)"
|
||||
if [ -n "$nextprefix" ]; then
|
||||
if [ -z "$prefix" ]; then
|
||||
echo >&2 "Got X-MIDENTIFY: without X-MIDENTIFY-START:"
|
||||
elif [ -n "$value" ]; then
|
||||
eval "$prefix$key"='"$value"'
|
||||
fi
|
||||
else
|
||||
if [ -n "$value" ]; then
|
||||
printf '%s=%s\n' "$key" "$value"
|
||||
fi
|
||||
fi
|
||||
*)
|
||||
set -- '' "$@"
|
||||
;;
|
||||
esac
|
||||
done <<EOF
|
||||
$(${MPV:-mpv} --term-playing-msg="$propstr" --vo=null --ao=null \
|
||||
--frames=1 --quiet --no-cache --no-config -- "$@")
|
||||
EOF
|
||||
}
|
||||
;;
|
||||
esac
|
||||
|
||||
__midentify__main "$@"
|
||||
if [ $# -lt 2 ]; then
|
||||
echo >&2 "Usage 1 (for humans only): $0 filename.mkv"
|
||||
echo >&2 "will print all property values."
|
||||
echo >&2 "Note that this output really shouldn't be parsed, as the"
|
||||
echo >&2 "format is subject to change."
|
||||
echo >&2
|
||||
echo >&2 "Usage 2 (for use by scripts): see top of this file"
|
||||
echo >&2
|
||||
echo >&2 "NOTE: for mkv with ordered chapters, this may"
|
||||
echo >&2 "not always identify the specified file, but the"
|
||||
echo >&2 "file providing the first chapter. Specify"
|
||||
echo >&2 "--no-ordered-chapters to prevent this."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$MPV" ]; then
|
||||
MPV="mpv"
|
||||
fi
|
||||
|
||||
__midentify__LF="
|
||||
"
|
||||
|
||||
__midentify__nextprefix=$1
|
||||
shift
|
||||
|
||||
if [ -n "$__midentify__nextprefix" ]; then
|
||||
# in case of error, we always want this unset
|
||||
eval unset $__midentify__nextprefix'path'
|
||||
fi
|
||||
|
||||
__midentify__allprops="
|
||||
filename
|
||||
path
|
||||
stream-start
|
||||
stream-end
|
||||
stream-length
|
||||
|
||||
demuxer
|
||||
|
||||
length
|
||||
chapters
|
||||
editions
|
||||
titles
|
||||
|
||||
audio
|
||||
audio-bitrate
|
||||
audio-codec
|
||||
audio-format
|
||||
channels
|
||||
samplerate
|
||||
|
||||
video
|
||||
angle
|
||||
video-bitrate
|
||||
video-codec
|
||||
video-format
|
||||
video-aspect
|
||||
fps
|
||||
width
|
||||
height
|
||||
dwidth
|
||||
dheight
|
||||
|
||||
sub
|
||||
"
|
||||
# TODO add metadata support once mpv can do it
|
||||
|
||||
__midentify__propstr="X-MIDENTIFY-START:$__midentify__LF"
|
||||
for __midentify__key in $__midentify__allprops; do
|
||||
__midentify__propstr=$__midentify__propstr"X-MIDENTIFY: $__midentify__key \${=$__midentify__key}$__midentify__LF"
|
||||
__midentify__key=`echo "$__midentify__key" | tr - _`
|
||||
eval unset $__midentify__nextprefix$__midentify__key
|
||||
done
|
||||
|
||||
__midentify__output=`$MPV --term-playing-msg="$__midentify__propstr" --vo=null --ao=null --frames=1 --quiet --no-cache --no-config "$@"`
|
||||
__midentify__fileindex=0
|
||||
__midentify__prefix=
|
||||
while :; do
|
||||
case "$__midentify__output" in
|
||||
'')
|
||||
break
|
||||
;;
|
||||
*$__midentify__LF*)
|
||||
__midentify__line=${__midentify__output%%$__midentify__LF*}
|
||||
__midentify__output=${__midentify__output#*$__midentify__LF}
|
||||
;;
|
||||
*)
|
||||
__midentify__line=$__midentify__output
|
||||
__midentify__output=
|
||||
;;
|
||||
esac
|
||||
case "$__midentify__line" in
|
||||
X-MIDENTIFY-START:)
|
||||
if [ -n "$__midentify__nextprefix" ]; then
|
||||
__midentify__prefix=$__midentify__nextprefix
|
||||
if [ $__midentify__fileindex -gt 0 ]; then
|
||||
__midentify__nextprefix=${__midentify__prefix%$__midentify__fileindex\_}
|
||||
fi
|
||||
__midentify__fileindex=$(($__midentify__fileindex+1))
|
||||
__midentify__nextprefix=$__midentify__nextprefix$__midentify__fileindex\_
|
||||
for __midentify__key in $__midentify__allprops; do
|
||||
__midentify__key=`echo "$__midentify__key" | tr - _`
|
||||
eval unset $__midentify__nextprefix$__midentify__key
|
||||
done
|
||||
else
|
||||
if [ $__midentify__fileindex -gt 0 ]; then
|
||||
echo
|
||||
fi
|
||||
__midentify__fileindex=$(($__midentify__fileindex+1))
|
||||
fi
|
||||
;;
|
||||
X-MIDENTIFY:\ *)
|
||||
__midentify__key=${__midentify__line#X-MIDENTIFY:\ }
|
||||
__midentify__value=${__midentify__key#* }
|
||||
__midentify__key=${__midentify__key%% *}
|
||||
__midentify__key=`echo "$__midentify__key" | tr - _`
|
||||
if [ -n "$__midentify__nextprefix" ]; then
|
||||
if [ -z "$__midentify__prefix" ]; then
|
||||
echo >&2 "Got X-MIDENTIFY: without X-MIDENTIFY-START:"
|
||||
elif [ -n "$__midentify__value" ]; then
|
||||
eval $__midentify__prefix$__midentify__key=\$__midentify__value
|
||||
fi
|
||||
else
|
||||
if [ -n "$__midentify__value" ]; then
|
||||
echo "$__midentify__key=$__midentify__value"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
unset __midentify__fileindex
|
||||
unset __midentify__allprops
|
||||
unset __midentify__key
|
||||
unset __midentify__LF
|
||||
unset __midentify__line
|
||||
unset __midentify__output
|
||||
unset __midentify__nextprefix
|
||||
unset __midentify__prefix
|
||||
unset __midentify__propstr
|
||||
unset __midentify__value
|
||||
+2
-13
@@ -3,7 +3,6 @@
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import fileinput
|
||||
from optparse import OptionParser
|
||||
|
||||
def sh(command):
|
||||
@@ -36,20 +35,10 @@ def copy_binary(binary_name):
|
||||
shutil.copy(binary_name, target_binary(binary_name))
|
||||
|
||||
def apply_plist_template(plist_file, version):
|
||||
for line in fileinput.input(plist_file, inplace=1):
|
||||
print (line.rstrip().replace('${VERSION}', version))
|
||||
|
||||
def bundle_version():
|
||||
if os.path.exists('VERSION'):
|
||||
x = open('VERSION')
|
||||
version = x.read()
|
||||
x.close()
|
||||
else:
|
||||
version = sh("./version.sh").strip()
|
||||
return version
|
||||
sh("sed -i -e 's/${VERSION}/%s/g' %s" % (version, plist_file))
|
||||
|
||||
def main():
|
||||
version = bundle_version().rstrip()
|
||||
version = sh("./version.sh --print").strip()
|
||||
|
||||
usage = "usage: %prog [options] arg"
|
||||
parser = OptionParser(usage)
|
||||
|
||||
@@ -88,7 +88,6 @@
|
||||
<string>VOB</string>
|
||||
<string>WEBM</string>
|
||||
<string>WMV</string>
|
||||
<string>MK3D</string>
|
||||
<string>asf</string>
|
||||
<string>avi</string>
|
||||
<string>cpk</string>
|
||||
@@ -123,7 +122,6 @@
|
||||
<string>vob</string>
|
||||
<string>webm</string>
|
||||
<string>wmv</string>
|
||||
<string>mk3d</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
@@ -173,7 +171,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>mpv-wrapper.sh</string>
|
||||
<string>mpv</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>icon</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@@ -210,7 +208,6 @@
|
||||
<string>mms</string>
|
||||
<string>mmst</string>
|
||||
<string>http</string>
|
||||
<string>https</string>
|
||||
<string>httpproxy</string>
|
||||
<string>rtp</string>
|
||||
<string>rtsp</string>
|
||||
@@ -516,47 +513,6 @@
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>mkv</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.movie</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Matroska stereoscopic/3D video</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>io.mpv.mk3d</string>
|
||||
<key>UTTypeReferenceURL</key>
|
||||
<string>http://www.matroska.org</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>mk3d</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.movie</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>WebM Video</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>io.mpv.webm</string>
|
||||
<key>UTTypeReferenceURL</key>
|
||||
<string>http://www.webmproject.org</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>webm</string>
|
||||
</array>
|
||||
</dict>
|
||||
|
||||
Loaded 100 of 756 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user