Add HLS video streaming support with multiple resolutions and WebP thumbnails
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
This commit is contained in:
parent
16393510dd
commit
b714d1a2d6
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
@ -12,10 +12,10 @@ mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div cl
|
|||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works" tabindex=0>How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research tabindex=0>Research</a>
|
||||
<a class=mdl-navigation__link href=/posts/ title=Posts tabindex=0>Posts</a>
|
||||
<a class=mdl-navigation__link href=/components/ title=Components tabindex=0>Components</a></nav></div><div class=chocolate-hero-section style=background-image:url(/images/material-bg.webp)><div class=hero-row-group><div class=hero-row><div class="hero-row-item hero-text-info"><h1 class=mdl-typography--display-3>Shower Loop</h1><h2>Open Source - Open Hardware - Ecological - Economical.</h2><p>Real-time filtration, purification, recycling & heat recovery system for showers. Made in Finland, for Earth.</p></div><div class="hero-row-item hero-video"><div class=video-container><video id=video-hero-1741459865 controls preload=none width=100% height=auto>
|
||||
<source src=/static/videos/video1.mp4 type=video/mp4><p>To view this video please enable JavaScript, and consider upgrading to a
|
||||
web browser that supports HTML5 video</p></video></div></div></div></div></div><div class=cta><div class=cta-row-group><div class=cta-row><div class=cta-row-item><p class="mdl-typography--headline mdl-typography--font-thin">Looking to make a change? Want to support the project?</p><a href=/components class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">Check Out our Components</a></div></div></div></div><main><div class=homepage-content><div class=home-introduction><div class=chocolate-container><div class=mdl-grid><div class="mdl-cell mdl-cell--12-col"><h2 class=mdl-typography--display-2>Shower Loop vs Normal Shower</h2><p class=intro-description>90% reduction in water usage and 70-90% in energy reduction for a 10 minute shower with a flow rate of 10 l/min. Savings are dependant on user behaviour and can vary. Use Just one bucket of water for a shower of any length. See the savings section for more information.</p><div class="mdl-grid reasons"><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Save Water</h3><p>Capture, Filter, Reuse</p></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Saving Energy</h3><p>By reusing warm water.</p></div></div></div><div class="mdl-grid reasons"><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Save The Planet</h3><p>Save Money</p></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Open Hardware</h3><p>Copy, improve, adapt, share</p></div></div></div><div class="mdl-grid reasons"><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Assemble It Yourself</h3><p>With manufactured and off-shell components</p></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Enjoy Better Showers</h3><p>The single pump provides stable water pressure and the thermostat and heater keep water nice and warm</p></div></div></div><div class="mdl-grid reasons"><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Off - Grid Ready</h3><p>The entire system can run on a 12V DC</p></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>No Plumber Needed</h3><p>Shower Loop is like a standalone appliance without connecting to water mains</p></div></div></div></div></div></div></div><div class=home-works><div class=mdl-grid><div class="mdl-cell mdl-cell--12-col"><h2 class="mdl-typography--display-2 section-title">How It Works</h2><p class=intro-description>Showers are great, but pouring hot and almost drinkable water down the drain is not. Besides the obvious costs to the environment and your bills, there is also a conscious on unconscious psychological cost any time you create waste. To solve this problem we created Showerloop. It's a shower that collects, cleans and reuses the water in real time while you are showering. So now you can shower for as long as you like but with a reduced ecological impact.</p><div class="mdl-grid videos" style=justify-content:center><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div class=video-container><video id=video2 controls preload=auto width=640 height=360>
|
||||
<source src=/static/videos/video2.mp4 type=video/mp4><p>To view this video please enable JavaScript, and consider upgrading to a
|
||||
web browser that supports HTML5 video</p></video></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div class=video-container><video id=video3 controls preload=auto width=640 height=360>
|
||||
<source src=/static/videos/video3.mp4 type=video/mp4><p>To view this video please enable JavaScript, and consider upgrading to a
|
||||
<a class=mdl-navigation__link href=/components/ title=Components tabindex=0>Components</a></nav></div><div class=chocolate-hero-section style=background-image:url(/images/material-bg.webp)><div class=hero-row-group><div class=hero-row><div class="hero-row-item hero-text-info"><h1 class=mdl-typography--display-3>Shower Loop</h1><h2>Open Source - Open Hardware - Ecological - Economical.</h2><p>Real-time filtration, purification, recycling & heat recovery system for showers. Made in Finland, for Earth.</p></div><div class="hero-row-item hero-video"><div class=video-container><video id=video-hero-1741460284 controls preload=none width=100% height=auto poster=/static/videos/posters/video1.webp>
|
||||
<source src=/static/videos/hls/video1/index.m3u8 type=application/x-mpegurl><source src=/static/videos/video1.mp4 type=video/mp4><p>To view this video please enable JavaScript, and consider upgrading to a
|
||||
web browser that supports HTML5 video</p></video></div></div></div></div></div><div class=cta><div class=cta-row-group><div class=cta-row><div class=cta-row-item><p class="mdl-typography--headline mdl-typography--font-thin">Looking to make a change? Want to support the project?</p><a href=/components class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">Check Out our Components</a></div></div></div></div><main><div class=homepage-content><div class=home-introduction><div class=chocolate-container><div class=mdl-grid><div class="mdl-cell mdl-cell--12-col"><h2 class=mdl-typography--display-2>Shower Loop vs Normal Shower</h2><p class=intro-description>90% reduction in water usage and 70-90% in energy reduction for a 10 minute shower with a flow rate of 10 l/min. Savings are dependant on user behaviour and can vary. Use Just one bucket of water for a shower of any length. See the savings section for more information.</p><div class="mdl-grid reasons"><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Save Water</h3><p>Capture, Filter, Reuse</p></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Saving Energy</h3><p>By reusing warm water.</p></div></div></div><div class="mdl-grid reasons"><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Save The Planet</h3><p>Save Money</p></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Open Hardware</h3><p>Copy, improve, adapt, share</p></div></div></div><div class="mdl-grid reasons"><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Assemble It Yourself</h3><p>With manufactured and off-shell components</p></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Enjoy Better Showers</h3><p>The single pump provides stable water pressure and the thermostat and heater keep water nice and warm</p></div></div></div><div class="mdl-grid reasons"><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>Off - Grid Ready</h3><p>The entire system can run on a 12V DC</p></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div><i class="far fa-lightbulb"></i></div><div><h3>No Plumber Needed</h3><p>Shower Loop is like a standalone appliance without connecting to water mains</p></div></div></div></div></div></div></div><div class=home-works><div class=mdl-grid><div class="mdl-cell mdl-cell--12-col"><h2 class="mdl-typography--display-2 section-title">How It Works</h2><p class=intro-description>Showers are great, but pouring hot and almost drinkable water down the drain is not. Besides the obvious costs to the environment and your bills, there is also a conscious on unconscious psychological cost any time you create waste. To solve this problem we created Showerloop. It's a shower that collects, cleans and reuses the water in real time while you are showering. So now you can shower for as long as you like but with a reduced ecological impact.</p><div class="mdl-grid videos" style=justify-content:center><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div class=video-container><video id=video2 controls preload=auto width=100% height=auto poster=/static/videos/posters/video2.webp>
|
||||
<source src=/static/videos/hls/video2/index.m3u8 type=application/x-mpegurl><source src=/static/videos/video2.mp4 type=video/mp4><p>To view this video please enable JavaScript, and consider upgrading to a
|
||||
web browser that supports HTML5 video</p></video></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone"><div class=video-container><video id=video3 controls preload=auto width=100% height=auto poster=/static/videos/posters/video3.webp>
|
||||
<source src=/static/videos/hls/video3/index.m3u8 type=application/x-mpegurl><source src=/static/videos/video3.mp4 type=video/mp4><p>To view this video please enable JavaScript, and consider upgrading to a
|
||||
web browser that supports HTML5 video</p></video></div></div></div></div></div></div></div><div class=recent-posts><div class=chocolate-container><div class=mdl-grid><div class="mdl-cell mdl-cell--12-col"><h2 class="mdl-typography--display-2 section-title">Recent News</h2><p class=blog-description></p><div class=mdl-grid><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone blog-post mdl-card mdl-shadow--2dp"><div class=mdl-card__title><h3 class=mdl-card__title-text>2 Ways to Be Economical When Showering With an Injury</h3></div><div class=mdl-card__supporting-text><p><p>It's extremely challenging to lead your daily life while sustaining an injury. And yet, dealing with sports injuries is something that most of us will have to go through, with nearly 2 million sports-related injuries affecting high school athletes alone per year. Most of us know the feeling of attempting to take a shower or bath when your arm is wrapped in a cast and cannot get wet. It's a defeated feeling, and it can quickly take away the motivation to shower or bathe in the first place. After all, wouldn't it be easier to not deal with the challenge? Furthermore, you may also be concerned that showering with your sports-related injury will be a longer process than a normal shower, making the entire ordeal less environmentally friendly. While there are ways to make sure you are being economical while showering, like being conscientious of what you put down the drain, you may not always be thinking about the environment when trying to avoid getting your injury wet in the shower. Fortunately, there are two ways you can be economical about your water usage while showering with an injury, including:</p></p></div><div class="mdl-card__actions mdl-card--border"><a href=/posts/blog4/ class="mdl-button mdl-button--colored mdl-button mdl-js-button mdl-button--raised mdl-button--colored" tabindex=0 aria-label="Read more about 2 Ways to Be Economical When Showering With an Injury">Read Article: 2 Ways to Be Economical When Showering With an Injury</a></div></div><div class="mdl-cell mdl-cell--6-col mdl-cell--12-col-tablet mdl-cell--12-col-phone blog-post mdl-card mdl-shadow--2dp"><div class=mdl-card__title><h3 class=mdl-card__title-text>Don't Put These Things Down The Shower Drain!</h3></div><div class=mdl-card__supporting-text><p><p>Natural water in Finland is some of the most polluted water in Europe (read the discussions in the article). You might be contributing to its pollution without realizing it, such as if you're putting things down the drain that you really shouldn't. Making your shower eco-friendly should be about saving water as well as preventing water contamination. Here's what you can do to be greener and cleaner!</p><p>In Finland, people use an average of 140 liters of water every day. By installing a product such as Showerloop into your shower, you can save water and energy. Showerloop reuses water while you shower so that it doesn't go to waste – and you don't have to feel guilty about taking longer showers. However, that's just Step One to ensuring a more eco-friendly shower. Step Two involves preventing toxins from ending up in water systems and the environment. That means you can enjoy showering without worrying about how you're harming the water and wildlife.</p></p></div><div class="mdl-card__actions mdl-card--border"><a href=/posts/blog3/ class="mdl-button mdl-button--colored mdl-button mdl-js-button mdl-button--raised mdl-button--colored" tabindex=0 aria-label="Read more about Don't Put These Things Down The Shower Drain!">Read Article: Don't Put These Things Down The Shower Drain!</a></div></div></div></div></div></div></div></main><footer class="mdl-mini-footer site-footer"><div class=mdl-mini-footer__left-section>© 2020 Shower Loop | All Rights Reserved</div><div class=mdl-mini-footer__right-section></div></footer></div></body></html>
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* HLS Player Utility
|
||||
* This script adds HLS playback capability to browsers using the native
|
||||
* HLS support in Safari/iOS or hls.js library in other browsers.
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Find all video elements on the page
|
||||
const videos = document.querySelectorAll('video');
|
||||
|
||||
// Skip processing if no videos are found
|
||||
if (videos.length === 0) return;
|
||||
|
||||
// Function to check for native HLS support
|
||||
function isHlsSupported() {
|
||||
const video = document.createElement('video');
|
||||
return video.canPlayType('application/vnd.apple.mpegURL') ||
|
||||
video.canPlayType('application/x-mpegURL');
|
||||
}
|
||||
|
||||
// Function to initialize HLS.js for a video element
|
||||
function setupHlsJs(video) {
|
||||
// Only process videos with HLS sources
|
||||
const hlsSource = Array.from(video.querySelectorAll('source'))
|
||||
.find(source => source.src.includes('.m3u8'));
|
||||
|
||||
if (!hlsSource) return;
|
||||
|
||||
// Don't setup HLS.js if browser has native support
|
||||
if (isHlsSupported()) return;
|
||||
|
||||
// Check if HLS.js is loaded
|
||||
if (typeof Hls !== 'undefined') {
|
||||
// Check if HLS.js is supported in this browser
|
||||
if (Hls.isSupported()) {
|
||||
const hls = new Hls({
|
||||
maxBufferLength: 30,
|
||||
maxMaxBufferLength: 60
|
||||
});
|
||||
|
||||
hls.loadSource(hlsSource.src);
|
||||
hls.attachMedia(video);
|
||||
|
||||
hls.on(Hls.Events.MANIFEST_PARSED, function() {
|
||||
if (video.autoplay) {
|
||||
video.play()
|
||||
.catch(error => console.warn('Auto-play failed:', error));
|
||||
}
|
||||
});
|
||||
|
||||
// Handle errors
|
||||
hls.on(Hls.Events.ERROR, function(event, data) {
|
||||
console.warn('HLS error:', data);
|
||||
|
||||
// If fatal error, try to recover
|
||||
if (data.fatal) {
|
||||
switch (data.type) {
|
||||
case Hls.ErrorTypes.NETWORK_ERROR:
|
||||
console.log('Fatal network error, trying to recover...');
|
||||
hls.startLoad();
|
||||
break;
|
||||
case Hls.ErrorTypes.MEDIA_ERROR:
|
||||
console.log('Fatal media error, trying to recover...');
|
||||
hls.recoverMediaError();
|
||||
break;
|
||||
default:
|
||||
// Cannot recover
|
||||
hls.destroy();
|
||||
// Fall back to MP4 if available
|
||||
const mp4Source = Array.from(video.querySelectorAll('source'))
|
||||
.find(source => source.type === 'video/mp4');
|
||||
if (mp4Source) {
|
||||
video.src = mp4Source.src;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn('HLS.js is not supported in this browser');
|
||||
}
|
||||
} else {
|
||||
console.warn('HLS.js is not loaded');
|
||||
// You might want to dynamically load hls.js here
|
||||
// const script = document.createElement('script');
|
||||
// script.src = '/static/js/vendor/hls.min.js';
|
||||
// document.head.appendChild(script);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize each video
|
||||
videos.forEach(setupHlsJs);
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
document.addEventListener("DOMContentLoaded",(function(){const e=document.querySelectorAll("video");0!==e.length&&e.forEach((function(e){const o=Array.from(e.querySelectorAll("source")).find((e=>e.src.includes(".m3u8")));if(o&&!function(){const e=document.createElement("video");return e.canPlayType("application/vnd.apple.mpegURL")||e.canPlayType("application/x-mpegURL")}())if("undefined"!=typeof Hls)if(Hls.isSupported()){const r=new Hls({maxBufferLength:30,maxMaxBufferLength:60});r.loadSource(o.src),r.attachMedia(e),r.on(Hls.Events.MANIFEST_PARSED,(function(){e.autoplay&&e.play().catch((e=>console.warn("Auto-play failed:",e)))})),r.on(Hls.Events.ERROR,(function(o,n){if(console.warn("HLS error:",n),n.fatal)switch(n.type){case Hls.ErrorTypes.NETWORK_ERROR:console.log("Fatal network error, trying to recover..."),r.startLoad();break;case Hls.ErrorTypes.MEDIA_ERROR:console.log("Fatal media error, trying to recover..."),r.recoverMediaError();break;default:r.destroy();const o=Array.from(e.querySelectorAll("source")).find((e=>"video/mp4"===e.type));o&&(e.src=o.src)}}))}else console.warn("HLS.js is not supported in this browser");else console.warn("HLS.js is not loaded")}))}));
|
File diff suppressed because one or more lines are too long
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
@ -20,8 +20,8 @@ mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div cl
|
|||
<img class=responsive-img src=/images/PCBBasic2_6.webp alt="Close-up of soldered diode connections on the prototype circuit board">
|
||||
<img class=responsive-img src=/images/PCBBasic2_7.webp alt="Assembled circuit board showing the completed control system with all components">
|
||||
<img class=responsive-img src=/images/PCBBasic2_8.webp alt="Testing the control board with multimeter to verify electrical connections">
|
||||
<img class=responsive-img src=/images/PCBBasic2_9.webp alt="Final control board mounted in enclosure with cable connections"><div class=video-container><video id=video3 controls preload=auto width=640 height=360>
|
||||
<source src=/static/videos/video3.mp4 type=video/mp4><p>To view this video please enable JavaScript, and consider upgrading to a
|
||||
<img class=responsive-img src=/images/PCBBasic2_9.webp alt="Final control board mounted in enclosure with cable connections"><div class=video-container><video id=video3 controls preload=auto width=100% height=auto poster=/static/videos/posters/video3.webp>
|
||||
<source src=/static/videos/hls/video3/index.m3u8 type=application/x-mpegurl><source src=/static/videos/video3.mp4 type=video/mp4><p>To view this video please enable JavaScript, and consider upgrading to a
|
||||
web browser that supports HTML5 video</p></video></div><img class=responsive-img src=/images/PCBBasic2_10.webp alt="Control panel installed and connected to the ShowerLoop system showing operational status">
|
||||
<img class=responsive-img src=/images/PCBBasic2_11.webp alt="Complete ShowerLoop control system with the new electronics board fully wired and functional"></div><span>Tags:</span>
|
||||
<span class=nowrap><em><span class=ph1>post</span></em>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=posts><body class=posts><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import * as utils from '/js/utils.modern.min.js';
|
||||
window.utilsModule = utils;
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
</script><script type=module src=/js/app.modern.min.js defer></script><script type=module src=/js/skip-to-content.modern.min.js defer></script><script type=module src=/js/material.modern.min.js defer></script><script nomodule src=/js/app.min.js defer></script><script nomodule src=/js/skip-to-content.min.js defer></script><script nomodule src=/js/material.min.js defer></script><link rel=stylesheet type=text/css href=/css/app.min.css><link rel=stylesheet type=text/css href=/css/custom.css media=print onload='this.media="all"'><noscript><link rel=stylesheet href=/css/custom.css></noscript><link rel=icon href=/static/favicon.svg type=image/svg+xml><link rel=icon href=/static/favicon.ico type=image/x-icon><script src=/static/js/vendor/hls.min.js defer></script><script src=/static/js/hls-player.min.js defer></script></head><body class=page><body class=page><div class="mdl-layout mdl-js-layout
|
||||
mdl-layout--fixed-header"><header class="mdl-layout__header site-header"><div class=mdl-layout__header-row><a href=/ class=mdl-layout-title><img class=logo src=/images/logo2.webp height=50 width=auto alt="ShowerLoop Logo"></a><div class=mdl-layout-spacer></div><nav class="mdl-navigation mdl-layout--large-screen-only"><a class=mdl-navigation__link href=/ title=Home>Home</a>
|
||||
<a class=mdl-navigation__link href=/how-it-works/ title="How It Works">How It Works</a>
|
||||
<a class=mdl-navigation__link href=/research/ title=Research>Research</a>
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* HLS Player Utility
|
||||
* This script adds HLS playback capability to browsers using the native
|
||||
* HLS support in Safari/iOS or hls.js library in other browsers.
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Find all video elements on the page
|
||||
const videos = document.querySelectorAll('video');
|
||||
|
||||
// Skip processing if no videos are found
|
||||
if (videos.length === 0) return;
|
||||
|
||||
// Function to check for native HLS support
|
||||
function isHlsSupported() {
|
||||
const video = document.createElement('video');
|
||||
return video.canPlayType('application/vnd.apple.mpegURL') ||
|
||||
video.canPlayType('application/x-mpegURL');
|
||||
}
|
||||
|
||||
// Function to initialize HLS.js for a video element
|
||||
function setupHlsJs(video) {
|
||||
// Only process videos with HLS sources
|
||||
const hlsSource = Array.from(video.querySelectorAll('source'))
|
||||
.find(source => source.src.includes('.m3u8'));
|
||||
|
||||
if (!hlsSource) return;
|
||||
|
||||
// Don't setup HLS.js if browser has native support
|
||||
if (isHlsSupported()) return;
|
||||
|
||||
// Check if HLS.js is loaded
|
||||
if (typeof Hls !== 'undefined') {
|
||||
// Check if HLS.js is supported in this browser
|
||||
if (Hls.isSupported()) {
|
||||
const hls = new Hls({
|
||||
maxBufferLength: 30,
|
||||
maxMaxBufferLength: 60
|
||||
});
|
||||
|
||||
hls.loadSource(hlsSource.src);
|
||||
hls.attachMedia(video);
|
||||
|
||||
hls.on(Hls.Events.MANIFEST_PARSED, function() {
|
||||
if (video.autoplay) {
|
||||
video.play()
|
||||
.catch(error => console.warn('Auto-play failed:', error));
|
||||
}
|
||||
});
|
||||
|
||||
// Handle errors
|
||||
hls.on(Hls.Events.ERROR, function(event, data) {
|
||||
console.warn('HLS error:', data);
|
||||
|
||||
// If fatal error, try to recover
|
||||
if (data.fatal) {
|
||||
switch (data.type) {
|
||||
case Hls.ErrorTypes.NETWORK_ERROR:
|
||||
console.log('Fatal network error, trying to recover...');
|
||||
hls.startLoad();
|
||||
break;
|
||||
case Hls.ErrorTypes.MEDIA_ERROR:
|
||||
console.log('Fatal media error, trying to recover...');
|
||||
hls.recoverMediaError();
|
||||
break;
|
||||
default:
|
||||
// Cannot recover
|
||||
hls.destroy();
|
||||
// Fall back to MP4 if available
|
||||
const mp4Source = Array.from(video.querySelectorAll('source'))
|
||||
.find(source => source.type === 'video/mp4');
|
||||
if (mp4Source) {
|
||||
video.src = mp4Source.src;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn('HLS.js is not supported in this browser');
|
||||
}
|
||||
} else {
|
||||
console.warn('HLS.js is not loaded');
|
||||
// You might want to dynamically load hls.js here
|
||||
// const script = document.createElement('script');
|
||||
// script.src = '/static/js/vendor/hls.min.js';
|
||||
// document.head.appendChild(script);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize each video
|
||||
videos.forEach(setupHlsJs);
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
document.addEventListener("DOMContentLoaded",(function(){const e=document.querySelectorAll("video");0!==e.length&&e.forEach((function(e){const o=Array.from(e.querySelectorAll("source")).find((e=>e.src.includes(".m3u8")));if(o&&!function(){const e=document.createElement("video");return e.canPlayType("application/vnd.apple.mpegURL")||e.canPlayType("application/x-mpegURL")}())if("undefined"!=typeof Hls)if(Hls.isSupported()){const r=new Hls({maxBufferLength:30,maxMaxBufferLength:60});r.loadSource(o.src),r.attachMedia(e),r.on(Hls.Events.MANIFEST_PARSED,(function(){e.autoplay&&e.play().catch((e=>console.warn("Auto-play failed:",e)))})),r.on(Hls.Events.ERROR,(function(o,n){if(console.warn("HLS error:",n),n.fatal)switch(n.type){case Hls.ErrorTypes.NETWORK_ERROR:console.log("Fatal network error, trying to recover..."),r.startLoad();break;case Hls.ErrorTypes.MEDIA_ERROR:console.log("Fatal media error, trying to recover..."),r.recoverMediaError();break;default:r.destroy();const o=Array.from(e.querySelectorAll("source")).find((e=>"video/mp4"===e.type));o&&(e.src=o.src)}}))}else console.warn("HLS.js is not supported in this browser");else console.warn("HLS.js is not loaded")}))}));
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
master.m3u8
|
|
@ -0,0 +1,12 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:3
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=200000,RESOLUTION=256:144
|
||||
video1_144p.m3u8
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=400000,RESOLUTION=426:240
|
||||
video1_240p.m3u8
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640:360
|
||||
video1_360p.m3u8
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=1500000,RESOLUTION=854:480
|
||||
video1_480p.m3u8
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280:720
|
||||
video1_720p.m3u8
|
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
|
@ -0,0 +1,86 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:3
|
||||
#EXT-X-TARGETDURATION:6
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXT-X-PLAYLIST-TYPE:VOD
|
||||
#EXTINF:5.760000,
|
||||
video1_144p_000.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_001.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_002.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_003.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_004.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_005.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_006.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_007.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_008.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_009.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_010.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_011.ts
|
||||
#EXTINF:5.760000,
|
||||
video1_144p_012.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_013.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_014.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_015.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_016.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_017.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_018.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_019.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_020.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_021.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_022.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_023.ts
|
||||
#EXTINF:5.760000,
|
||||
video1_144p_024.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_025.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_026.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_027.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_028.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_029.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_030.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_031.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_032.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_033.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_034.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_035.ts
|
||||
#EXTINF:5.760000,
|
||||
video1_144p_036.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_037.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_144p_038.ts
|
||||
#EXTINF:2.600000,
|
||||
video1_144p_039.ts
|
||||
#EXT-X-ENDLIST
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,86 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:3
|
||||
#EXT-X-TARGETDURATION:6
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXT-X-PLAYLIST-TYPE:VOD
|
||||
#EXTINF:5.760000,
|
||||
video1_240p_000.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_001.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_002.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_003.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_004.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_005.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_006.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_007.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_008.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_009.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_010.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_011.ts
|
||||
#EXTINF:5.760000,
|
||||
video1_240p_012.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_013.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_014.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_015.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_016.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_017.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_018.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_019.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_020.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_021.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_022.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_023.ts
|
||||
#EXTINF:5.760000,
|
||||
video1_240p_024.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_025.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_026.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_027.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_028.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_029.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_030.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_031.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_032.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_033.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_034.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_035.ts
|
||||
#EXTINF:5.760000,
|
||||
video1_240p_036.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_037.ts
|
||||
#EXTINF:3.840000,
|
||||
video1_240p_038.ts
|
||||
#EXTINF:2.600000,
|
||||
video1_240p_039.ts
|
||||
#EXT-X-ENDLIST
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue