This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan
<p><a href="https://w3c.github.io/picture-in-picture/">Picture in Picture</a> is an amazing API, it let's you keep on working in another tab but have a little playable live thumbnail of the video on the screen for you to keep up with. Yet there are a number of sites that disable the feature.</p>
<p>I just wanted a quick and easy access button that I can press in my browser that will just PIP the video. So I made a bookmarklet.</p>
<p>Just drag the link to you Bookmark bar and when you press it, the currently playing video will be put in to Picture in Picture mode.</p>
<p><a href="javascript:(function()%7B%5Bdocument%2C...%5B...document.querySelectorAll(%22iframe%22)%5D.map(iframe%20%3D%3E%20iframe.contentDocument).filter(iframe%20%3D%3E%20!!iframe)%5D.some(d%20%3D%3E%5B...d.querySelectorAll(%22video%22)%5D.filter(video%20%3D%3E%20video.paused%20%3D%3D%20false%20%26%26%20video.ended%20%3D%3D%20false).some(video%20%3D%3E%20!!video.requestPictureInPicture().catch(err%20%3D%3E%20console.log(err))))%7D)()">Quick PIP</a></p>
<p>If it tickles your fancy, the code is below.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-JavaScript" data-lang="JavaScript"><span style="color:#75715e">// dont define a variable on scope. Only pip the first video
</span><span style="color:#75715e"></span>
[
document,
...[...document.<span style="color:#a6e22e">querySelectorAll</span>(<span style="color:#e6db74">"iframe"</span>)]
.<span style="color:#a6e22e">map</span>(<span style="color:#a6e22e">iframe</span> => <span style="color:#a6e22e">iframe</span>.<span style="color:#a6e22e">contentDocument</span>)
.<span style="color:#a6e22e">filter</span>(<span style="color:#a6e22e">iframe</span> => <span style="color:#f92672">!!</span><span style="color:#a6e22e">iframe</span>)
].<span style="color:#a6e22e">some</span>(<span style="color:#a6e22e">d</span> =>
[...<span style="color:#a6e22e">d</span>.<span style="color:#a6e22e">querySelectorAll</span>(<span style="color:#e6db74">"video"</span>)]
.<span style="color:#a6e22e">filter</span>(<span style="color:#a6e22e">video</span> => <span style="color:#a6e22e">video</span>.<span style="color:#a6e22e">paused</span> <span style="color:#f92672">==</span> <span style="color:#66d9ef">false</span> <span style="color:#f92672">&&</span> <span style="color:#a6e22e">video</span>.<span style="color:#a6e22e">ended</span> <span style="color:#f92672">==</span> <span style="color:#66d9ef">false</span>)
.<span style="color:#a6e22e">some</span>(
<span style="color:#a6e22e">video</span> => <span style="color:#f92672">!!</span><span style="color:#a6e22e">video</span>.<span style="color:#a6e22e">requestPictureInPicture</span>().<span style="color:#66d9ef">catch</span>(<span style="color:#a6e22e">err</span> => <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#a6e22e">err</span>))
)
);
</code></pre></div><p>Why one line? Well, Bookmarklets run their code in the local scope, and I worry about adding new variables on to the global object that might clash with others on the current page.</p>
<p>The above code will find the first video that is playing in either the document or an iframe that is on the same origin.</p>
<p>First we build a list of valid documents, then for each document (using <code>some</code>) we check to see if there are any videos that are currently playing and then using <code>some</code> will <code>requestPictureInPicture</code>. </p>
<p>The use of <code>some</code> is interesting because it means that we don't need to iterate over each video in each document, instead the first document to contain a playing video will be Picture in Pictured.</p>
<p>That was a fun 30 minutes :D</p>
This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan