/PiPer

Browser extension that adds Picture in Picture support to YouTube, Netflix, Amazon Video, Twitch, Plex, and more!

Primary LanguageJavaScriptGNU General Public License v3.0GPL-3.0

PiPer logo

PiPer

PiPer is the browser extension to watch video Picture in Picture.

Install · Donate · Report an issue


Contents

Features

  • Adds a dedicated Picture in Picture button to the video player of supported sites
  • Button integrates seamlessly with the player including hover effects and tooltips
  • Supports closed captions in Picture and Picture mode (Safari only)
  • Supports Safari and Chrome
  • Free and open source

Installation

Safari

Install from the Mac App Store by clicking "Get"
(The Safari Extension Gallery is now deprecated)

Chrome

Install from the Chrome Web Store by clicking "Add to Chrome"

...or live life on the edge with the latest development build (IMPORTANT: these builds do not update automatically!)

Supported sites

Changelog

You can find information about releases here

Development

Building

Prerequisites

  • Operating system
    • macOS: 10.12 Sierra or newer (required to build Safari extension)
    • Windows: Vista or newer using Cygwin
    • Linux: 64-bit Ubuntu 14.04+, Debian 8+, openSUSE 13.3+, or Fedora Linux 24+
  • Software

Build tools

The following build tools are used to build the extension:

These can be installed by executing the following command:

npm install -g csso-cli svgo xar-js google-closure-compiler

Steps

  1. Clone the repository
  2. Run make.sh
    1. By default this builds the unoptimized and unpackaged development version for all targets into the ./out/ directory
    2. Alternatively:
      • ./make.sh -p release to build the optimized release versions for all targets
      • ./make.sh -p release -t chrome to build the optimized release version for the Chrome browser
      • ./make.sh -h to see the full list of options

Supporting a new site

If we wanted to support example.com with the source:

<div class="video-container">
  <video src="blob:http://example.com/342b3a13-c892-54ec-84f6-281579de03ab"></video>
  <div class="video-captions">
    Example caption
  </div>
  <div class="video-controls">
    <button class="control button-play">Play</button>
    <button class="control button-fullscreen">Fullscreen</button>
  </div>
</div>

We would start by adding a new file example.js in the resources directory:

export const domain = 'example';

export const resource = {
  buttonParent: function() {
    // Returns the element that will contain the button
    return document.querySelector('.video-controls');
  },
  videoElement: function() {
    // Returns the video element
    return document.querySelector('.video-container video');
  },
  
  // Optional
  captionElement: function() {
    // Returns the element that contains the video captions
    return document.querySelector('.video-captions');
  },
};

We might want to style the button so that it integrates with the page better:

export const resource = {
  ...
  // Assign a CSS class
  buttonClassName: 'control',
  // Scale the button
  buttonScale: 0.5,
  // Apply custom CSS styles
  buttonStyle: /** CSS */ (`
    /* Declaring CSS this way ensures it gets optimized when the extension is built */
    cursor: pointer;
    opacity: 0.5;
  `),
  // Apply a custom CSS hover style
  buttonHoverStyle: /** CSS */ (`opacity: 1 !important`),
};

For more examples, please see the source

Acknowledgements