mirror of https://github.com/zedeus/nitter
fmt, cleanup, add min observer threshold
This commit is contained in:
parent
5cb82a2520
commit
67156e56a8
|
@ -1,89 +1,79 @@
|
||||||
// @license http://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
|
// @license http://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
(function() {
|
(function() {
|
||||||
'use strict'
|
'use strict';
|
||||||
|
|
||||||
const thresholdLower = 0.8
|
const m3u8 = 'application/vnd.apple.mpegurl';
|
||||||
const thresholdUpper = 0.9
|
const thresholds = [ 0.1, 0.9 ]; // check viewport at 10% and 90%
|
||||||
const videoConfig = {
|
const videoConfig = { controls: true, oldRatio: 0, visible: true };
|
||||||
controls: true,
|
|
||||||
oldRatio: 0.0,
|
|
||||||
viewportChange: false
|
|
||||||
}
|
|
||||||
const videoObserver = new IntersectionObserver(onViewportChange, {
|
|
||||||
threshold: [thresholdLower, thresholdUpper]
|
|
||||||
})
|
|
||||||
|
|
||||||
function isMostlyInView(entry) {
|
const observer = new IntersectionObserver(observeEntries, { threshold: thresholds });
|
||||||
return entry.intersectionRatio > thresholdUpper
|
|
||||||
|
function isMostlyInView(currRatio) {
|
||||||
|
return (currRatio > thresholds[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLeavingView(entry, video) {
|
function isLeavingView(currRatio, oldRatio) {
|
||||||
return entry.intersectionRatio >= thresholdLower && video.oldRatio > entry.intersectionRatio
|
return (oldRatio > currRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/36803176
|
// is paused -> https://stackoverflow.com/questions/36803176
|
||||||
function isPlaying(video) {
|
function isVideoPaused(video) {
|
||||||
return video.currentTime > 0 && !video.paused && !video.ended && video.readyState > video.HAVE_CURRENT_DATA
|
return (video.paused || video.ended || video.readyState < video.HAVE_CURRENT_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
function observeVideo(video) {
|
function loadVideo(video) {
|
||||||
videoObserver.observe(video)
|
Object.assign(video, videoConfig);
|
||||||
video.addEventListener('pause', (evt) => {
|
return video.play();
|
||||||
video.viewportChange
|
|
||||||
? (videoObserver.observe(video), video.viewportChange = false)
|
|
||||||
: videoObserver.unobserve(video)
|
|
||||||
})
|
|
||||||
video.addEventListener('play', (evt) => {
|
|
||||||
videoObserver.observe(video)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayVideo(overlay, video) {
|
function observeEntries(entries) {
|
||||||
overlay.style.display = 'none'
|
|
||||||
Object.assign(video, videoConfig)
|
|
||||||
video.play().then(() => observeVideo(video))
|
|
||||||
}
|
|
||||||
|
|
||||||
function onViewportChange(entries) {
|
|
||||||
entries.forEach((entry) => {
|
entries.forEach((entry) => {
|
||||||
const video = entry.target
|
const video = entry.target;
|
||||||
if (isMostlyInView(entry) && !isPlaying(video)) {
|
|
||||||
video.play()
|
const inView = isMostlyInView(entry.intersectionRatio)
|
||||||
} else if (
|
const isPaused = isVideoPaused(video)
|
||||||
!isMostlyInView(entry) &&
|
|
||||||
isLeavingView(entry, video) &&
|
if (inView && isPaused) video.play();
|
||||||
isPlaying(video)
|
else if (!inView && !isPaused && isLeavingView(entry.intersectionRatio, video.oldRatio)) {
|
||||||
) {
|
video.visible = false;
|
||||||
video.viewportChange = true
|
video.pause();
|
||||||
video.pause()
|
|
||||||
}
|
}
|
||||||
video.oldRatio = entry.intersectionRatio
|
|
||||||
})
|
video.oldRatio = entry.intersectionRatio;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// we set the oldRatio to 0 on pauses, as we aren't observing where the viewport is
|
||||||
|
function observeVideo(video) {
|
||||||
|
observer.observe(video);
|
||||||
|
video.addEventListener('play', (evt) => observer.observe(video));
|
||||||
|
video.addEventListener('pause', (evt) => {
|
||||||
|
video.visible ? (observer.unobserve(video), video.oldRatio = 0) : (observer.observe(video), video.visible = true)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function useHLS(video, url) {
|
||||||
|
const hls = new Hls();
|
||||||
|
hls.on(Hls.Events.MEDIA_ATTACHED, () => hls.loadSource(url));
|
||||||
|
hls.on(Hls.Events.MANIFEST_PARSED, () => loadVideo(video).then(() => observeVideo(video)));
|
||||||
|
hls.attachMedia(video);
|
||||||
|
}
|
||||||
|
|
||||||
|
function useM3U8(video, url) {
|
||||||
|
video.src = url;
|
||||||
|
video.addEventListener('canplay', () => loadVideo(video));
|
||||||
}
|
}
|
||||||
|
|
||||||
window.playVideo = function(overlay) {
|
window.playVideo = function(overlay) {
|
||||||
if (!('Hls' in window)) {
|
const video = overlay.parentElement.querySelector('video');
|
||||||
console.error('ERROR: Hls not found, unable to play video!')
|
const url = video.getAttribute('data-url');
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const video = overlay.parentElement.querySelector('video')
|
if ('Hls' in window && Hls.isSupported()) useHLS(video, url);
|
||||||
const url = video.getAttribute('data-url')
|
else if (video.canPlayType(m3u8)) useM3U8(video, url);
|
||||||
|
|
||||||
if (Hls.isSupported()) {
|
overlay.style.display = 'none';
|
||||||
const hls = new Hls()
|
|
||||||
hls.attachMedia(video)
|
|
||||||
hls.on(Hls.Events.MEDIA_ATTACHED, () => {
|
|
||||||
hls.loadSource(url)
|
|
||||||
hls.on(Hls.Events.MANIFEST_PARSED, () => {
|
|
||||||
displayVideo(overlay, video)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
|
||||||
video.src = url
|
|
||||||
video.addEventListener('canplay', () => video.play())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})()
|
})()
|
||||||
// @license-end
|
// @license-end
|
||||||
|
|
Loading…
Reference in New Issue