Lazy Loading Videos und der Viewport - Vanilla JS
Lazy loading von Videos wird leider noch nicht nativ von den Browsern unterstützt und so realisiert man es halt genau so wie es früher auch für Bilder notwendig war, oder vielmehr wie es für ätere Browser noch als Fallback eingesetzt wird.
HTML:
video_lazy.htm HTML (977 Bytes) 18.04.2021 12:23
<!DOCTYPE html >
<html lang = "de" >
<head >
<meta charset = "utf-8" />
<title > Video Lazy Loading Example </title >
</head >
<body >
<video controls preload = "none" data-loading = "lazy" data-autoplay = "true" data-poster = "/media/video/sammy.jpg" title = "Sammy geht baden" data-description = "Ein Beispiel-Video zur Demonstration der Einbindung." data-uploaddate = "30.12.2018" width = "100%" >
<source type = "video/mp4" src = "/media/video/sammy-426x240.mp4" />
<source type = "video/mp4" data-src = "/media/video/sammy-640x360.mp4" data-media = "(min-width: 640px)" />
<source type = "video/mp4" data-src = "/media/video/sammy-854x480.mp4" data-media = "(min-width: 854px)" />
<source type = "video/mp4" data-src = "/media/video/sammy-1280x720.mp4" data-media = "(min-width: 1280px)" />
<source type = "video/mp4" data-src = "/media/video/sammy-1920x1080.mp4" data-media = "(min-width: 1920px)" />
</video >
<script src = "video_lazy.js" > </script >
</body >
</html >
JavaScript:
video_lazy.js JavaScript (4,48 kByte) 08.04.2021 23:59
(function () {
'use strict' ;
function loadVideo(el) {
if (el.dataset.poster) {
el.setAttribute('poster' , el.dataset.poster);
el.removeAttribute('data-poster' );
}
var childs = el.children;
for (var i = 0 ; i < childs.length; i++ ) {
if ((childs[i].tagName.toLowerCase() == 'source' ) && childs[i].dataset.src) {
childs[i].src = childs[i].dataset.src;
childs[i].removeAttribute('data-src' );
}
}
if (el.dataset.controls && el.dataset.controls == 'true' ) {
el.setAttribute('controls' , '' );
el.removeAttribute('data-controls' );
}
el.setAttribute('preload' , 'auto' );
el.load();
if (el.dataset.autoplay && el.dataset.autoplay == 'true' ) {
el.removeAttribute('data-autoplay' );
el.setAttribute('autoplay' , 'autoplay' );
el.autoplay = true ;
el.play();
}
}
function Viewport(els, callback) {
this .els = els;
this .callback = callback;
this .active = false ;
var self = this ;
var hidden = [];
function alreadyObserved(el) {
for (var i= 0 ; i< hidden.length; i++ ) {
if (el === hidden[i]) {
return true ;
}
}
return false ;
}
for (var i= 0 ; i < els.length; i++ ) {
var el = els[i];
let properties = window .getComputedStyle( el.parentNode);
if (! properties.getPropertyValue('position' )) {
el.parentNode.style.position = 'relative' ;
while (el && el.tagName.toLowerCase() !== 'body' ) {
if (window .getComputedStyle( el).display === "none" ) {
if (! alreadyObserved(el)) {
hidden.push(el);
var observer = new MutationObserver(function (mutations) {
if (mutations[0 ].target.style.display !== 'none' ) {
self.handleEvent();
}
});
observer.observe(el, { attributes: true });
break ;
}
}
el = el.parentNode;
}
}
}
this .handleEvent.bind(this );
function ready(f){
/ complete| loaded/ i.test(document .readyState) ? f() : setTimeout(function (){ready(f);},9);
}
ready(function (){self.handleEvent();});
document .addEventListener( 'scroll' , this , true );
window .addEventListener( 'resize' , this , true );
window .addEventListener( 'orientationchange' , this , true );
}
Viewport.prototype = {
isVisible: function (el) {
var style = window .getComputedStyle( el);
return ! ! (el.offsetWidth || el.offsetHeight || el.getClientRects().length);
},
isInViewport: function (el) {
var bounding = el.getBoundingClientRect();
return (
bounding.bottom >= 0 &&
bounding.right >= 0 &&
bounding.top <= (window .innerHeight || document .documentElement.clientHeight) &&
bounding.left <= (window .innerWidth || document .documentElement.clientWidth)
);
},
handleEvent: function () {
if (this .active === false ) {
this .active = true ;
for (var i= 0 ; i < this .els.length; i++ ) {
if (this .isInViewport(this .els[i]) && this .isVisible(this .els[i])) {
this .callback(this .els[i]);
}
}
this .active = false ;
}
}
};
var videos = document .querySelectorAll( "video[data-loading='lazy']" );
if (videos.length > 0 ) {
if ("IntersectionObserver" in window ) {
let lazyobserver = new IntersectionObserver(function (entries, observer) {
for (var i= 0 ; i < entries.length; i++ ) {
if (entries[i].isIntersecting) {
loadVideo(entries[i].target);
lazyobserver.unobserve(entries[i].target);
}
}
},
{
threshold: [0.1 ],
delay: 100
});
for (var i= 0 ; i < videos.length; i++ ) {
lazyobserver.observe(videos[i]);
}
} else {
new Viewport(videos, loadVideo);
}
}
})();
Video.js - HTML5 Video Player
Hier nun eine simple Implementierung des HTML5 Video-Tags mit Flash Fallback . Mehr Infos unter https://videojs.com/ .
To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video
Damit das Video auch auf dem iPad läuft müss auf die richtigen Einstellungen beim Encoden geachtet werden:
H.264 Baseline Profile Level 3.0
Auflösung unter 640 x 480 und Frameraten bis 30 Frames/Sec
keine B Frames
Bitraten bis 900kb
video.htm HTML (1,42 kByte) 21.08.2023 07:33
<!DOCTYPE html >
<html >
<head >
<title > Video.js | HTML5 Video Player </title >
<meta http-equiv = "Content-Security-Policy" content = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: " />
<link href = "/code/video-js/video-js.css" rel = "stylesheet" type = "text/css" />
<script src = "/code/video-js/video.js" > </script >
<script >
videojs.options.flash.swf = "/code/video-js/video-js.swf" ;
</script >
</head >
<body >
<video id = "example_video_1" class = "video-js vjs-default-skin vjs-big-play-centered" controls preload = "auto" width = "640" height = "360" poster = "/media/video/sammy.png" data-setup = "{}" >
<source src = "/media/video/sammy.mp4" type = "video/mp4" />
<source src = "/media/video/sammy.webm" type = "video/webm" />
<source src = "/media/video/sammy.ogv" type = "video/ogg" />
<track kind = "captions" src = "/media/video/sammy.de.vtt" srclang = "de" label = "Deutsch" />
<p class = "vjs-no-js" > To view this video please enable JavaScript, and consider upgrading to a web browser that <a href = "http://videojs.com/html5-video-support/" target = "_blank" > supports HTML5 video </a > </p >
</video >
</body >
</html >