diff options
author | jaseg <git@jaseg.de> | 2023-10-14 13:03:20 +0200 |
---|---|---|
committer | jaseg <git@jaseg.de> | 2023-10-14 13:03:20 +0200 |
commit | d3129f384f2a7313d7d2259b09c4d46661597ed7 (patch) | |
tree | 030c1e62fe05d93ae95b678b9546d95de7d70da8 /projects/python-mpv/index.html | |
parent | 2cdeee2a3c728a42dc1b9fe9d6892ea647402e1c (diff) | |
parent | 74d7f5c965c55be28ea6da0e0e33f7f0fd5478f9 (diff) | |
download | blog-d3129f384f2a7313d7d2259b09c4d46661597ed7.tar.gz blog-d3129f384f2a7313d7d2259b09c4d46661597ed7.tar.bz2 blog-d3129f384f2a7313d7d2259b09c4d46661597ed7.zip |
deploy.py auto-commit
Diffstat (limited to 'projects/python-mpv/index.html')
-rw-r--r-- | projects/python-mpv/index.html | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/projects/python-mpv/index.html b/projects/python-mpv/index.html new file mode 100644 index 0000000..e7e19a7 --- /dev/null +++ b/projects/python-mpv/index.html @@ -0,0 +1,408 @@ +<!DOCTYPE html> +<html><head> + <meta charset="utf-8"> + <title>python-mpv | Home</title> + <meta name="description" content=""> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="mobile-web-app-capable" content="yes"> + <meta name="color-scheme" content="dark light"> + <link rel="stylesheet" href="/style.css"> +</head> +<body><nav> + <div class="internal"> + + <a href="/" title="Home">Home</a> + <a href="/blog/" title="Blog">Blog</a> + <a href="/projects/" title="Projects">Projects</a> + <a href="/about/" title="About">About</a> + </div> + <div class="external"> + <a href="https://git.jaseg.de/" title="cgit">cgit</a> + <a href="https://github.com/jaseg" title="Github">Github</a> + <a href="https://gitlab.com/neinseg" title="Gitlab">Gitlab</a> + <a href="https://chaos.social/jaseg" title="Mastodon">Mastodon</a> + </span> +</nav> + + <header> + <h1>python-mpv</h1> +<ul class="breadcrumbs"> + <li><a href="/">jaseg.de</a></li> + <li><a href="/projects/">Projects</a></li><li><a href="/projects/python-mpv/">python-mpv</a></li> +</ul> + + </header> + <main> + <div class="links"> + <a href="https://git.jaseg.de/python-mpv.git">Sources</a> + <a href="https://github.com/jaseg/python-mpv/issues">Issues</a> + <a href="https://neinseg.gitlab.io/python-mpv">Docs</a> + <a href="https://pypi.org/project/mpv">PyPI</a> + </div> + <div class="document"> + + +<!-- vim: tw=120 sw=4 et --> +<p>python-mpv is a ctypes-based python interface to the mpv media player. It gives you more or less full control of all +features of the player, just as the lua interface does.</p> +<div class="section" id="installation"> +<h2>Installation</h2> +<pre class="code bash literal-block"> +<span class="lineno"></span><span class="line">pip<span class="w"> </span>install<span class="w"> </span>mpv +</span></pre> +<p>...though you can also realistically just copy <a class="reference external" href="https://raw.githubusercontent.com/jaseg/python-mpv/main/mpv.py">mpv.py</a> into your project as it's all nicely contained in one file.</p> +<div class="section" id="requirements"> +<h3>Requirements</h3> +<div class="section" id="libmpv"> +<h4>libmpv</h4> +<p><tt class="docutils literal">libmpv.so</tt> either locally (in your current working directory) or somewhere in your system library search path. This +module is somewhat lenient as far as <tt class="docutils literal">libmpv</tt> versions are concerned but since <tt class="docutils literal">libmpv</tt> is changing quite frequently +you'll only get all the newest features when using an up-to-date version of this module. The unit tests for this module +do some basic automatic version compatibility checks. If you discover anything missing here, please open an <a class="reference external" href="https://github.com/jaseg/python-mpv/issues">issue</a> or +submit a <a class="reference external" href="https://github.com/jaseg/python-mpv/pulls">pull request</a> on github.</p> +<p>On Windows you can place libmpv anywhere in your <tt class="docutils literal">%PATH%</tt> (e.g. next to <tt class="docutils literal">python.exe</tt>) or next to this module's +<tt class="docutils literal">mpv.py</tt>. Before falling back to looking in the mpv module's directory, python-mpv uses the DLL search order built +into ctypes, which is different to the one Windows uses internally. Consult <a class="reference external" href="https://stackoverflow.com/a/23805306">this stackoverflow post</a> for details.</p> +</div> +<div class="section" id="python-3-7-officially"> +<h4>Python >= 3.7 (officially)</h4> +<p>The <tt class="docutils literal">main</tt> branch officially only supports recent python releases (3.5 onwards), but there is the somewhat outdated +but functional <a class="reference external" href="https://github.com/jaseg/python-mpv/tree/py2compat">py2compat branch</a> providing Python 2 compatibility.</p> +</div> +<div class="section" id="supported-platforms"> +<h4>Supported Platforms</h4> +<p><strong>Linux</strong>, <strong>Windows</strong> and <strong>OSX</strong> all seem to work mostly fine. For some notes on the installation on Windows see +<a class="reference external" href="https://github.com/jaseg/python-mpv/issues/60#issuecomment-352719773">this comment</a>. Shared library handling is quite bad on windows, so expect some pain there. On OSX there seems to be +some bug int the event logic. See <a class="reference external" href="https://github.com/jaseg/python-mpv/issues/36">issue 36</a> and <a class="reference external" href="https://github.com/jaseg/python-mpv/issues/61">issue 61</a> for details. Creating a pyQT window and having mpv draw +into it seems to be a workaround (about 10loc), but in case you want this fixed please weigh in on the issue tracker +since right now there is not many OSX users.</p> +</div> +</div> +</div> +<div class="section" id="usage"> +<h2>Usage</h2> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">ytdl</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s1">'https://youtu.be/DOmdB7D-pUU'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">wait_for_playback</span><span class="p">()</span> +</span></pre> +<p>python-mpv mostly exposes mpv's built-in API to python, adding only some porcelain on top. Most "<a class="reference external" href="https://mpv.io/manual/master/#list-of-input-commands">input commands</a>" are mapped to methods of the MPV class. Check out these methods and their docstrings in <a class="reference external" href="https://github.com/jaseg/python-mpv/blob/main/mpv.py">the source</a> for things you can do. Additional controls and status information are exposed through <a class="reference external" href="https://mpv.io/manual/master/#properties">MPV properties</a>. These can be accessed like <tt class="docutils literal">player.metadata</tt>, <tt class="docutils literal">player.fullscreen</tt> and <tt class="docutils literal">player.loop_playlist</tt>.</p> +<div class="section" id="threading"> +<h3>Threading</h3> +<p>The <tt class="docutils literal">mpv</tt> module starts one thread for event handling, since MPV sends events that must be processed quickly. The +event queue has a fixed maxmimum size and some operations can cause a large number of events to be sent.</p> +<p>If you want to handle threading yourself, you can pass <tt class="docutils literal">start_event_thread=False</tt> to the <tt class="docutils literal">MPV</tt> constructor and +manually call the <tt class="docutils literal">MPV</tt> object's <tt class="docutils literal">_loop</tt> function. If you have some strong need to not use threads and use some +external event loop (such as asyncio) instead you can do that, too with some work. The API of the backend C <tt class="docutils literal">libmpv</tt> +has a function for producing a sort of event file descriptor for a handle. You can use that to produce a file descriptor +that can be passed to an event loop to tell it to wake up the python-mpv event handler on every incoming event.</p> +<p>All API functions are thread-safe. If one is not, please file an issue on github.</p> +</div> +<div class="section" id="advanced-usage"> +<h3>Advanced Usage</h3> +<div class="section" id="logging-properties-python-key-bindings-screenshots-and-youtube-dl"> +<h4>Logging, Properties, Python Key Bindings, Screenshots and youtube-dl</h4> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">my_log</span><span class="p">(</span><span class="n">loglevel</span><span class="p">,</span> <span class="n">component</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">print</span><span class="p">(</span><span class="s1">'[</span><span class="si">{}</span><span class="s1">] </span><span class="si">{}</span><span class="s1">: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">loglevel</span><span class="p">,</span> <span class="n">component</span><span class="p">,</span> <span class="n">message</span><span class="p">))</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">log_handler</span><span class="o">=</span><span class="n">my_log</span><span class="p">,</span> <span class="n">ytdl</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_default_bindings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_vo_keyboard</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c1"># Property access, these can be changed at runtime</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="nd">@player</span><span class="o">.</span><span class="n">property_observer</span><span class="p">(</span><span class="s1">'time-pos'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">time_observer</span><span class="p">(</span><span class="n">_name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># Here, _value is either None if nothing is playing or a float containing</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># fractional seconds since the beginning of the file.</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">print</span><span class="p">(</span><span class="s1">'Now playing at </span><span class="si">{:.2f}</span><span class="s1">s'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">fullscreen</span> <span class="o">=</span> <span class="kc">True</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">loop_playlist</span> <span class="o">=</span> <span class="s1">'inf'</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c1"># Option access, in general these require the core to reinitialize</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="p">[</span><span class="s1">'vo'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'gpu'</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="nd">@player</span><span class="o">.</span><span class="n">on_key_press</span><span class="p">(</span><span class="s1">'q'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">my_q_binding</span><span class="p">():</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">print</span><span class="p">(</span><span class="s1">'THERE IS NO ESCAPE'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="nd">@player</span><span class="o">.</span><span class="n">on_key_press</span><span class="p">(</span><span class="s1">'s'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">my_s_binding</span><span class="p">():</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">pillow_img</span> <span class="o">=</span> <span class="n">player</span><span class="o">.</span><span class="n">screenshot_raw</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">pillow_img</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s1">'screenshot.png'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s1">'https://youtu.be/DLzxrzFCyOs'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">wait_for_playback</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">del</span> <span class="n">player</span> +</span></pre> +</div> +<div class="section" id="skipping-silence-using-libav-filters"> +<h4>Skipping silence using libav filters</h4> +<p>The following code uses the libav silencedetect filter to skip silence at the beginning of a file. It works by loading +the filter, then parsing its output from mpv's log. Thanks to Sean DeNigris on github (#202) for the original code!</p> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">sys</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">p</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">p</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">skip_silence</span><span class="p">():</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">p</span><span class="o">.</span><span class="n">set_loglevel</span><span class="p">(</span><span class="s1">'debug'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">p</span><span class="o">.</span><span class="n">af</span> <span class="o">=</span> <span class="s1">'lavfi=[silencedetect=n=-20dB:d=1]'</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">p</span><span class="o">.</span><span class="n">speed</span> <span class="o">=</span> <span class="mi">100</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="n">evt</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">toks</span> <span class="o">=</span> <span class="n">evt</span><span class="p">[</span><span class="s1">'event'</span><span class="p">][</span><span class="s1">'text'</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">if</span> <span class="s1">'silence_end:'</span> <span class="ow">in</span> <span class="n">toks</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">return</span> <span class="nb">float</span><span class="p">(</span><span class="n">toks</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">p</span><span class="o">.</span><span class="n">time_pos</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">wait_for_event</span><span class="p">(</span><span class="s1">'log_message'</span><span class="p">,</span> <span class="n">cond</span><span class="o">=</span><span class="n">check</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">p</span><span class="o">.</span><span class="n">speed</span> <span class="o">=</span> <span class="mi">1</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">p</span><span class="o">.</span><span class="n">af</span> <span class="o">=</span> <span class="s1">''</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">skip_silence</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">p</span><span class="o">.</span><span class="n">wait_for_playback</span><span class="p">()</span> +</span></pre> +</div> +<div class="section" id="video-overlays"> +<h4>Video overlays</h4> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">time</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span> <span class="nn">PIL</span> <span class="kn">import</span> <span class="n">Image</span><span class="p">,</span> <span class="n">ImageDraw</span><span class="p">,</span> <span class="n">ImageFont</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">loop</span> <span class="o">=</span> <span class="kc">True</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s1">'test.webm'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">wait_until_playing</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">font</span> <span class="o">=</span> <span class="n">ImageFont</span><span class="o">.</span><span class="n">truetype</span><span class="p">(</span><span class="s1">'DejaVuSans.ttf'</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">while</span> <span class="ow">not</span> <span class="n">player</span><span class="o">.</span><span class="n">core_idle</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">overlay</span> <span class="o">=</span> <span class="n">player</span><span class="o">.</span><span class="n">create_image_overlay</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">for</span> <span class="n">pos</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">500</span><span class="p">,</span> <span class="mi">5</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">ts</span> <span class="o">=</span> <span class="n">player</span><span class="o">.</span><span class="n">time_pos</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">if</span> <span class="n">ts</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">break</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">img</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">'RGBA'</span><span class="p">,</span> <span class="p">(</span><span class="mi">400</span><span class="p">,</span> <span class="mi">150</span><span class="p">),</span> <span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">d</span> <span class="o">=</span> <span class="n">ImageDraw</span><span class="o">.</span><span class="n">Draw</span><span class="p">(</span><span class="n">img</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">d</span><span class="o">.</span><span class="n">text</span><span class="p">((</span><span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">),</span> <span class="s1">'Hello World'</span><span class="p">,</span> <span class="n">font</span><span class="o">=</span><span class="n">font</span><span class="p">,</span> <span class="n">fill</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">128</span><span class="p">))</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">d</span><span class="o">.</span><span class="n">text</span><span class="p">((</span><span class="mi">10</span><span class="p">,</span> <span class="mi">60</span><span class="p">),</span> <span class="sa">f</span><span class="s1">'t=</span><span class="si">{</span><span class="n">ts</span><span class="si">:</span><span class="s1">.3f</span><span class="si">}</span><span class="s1">'</span><span class="p">,</span> <span class="n">font</span><span class="o">=</span><span class="n">font</span><span class="p">,</span> <span class="n">fill</span><span class="o">=</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">))</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">overlay</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">img</span><span class="p">,</span> <span class="n">pos</span><span class="o">=</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">pos</span><span class="p">,</span> <span class="n">pos</span><span class="p">))</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.05</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">overlay</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span> +</span></pre> +</div> +<div class="section" id="playlist-handling"> +<h4>Playlist handling</h4> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">ytdl</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_default_bindings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_vo_keyboard</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">playlist_append</span><span class="p">(</span><span class="s1">'https://youtu.be/PHIGke6Yzh8'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">playlist_append</span><span class="p">(</span><span class="s1">'https://youtu.be/Ji9qSuQapFY'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">playlist_append</span><span class="p">(</span><span class="s1">'https://youtu.be/6f78_Tf4Tdk'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">playlist_pos</span> <span class="o">=</span> <span class="mi">0</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">while</span> <span class="kc">True</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># To modify the playlist, use player.playlist_{append,clear,move,remove}. player.playlist is read-only</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">print</span><span class="p">(</span><span class="n">player</span><span class="o">.</span><span class="n">playlist</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">player</span><span class="o">.</span><span class="n">wait_for_playback</span><span class="p">()</span> +</span></pre> +</div> +<div class="section" id="directly-feeding-mpv-data-from-python"> +<h4>Directly feeding mpv data from python</h4> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="nd">@player</span><span class="o">.</span><span class="n">python_stream</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">reader</span><span class="p">():</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'test.webm'</span><span class="p">,</span> <span class="s1">'rb'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">yield</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s1">'python://foo'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">wait_for_playback</span><span class="p">()</span> +</span></pre> +</div> +<div class="section" id="using-external-subtitles"> +<h4>Using external subtitles</h4> +<p>The easiest way to load custom subtitles from a file is to pass the <tt class="docutils literal"><span class="pre">--sub-file</span></tt> option to the <tt class="docutils literal">loadfile</tt> call:</p> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">loadfile</span><span class="p">(</span><span class="s1">'test.webm'</span><span class="p">,</span> <span class="n">sub_file</span><span class="o">=</span><span class="s1">'test.srt'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">wait_for_playback</span><span class="p">()</span> +</span></pre> +<p>Note that you can also pass many other options to <tt class="docutils literal">loadfile</tt>. See the mpv docs for details.</p> +<p>If you want to add subtitle files or streams at runtime, you can use the <tt class="docutils literal"><span class="pre">sub-add</span></tt> command. <tt class="docutils literal"><span class="pre">sub-add</span></tt> can only be +called once the player is done loading the file and starts playing. An easy way to wait for this is to wait for the +<tt class="docutils literal"><span class="pre">core-idle</span></tt> property.</p> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s1">'test.webm'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">wait_until_playing</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">sub_add</span><span class="p">(</span><span class="s1">'test.srt'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">wait_for_playback</span><span class="p">()</span> +</span></pre> +</div> +<div class="section" id="using-mpv-s-built-in-gui"> +<h4>Using MPV's built-in GUI</h4> +<p>python-mpv is using mpv via libmpv. libmpv is meant for embedding into other applications and by default disables most +GUI features such as the OSD or keyboard input. To enable the built-in GUI, use the following options when initializing +the MPV instance. See <a class="reference external" href="https://github.com/jaseg/python-mpv/issues/61">Issue 102</a> for more details</p> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="c1"># Enable the on-screen controller and keyboard shortcuts</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">input_default_bindings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_vo_keyboard</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">osc</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c1"># Alternative version using the old "floating box" style on-screen controller</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">player_operation_mode</span><span class="o">=</span><span class="s1">'pseudo-gui'</span><span class="p">,</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">script_opts</span><span class="o">=</span><span class="s1">'osc-layout=box,osc-seekbarstyle=bar,osc-deadzonesize=0,osc-minmousemove=3'</span><span class="p">,</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">input_default_bindings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">input_vo_keyboard</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">osc</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> +</span></pre> +</div> +<div class="section" id="pyqt-embedding"> +<h4>PyQT embedding</h4> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">sys</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span> <span class="nn">PyQt5.QtWidgets</span> <span class="kn">import</span> <span class="o">*</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span> <span class="nn">PyQt5.QtCore</span> <span class="kn">import</span> <span class="o">*</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">class</span> <span class="nc">Test</span><span class="p">(</span><span class="n">QMainWindow</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parent</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">parent</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">container</span> <span class="o">=</span> <span class="n">QWidget</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">setCentralWidget</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">container</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">container</span><span class="o">.</span><span class="n">setAttribute</span><span class="p">(</span><span class="n">Qt</span><span class="o">.</span><span class="n">WA_DontCreateNativeAncestors</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">container</span><span class="o">.</span><span class="n">setAttribute</span><span class="p">(</span><span class="n">Qt</span><span class="o">.</span><span class="n">WA_NativeWindow</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">wid</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">container</span><span class="o">.</span><span class="n">winId</span><span class="p">())),</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">vo</span><span class="o">=</span><span class="s1">'x11'</span><span class="p">,</span> <span class="c1"># You may not need this</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">log_handler</span><span class="o">=</span><span class="nb">print</span><span class="p">,</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">loglevel</span><span class="o">=</span><span class="s1">'debug'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">player</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s1">'test.webm'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">app</span> <span class="o">=</span> <span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c1"># This is necessary since PyQT stomps over the locale settings needed by libmpv.</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="c1"># This needs to happen after importing PyQT before creating the first mpv.MPV instance.</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">locale</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">locale</span><span class="o">.</span><span class="n">setlocale</span><span class="p">(</span><span class="n">locale</span><span class="o">.</span><span class="n">LC_NUMERIC</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">win</span> <span class="o">=</span> <span class="n">Test</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">win</span><span class="o">.</span><span class="n">show</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span> +</span></pre> +</div> +<div class="section" id="pygobject-embedding"> +<h4>PyGObject embedding</h4> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">gi</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">gi</span><span class="o">.</span><span class="n">require_version</span><span class="p">(</span><span class="s1">'Gtk'</span><span class="p">,</span> <span class="s1">'3.0'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span> <span class="nn">gi.repository</span> <span class="kn">import</span> <span class="n">Gtk</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">class</span> <span class="nc">MainClass</span><span class="p">(</span><span class="n">Gtk</span><span class="o">.</span><span class="n">Window</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">super</span><span class="p">(</span><span class="n">MainClass</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">set_default_size</span><span class="p">(</span><span class="mi">600</span><span class="p">,</span> <span class="mi">400</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">"destroy"</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">on_destroy</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">widget</span> <span class="o">=</span> <span class="n">Gtk</span><span class="o">.</span><span class="n">Frame</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">widget</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">show_all</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># Must be created >after< the widget is shown, else property 'window' will be None</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">mpv</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">wid</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">widget</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="s2">"window"</span><span class="p">)</span><span class="o">.</span><span class="n">get_xid</span><span class="p">()))</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">mpv</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s2">"test.webm"</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span> <span class="nf">on_destroy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">widget</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">mpv</span><span class="o">.</span><span class="n">terminate</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">Gtk</span><span class="o">.</span><span class="n">main_quit</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># This is necessary since like Qt, Gtk stomps over the locale settings needed by libmpv.</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># Like with Qt, this needs to happen after importing Gtk but before creating the first mpv.MPV instance.</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="kn">import</span> <span class="nn">locale</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">locale</span><span class="o">.</span><span class="n">setlocale</span><span class="p">(</span><span class="n">locale</span><span class="o">.</span><span class="n">LC_NUMERIC</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">)</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">application</span> <span class="o">=</span> <span class="n">MainClass</span><span class="p">()</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">Gtk</span><span class="o">.</span><span class="n">main</span><span class="p">()</span> +</span></pre> +</div> +<div class="section" id="using-opengl-from-pygobject"> +<h4>Using OpenGL from PyGObject</h4> +<p>Just like it is possible to render into a GTK widget through X11 windows, it <a class="reference external" href="https://gist.github.com/jaseg/657e8ecca3267c0d82ec85d40f423caa">also is possible to render into a GTK +widget using OpenGL</a> through this python API.</p> +</div> +<div class="section" id="using-opengl-from-pyqt5-qml"> +<h4>Using OpenGL from PyQt5/QML</h4> +<p><a class="reference external" href="https://gitlab.com/robozman">Robozman</a> has mangaed to <a class="reference external" href="https://gitlab.com/robozman/python-mpv-qml-example">make mpv render into a PyQt5/QML widget using OpenGL</a> through this python API.</p> +</div> +<div class="section" id="using-mpv-inside-imgui-inside-opengl-via-glfw"> +<h4>Using mpv inside imgui inside OpenGL via GLFW</h4> +<p><a class="reference external" href="https://github.com/dfaker">dfaker</a> has written a demo (<a class="reference external" href="https://github.com/dfaker/imgui_glfw_pythonmpv_demo/blob/main/main.py">link</a>) that uses mpv to render video into an <a class="reference external" href="https://github.com/ocornut/imgui">imgui</a> UI running on an OpenGL context inside <a class="reference external" href="https://www.glfw.org/">GLFW</a>. Check out their demo to see how to integrate with imgui/OpenGL and how to access properties and manage the lifecycle of an MPV instance.</p> +</div> +</div> +</div> +<div class="section" id="running-tests"> +<h2>Running tests</h2> +<p>Use pytest to run tests.</p> +</div> +<div class="section" id="coding-conventions"> +<h2>Coding Conventions</h2> +<p>The general aim is <a class="reference external" href="https://www.python.org/dev/peps/pep-0008/">PEP 8</a>, with liberal application of the "consistency" section. 120 cells line width. Four spaces. +No tabs. Probably don't bother making pure-formatting PRs except if you think it <em>really</em> helps readability or it +<em>really</em> irks you if you don't.</p> +</div> +<div class="section" id="license"> +<h2>License</h2> +<p>python-mpv inherits the underlying libmpv's license, which can be either GPLv2 or later (default) or LGPLv2.1 or later. +For details, see <a class="reference external" href="https://github.com/mpv-player/mpv/blob/master/Copyright">the mpv copyright page</a>.</p> +</div> +</div> + </main><footer> + Copyright © 2023 Jan Sebastian Götte + / <a href="/about/">About</a> + / <a href="/imprint/">Imprint</a> +</footer> +<script> + if(navigator.getEnvironmentIntegrity!==undefined)document.querySelector('body').innerHTML=`<h1>Your browser + contains Google DRM</h1>"Web Environment Integrity" is a Google euphemism for a DRM that is designed to + prevent ad-blocking, and which Google has forced into their browsers against widespread public opposition. + In support of an open web, this website does not function with this DRM. Please install a browser such + as <a href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a> that respects your freedom and supports + ad blockers.`; + </script> + </body> +</html> |