Skip to content

Commit 907fa00

Browse files
authored
Merge pull request #84 from amarcu5/develop-1.0.x
v1.0.3
2 parents 786d1bc + a3c38e4 commit 907fa00

16 files changed

Lines changed: 188 additions & 28 deletions

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ Install from the [Chrome Web Store](https://chrome.google.com/webstore/detail/pi
5252
## Supported sites
5353
* [9Now](http://www.9now.com.au)
5454
* [Amazon Video](http://www.amazon.com/PrimeVideo)
55+
* [Česká televize](http://www.ceskatelevize.cz)
5556
* [CollegeHumor](http://www.collegehumor.com)
57+
* [Crunchyroll](http://www.crunchyroll.com)
5658
* [CuriosityStream](http://www.curiositystream.com)
5759
* [Eurosport player](http://www.eurosportplayer.com)
5860
* [FuboTV](http://www.fubo.tv)
@@ -82,6 +84,7 @@ Install from the [Chrome Web Store](https://chrome.google.com/webstore/detail/pi
8284
* [Video Aktálně](http://video.aktualne.cz)
8385
* [Vier](http://www.vier.be)
8486
* [Vijf](http://www.vijf.be)
87+
* [VK](http://www.vk.com)
8588
* [VRV](http://www.vrv.co)
8689
* [VRT NU](http://www.vrt.be/vrtnu/)
8790
* [Yelo Play](http://www.yeloplay.be)

out/PiPer-chrome.zip

606 Bytes
Binary file not shown.

out/PiPer-safari-legacy.safariextz

496 Bytes
Binary file not shown.

out/PiPer-safari.pkg

-78.3 KB
Binary file not shown.

src/common/scripts/captions.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const enableCaptions = function(ignoreNowPlayingCheck) {
4141
const video = /** @type {?HTMLVideoElement} */ (getResource().videoElement(true));
4242
if (!video) return;
4343
showingCaptions = videoPlayingPictureInPicture(video);
44-
prepareCaptions(video);
44+
track = getCaptionTrack(video);
4545
processCaptions();
4646
};
4747

@@ -55,27 +55,35 @@ export const shouldProcessCaptions = function() {
5555
};
5656

5757
/**
58-
* Prepares video for captions
58+
* Gets caption track for video (creates or returns existing track as needed)
5959
*
6060
* @param {HTMLVideoElement} video - video element that will display captions
61+
* @return {TextTrack}
6162
*/
62-
const prepareCaptions = function(video) {
63+
const getCaptionTrack = function(video) {
6364

6465
// Find existing caption track
65-
track = null;
6666
const allTracks = video.textTracks;
6767
for (let trackId = allTracks.length; trackId--;) {
6868
if (allTracks[trackId].label === TRACK_ID) {
69-
track = allTracks[trackId];
7069
info('Existing caption track found');
71-
break;
70+
return allTracks[trackId];
7271
}
7372
}
74-
if (track) return;
7573

7674
// Otherwise create new caption track
7775
info('Caption track created');
78-
track = video.addTextTrack('captions', TRACK_ID, 'en');
76+
return video.addTextTrack('captions', TRACK_ID, 'en');
77+
};
78+
79+
/**
80+
* Adds caption tracks to all video elements
81+
*/
82+
export const addVideoCaptionTracks = function() {
83+
const elements = document.getElementsByTagName('video');
84+
for (let index = 0, element; element = elements[index]; index++) {
85+
getCaptionTrack(/** @type {?HTMLVideoElement} */ (element));
86+
}
7987
};
8088

8189
/**
@@ -88,7 +96,10 @@ const pictureInPictureEventListener = function(video, isPlayingPictureInPicture)
8896

8997
// Toggle display of the captions and prepare video if needed
9098
showingCaptions = isPlayingPictureInPicture;
91-
if (showingCaptions) prepareCaptions(video);
99+
if (showingCaptions) {
100+
track = getCaptionTrack(video);
101+
track.mode = 'showing';
102+
}
92103
lastUnprocessedCaption = '';
93104
processCaptions();
94105

src/common/scripts/fix.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { info } from './logger.js'
2+
import { videoPlayingPictureInPicture } from './video.js'
23

34
let activeVideo = null;
45
let timeoutId = 0;
@@ -107,7 +108,7 @@ const bypassBackgroundTimerThrottling = function() {
107108
const allVideos = document.querySelectorAll('video');
108109
for (let videoId = allVideos.length; videoId--;) {
109110
const video = /** @type {?HTMLVideoElement} */ (allVideos[videoId]);
110-
if (video.webkitPresentationMode == 'picture-in-picture') {
111+
if (videoPlayingPictureInPicture(video)) {
111112
activeVideo = video;
112113
break;
113114
}

src/common/scripts/main.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,26 @@ import { Browser, getBrowser, getResource, setResource } from './common.js'
33
import { addVideoElementListeners } from './video.js'
44
import { resources } from './resources/index.js';
55
import { checkButton, addButton } from './button.js'
6-
import { shouldProcessCaptions, enableCaptions, processCaptions } from './captions.js'
6+
import { shouldProcessCaptions, enableCaptions, processCaptions, addVideoCaptionTracks } from './captions.js'
77
import { initialiseCaches } from './cache.js'
88

99
/**
1010
* Tracks injected button and captions
1111
*/
1212
const mutationObserver = function() {
13+
const currentResource = getResource();
1314

1415
// Process video captions if needed
1516
if (shouldProcessCaptions()) processCaptions();
1617

1718
// Workaround Chrome's lack of an entering Picture in Picture mode event by monitoring all video elements
1819
if (getBrowser() == Browser.CHROME) addVideoElementListeners();
1920

21+
// Workaround Safari bug; captions are not displayed if the track is added after the video has loaded
22+
if (getBrowser() == Browser.SAFARI && currentResource.captionElement) addVideoCaptionTracks();
23+
2024
// Try adding the button to the page if needed
2125
if (checkButton()) return;
22-
const currentResource = getResource();
2326
const buttonParent = currentResource.buttonParent();
2427
if (buttonParent) {
2528
addButton(buttonParent);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export const domain = 'ceskatelevize';
2+
3+
export const resource = {
4+
buttonClassName: 'videoButtonShell dontHideControls cursorPointer focusableBtn',
5+
buttonElementType: 'div',
6+
buttonHoverStyle: /** CSS */ (`
7+
filter: brightness(50%) sepia(1) hue-rotate(170deg) saturate(250%) brightness(90%);
8+
`),
9+
buttonInsertBefore: function(/** Element */ parent) {
10+
return document.getElementById('fullScreenShell');
11+
},
12+
buttonScale: 1.2,
13+
buttonStyle: /** CSS */ (`
14+
width: 18px;
15+
height: 18px;
16+
display: inline-block;
17+
`),
18+
buttonParent: function() {
19+
return document.getElementById('videoButtons');
20+
},
21+
videoElement: function() {
22+
return document.getElementById('video');
23+
},
24+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export const domain = 'crunchyroll';
2+
3+
export const resource = {
4+
buttonClassName: 'vjs-control vjs-button',
5+
buttonHoverStyle: /** CSS */ (`opacity: 1 !important`),
6+
buttonScale: 0.6,
7+
buttonStyle: /** CSS */ (`
8+
position: absolute;
9+
right: 100px;
10+
opacity: 0.75;
11+
cursor: pointer;
12+
`),
13+
buttonParent: function() {
14+
return document.querySelector('.vjs-control-bar');
15+
},
16+
videoElement: function() {
17+
return document.getElementById('player_html5_api');
18+
},
19+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { getButton } from './../button.js'
2+
3+
export const domain = 'espn';
4+
5+
export const resource = {
6+
buttonClassName: 'media-icon',
7+
buttonDidAppear: function() {
8+
// Get localized button title and hide default tooltip
9+
const button = getButton();
10+
const /** string */ title = button.title;
11+
button.title = '';
12+
13+
// Create stylized tooltip and add to DOM
14+
const tooltip = /** @type {HTMLElement} */ (document.createElement('div'));
15+
tooltip.className = 'control-tooltip';
16+
tooltip.style.cssText = /** CSS */ (`
17+
right: 0px;
18+
bottom: 35px;
19+
transition: bottom 0.2s ease-out;
20+
`);
21+
tooltip.textContent = title;
22+
button.appendChild(tooltip);
23+
24+
// Display stylized tooltip on mouseover
25+
button.addEventListener('mouseover', function() {
26+
button.classList.add('displaying');
27+
tooltip.style.bottom = '75px';
28+
});
29+
button.addEventListener('mouseout', function() {
30+
button.classList.remove('displaying');
31+
tooltip.style.bottom = '35px';
32+
});
33+
},
34+
buttonElementType: 'div',
35+
buttonInsertBefore: function(/** Element */ parent) {
36+
return parent.lastChild;
37+
},
38+
buttonParent: function() {
39+
return document.querySelector('.controls-right-horizontal');
40+
},
41+
buttonScale: 0.7,
42+
buttonStyle: /** CSS */ (`
43+
width: 44px;
44+
height: 44px;
45+
order: 4;
46+
`),
47+
captionElement: function() {
48+
return document.querySelector('.text-track-display');
49+
},
50+
videoElement: function() {
51+
return document.querySelector('video.js-video-content');
52+
},
53+
};

0 commit comments

Comments
 (0)