Skip to content

Commit

Permalink
Merge pull request #59 from amarcu5/develop
Browse files Browse the repository at this point in the history
v0.2.5
  • Loading branch information
amarcu5 authored Aug 6, 2018
2 parents 8fb4ea3 + 771b041 commit 8145d00
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 42 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ Adds Picture in Picture functionality to Safari for YouTube, Netflix, Amazon Vid

<img src="/promo/Promo-shot.png" alt="Screenshot of PiPer in action" width="512" />

## Contents
- [Features](#features)
- [Installation](#installation)
- [Supported sites](#supported-sites)
- [Changelog](#changelog)
- [Development](#development)
* [Building](#building)
+ [Prerequisites](#prerequisites)
+ [Build tools](#build-tools)
+ [Steps](#steps)
* [Supporting a new site](#supporting-a-new-site)
- [Acknowledgements](#acknowledgements)

## Features
* Adds a dedicated Picture in Picture button to the video player of [supported sites](#supported-sites)
* Button integrates seamlessly with the player including hover effects and tooltips
Expand All @@ -25,6 +38,7 @@ Get the latest release from the [Safari Extension Gallery](https://safari-extens
* [Mashable](http://www.mashable.com)
* [Metacafe](http://www.metacafe.com)
* [Mixer](http://mixer.com)
* [MLB](http://www.mlb.tv)
* [Netflix](http://www.netflix.com)
* [OCS](http://www.ocs.fr)
* [Openload](http://www.openload.co)
Expand All @@ -33,15 +47,21 @@ Get the latest release from the [Safari Extension Gallery](https://safari-extens
* [Seznam Zprávy](http://www.seznam.cz/zpravy)
* [Stream.cz](http://www.stream.cz)
* [Streamable](http://streamable.com)
* [TED](http://www.ted.com)
* [The Onion](http://www.theonion.com)
* [Twitch](http://www.twitch.tv)
* [Udemy](http://www.udemy.com)
* [Vevo](http://www.vevo.com)
* [Vice](http://www.vice.com)
* [Vid.me](http://www.vid.me)
* [Video Aktálně](http://video.aktualne.cz)
* [Vier](http://www.vier.be)
* [Vijf](http://www.vijf.be)
* [VRV](http://www.vrv.co)
* [VRT NU](http://www.vrt.be/vrtnu/)
* [Yelo Play](http://www.yeloplay.be)
* [YouTube](http://www.youtube.com)
* [Zes](http://www.zes.be)

## Changelog
You can find information about releases [here](https://github.com/amarcu5/PiPer/releases)
Expand Down
Binary file modified out/PiPer.safariextz
Binary file not shown.
16 changes: 16 additions & 0 deletions src/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
<string>*.metacafe.com</string>
<string>mixer.com</string>
<string>*.mixer.com</string>
<string>mlb.com</string>
<string>*.mlb.com</string>
<string>mlb.tv</string>
<string>*.mlb.tv</string>
<string>netflix.com</string>
<string>*.netflix.com</string>
<string>ocs.fr</string>
Expand All @@ -92,6 +96,8 @@
<string>*.stream.cz</string>
<string>streamable.com</string>
<string>*.streamable.com</string>
<string>ted.com</string>
<string>*.ted.com</string>
<string>theonion.com</string>
<string>*.theonion.com</string>
<string>twitch.tv</string>
Expand All @@ -104,12 +110,22 @@
<string>*.vice.com</string>
<string>vid.me</string>
<string>*.vid.me</string>
<string>vier.be</string>
<string>*.vier.be</string>
<string>vijf.be</string>
<string>*.vijf.be</string>
<string>vrt.be</string>
<string>*.vrt.be</string>
<string>vrv.co</string>
<string>*.vrv.co</string>
<string>yeloplay.be</string>
<string>*.yeloplay.be</string>
<string>youtu.be</string>
<string>*.youtu.be</string>
<string>youtube.com</string>
<string>*.youtube.com</string>
<string>zes.be</string>
<string>*.zes.be</string>
</array>
<key>Include Secure Pages</key>
<true/>
Expand Down
76 changes: 53 additions & 23 deletions src/scripts/fix.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@

let activeVideo = null;
let timeoutId = 0;
let timeouts = {};

const requests = [];
const callbacks = [];
const timeouts = [];

const originalRequestAnimationFrame = window.requestAnimationFrame;
const originalSetTimeout = window.setTimeout;
const originalClearTimeout = window.clearTimeout;
const originalRequestAnimationFrame = window.requestAnimationFrame;

/**
* Tracks animation frame requests and forwards requests when page visible
*/
const trackAnimationFrameRequest = function(callback) {
let request = 0;

if (!document.hidden) {
if (!activeVideo) {
request = originalRequestAnimationFrame(callback);
requests.push(request);
}
Expand All @@ -43,41 +44,63 @@
* Calls tracked animation frame requests and timeouts
*/
const callAnimationFrameRequestsAndTimeouts = function() {

// Copy animation frame callbacks before calling to prevent endless looping
const callbacksCopy = callbacks.slice();
callbacks.length = 0;

// Call animation frame requests
const timestamp = window.performance.now();
for (let callback; callback = callbacksCopy.pop();) {
callback(timestamp);
};

const timeoutsCopy = timeouts.slice();
timeouts.length = 0;
}

for (let timeout; timeout = timeoutsCopy.pop();) {
timeout();
};
// Copy timeouts to prevent endless looping
const timeoutsCopy = timeouts;
timeouts = {};

// Call elapsed timeouts
for (let id in timeoutsCopy) {
let timeout = timeoutsCopy[id];
if (timeout[0] <= timestamp) {
if (typeof timeout[1] == "function") {
timeout[1]();
} else {
eval(/** @type {string} */ (timeout[1]));
}
} else {
timeouts[id] = timeout;
}
}
};

/**
* Avoids background throttling by invoking small timeouts with media 'timeupdate' events
* Avoids background throttling by invoking timeouts with media 'timeupdate' events
*
* @param {Function|string} callback
* @param {number=} timeout
* @return {number}
*/
const unthrottledSetTimeout = function(callback, timeout) {
if (timeout >= 500) return originalSetTimeout(callback, timeout);

timeouts.push(callback);
const id = timeoutId++;
timeouts[id] = [window.performance.now() + (timeout || 0), callback];
return id;
};

return timeoutId++;
/**
* Clears queued timeouts to be invoked with media 'timeupdate' events
*
* @param {?number|undefined} id
*/
const unthrottledClearTimeout = function(id) {
delete timeouts[id];
};

/**
* Bypasses background timer throttling when video playing picture in picture
*/
const bypassBackgroundTimerThrottling = function() {

if (document.hidden) {

const allVideos = document.querySelectorAll('video');
Expand All @@ -95,23 +118,30 @@
}

window.setTimeout = unthrottledSetTimeout;
window.clearTimeout = unthrottledClearTimeout;

activeVideo.addEventListener('timeupdate', callAnimationFrameRequestsAndTimeouts);

} else if (activeVideo) {

window.setTimeout = originalSetTimeout;
window.clearTimeout = originalClearTimeout;

activeVideo.removeEventListener('timeupdate', callAnimationFrameRequestsAndTimeouts);

activeVideo = null;

for (let callbackId = callbacks.length; callbackId--;) {
let request = originalRequestAnimationFrame(callbacks[callbackId]);
requests.push(request);
}

window.setTimeout = originalSetTimeout;
activeVideo.removeEventListener('timeupdate', callAnimationFrameRequestsAndTimeouts);

for (let timeout; timeout = timeouts.pop();) {
timeout();
};

activeVideo = null;
const timestamp = window.performance.now();
for (let id in timeouts) {
let timeout = timeouts[id];
originalSetTimeout(timeout[1], timeout[0] - timestamp);
}
timeouts = {};
}
};
document.addEventListener('visibilitychange', bypassBackgroundTimerThrottling);
Expand Down
Loading

0 comments on commit 8145d00

Please sign in to comment.