So I'm currently building a website that has a carousel containing four videos, each video is triggered to play by hooking in to the Bootstrap 3 carousel's slide.bs.carousel
event.
Each of the videos are embedded in the page like so:
<video id="somevideo" class="video-js vjs-default-skin m-hide" controls preload="auto" data-setup='{ "controls": false, "autoplay": false, "preload": "auto" }'>
<source src="somevideo.mp4">
<source src="somevideo.webmhd.webm">
</video>
Now, given the restrictions imposed particularly by Apple on the autoplaying and preloading of HTML5 videos (both are disabled and user interaction is required to trigger playback) I've decided to omit the videos for mobile & opt for static images instead. This is relatively simple, since all that's required to stop the video from overlaying the content is a media query that hides them.
That said, I'm finding it very difficult to prevent the videos from being downloaded and the overhead is massive.
For example, I have a script to check whether the user is currently visiting from a mobile device, as such, I've tried:
var check = false;
window.mobilecheck = function() {
// Check for mobile here
if (check === true) {
// Device is mobile
var videos = document.querySelectorAll('.video-js');
for (var i = 0; i < videos.length; i++) {
// videojs(videos[i]).destroy();
videos[i].parentNode.removeChild(videos[i]);
}
}
}
This successfully removes the elements, but this has to be called on DOMReady which also means the resources already begin download.
How do I stop the videos from loading on mobile? I'd like to find a solution that uses VideoJS inherently preferably.
Based on the suggestions Ian kindly made, here is my working solution.
Firstly, I changed each video's child source elements to have an attribute data-src
like so:
<video id="my-id">
<source data-src="somevideo.mp4">
</video>
Then, after performing a mobile check using the script available at http://detectmobilebrowsers.com/ which I modified to include iPads etc (related SO answer here) I simply used the following script to automatically update the src
attribute of each video (if we're on desktop in my case):
var sources = document.querySelectorAll('video#my-id source');
// Define the video object this source is contained inside
var video = document.querySelector('video#my-id');
for(var i = 0; i<sources.length;i++) {
sources[i].setAttribute('src', sources[i].getAttribute('data-src'));
}
// If for some reason we do want to load the video after, for desktop as opposed to mobile (I'd imagine), use videojs API to load
video.load();
And that's it! Nothing loads on mobile devices anymore and I can have fairly granular control over the devices it will or won't load on.
Hope this helps somebody.
One way you could do this is by setting the src
attributes of your video
element via JavaScript, and only doing so based on a media query (using matchMedia
).
This would mean that the bulk of your code would have to move to JavaScript though.
For example, your HTML could be something like:
<video data-mp4="video.mp4" data-webm="video.webm" class="video-js" controls></video>
And then in your JavaScript (pseudo code here, not actual JS):
if (window.matchMedia("(min-width: 640px)").matches) {
// do nothing
} else {
var videos = document.querySelectorAll('.video-js'),
videoFile;
for (var i = 0; i < videos.length; i++) {
// Choose video type
if (video[i].canPlayType("video/mp4") === "probably") {
videoFile = video[i].getAttribute("data-mp4");
}
// do the same check for WebM here...
video[i].src = videoFile;
// Call whatever reload or refresh method video.js has
// for example...
video[i].refresh();
}
}
Something like that might work for you, although you might have to play around a bit with it.
Based on Ian and GDGR's answers, I modified this to work for multiple videos.
<video class="mobile-no-load">
<source data-src="somevideo.mp4">
</video>
if (window.innerWidth > 730) {
// get multiple videos
var sources = document.querySelectorAll('video.mobile-no-load');
// loop through the videos
sources.forEach(function(source){
// target the src attribute of the <source> element and set it to the data-src attribute
source.childNodes[1].setAttribute('src', source.childNodes[1].getAttribute('data-src'))
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With