summaryrefslogtreecommitdiff
path: root/projects/python-mpv/index.html
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2023-12-30 13:44:17 +0100
committerjaseg <git@jaseg.de>2023-12-30 13:44:17 +0100
commit58d54c5debedca8c91b28026f520b226ac8682f6 (patch)
tree672eb9d0b345ddada80eed512916b4ffd9f68406 /projects/python-mpv/index.html
parentb357b505257e460d41aef80550693c810780b7fc (diff)
parent3ab2c03e01264a9c6e262feef6a7188cb8b30775 (diff)
downloadblog-58d54c5debedca8c91b28026f520b226ac8682f6.tar.gz
blog-58d54c5debedca8c91b28026f520b226ac8682f6.tar.bz2
blog-58d54c5debedca8c91b28026f520b226ac8682f6.zip
deploy.py auto-commit
Diffstat (limited to 'projects/python-mpv/index.html')
-rw-r--r--projects/python-mpv/index.html408
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..037e1d8
--- /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 &gt;= 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 &quot;<a class="reference external" href="https://mpv.io/manual/master/#list-of-input-commands">input commands</a>&quot; 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">&#64;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">&#64;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">&#64;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">&#64;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 &quot;floating box&quot; 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">&quot;destroy&quot;</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 &gt;after&lt; 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">&quot;window&quot;</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">&quot;test.webm&quot;</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 &quot;consistency&quot; 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>