Attempting to use a self hosted video background hero (in wordpress with elemnetor) that auto plays on load but with no sound as it should be muted for both ADA compliance and to be supported by certain web browsers.
I am wondering if it's possible to have a button/icon that unmutes the sound but also restarts the video at the same time so the 30 sec message and sound starts over from the beginning?
Problem:
I have it set up to auto play with no sound and added an icon using this technique and this code (https://elementorcodes.com/elementor-video-background-sound-button/) but how can I trigger a restart at the same time?
Code:
document.addEventListener('DOMContentLoaded', function() {
var toggleSoundButton = document.querySelector('.fa-volume-mute');
var heroBackgroundVideo = document.querySelector('.herosection video');
toggleSoundButton.addEventListener('click', function (event) {
if (heroBackgroundVideo.muted !== false){
heroBackgroundVideo.muted=false;
toggleSoundButton.classList.add('fa-volume-up');
} else {
heroBackgroundVideo.muted=true;
toggleSoundButton.classList.remove('fa-volume-up');
} }); });
</script>
heroBackgroundVideo.currentTime = 0;
heroBackgroundVideo.play();
Related
I have set up some HTML & Javascript that can control the playing of an audio track on a webpage, I really like simplicity of JavaScript with play/stop function but I can't make it play automatically.
Here's my javascript code:
$('body');
var audio = document.getElementById("audio-player");
audio.volume = 0.2;
if ($(window).length) {
$('.bg-player').css({
'visibility': 'visible'
});
$('body').addClass("audio-on");
if ($('body').hasClass('audio-on')) {
$('body').removeClass('audio-off');
}
$(".bg-player").on('click', function() {
$('body').toggleClass("audio-on audio-off");
if ($('body').hasClass('audio-off')) {
audio.pause();
}
if ($('body').hasClass('audio-on')) {
audio.play();
}
});
}
I tried to add the autoplay property but no success:
audio.autoplay = true;
I would like know if there is a way for play the file on the page load.
It's a browser security feature to not autoplay an audio unless there is some user interaction.
https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#new-behaviors
Autoplay with sound is allowed if:
User has interacted with the domain (click, tap, etc.).
On desktop, the user's Media Engagement Index threshold has been crossed, meaning the user has previously played video with sound.
The user has added the site to their home screen on mobile or installed the PWA on desktop.
I built a page to play HLS content on most platform, use HTML5 video + HLS.js by default and fallback to flash version of player(Grind Player) if MSE is not supported.
I'm trying to stop video tag from playing when user switch to another tab or another program. After reading some answers of similar questions, I used code below:
function PauseVideo() {
if (isFlashPlayerUsed) {
var isPlaying = player.getPlaying();
AddLog("player.playing: " + isPlaying);
if (isPlaying)
player.pause();
}
else {
AddLog("player.paused: " + player.paused);
if (!player.paused)
player.pause();
}
}
$(window).on("blur", function (e) {
AddLog("window.blur fired.");
PauseVideo();
});
$(window).on("focusout", function (e) {
AddLog("window.focusout fired.");
PauseVideo();
});
$(document).on("visibilityChange", function (e) {
AddLog("document.visibilityChange fired.");
if (document.visibilityState == "hidden")
PauseVideo();
});
However, I found that in Internet Explorer 11 on Windows 7, Flash version of Player is used, and window.blur fired if I clicked anything other than player itself even if it's in the same page, but didn't fire if player is on focus and I clicked another program.
How to make sure the video will always pause when the window or tab lose focus, even if flash version of player is used?
Im having trouble firing up the audio (playback+pause) on the same page.
My standard HTML5 audio player works perfect and has standard controlls like this:
<play title="Play spoken audio for the visually impaired">▶</play>
<pause title="Pause audio, and press again to resume play">❚❚</pause>
Now imagine you would like to have a simplified alternative play/pause controls elsewhere on the same page. Good idea right? Now my problem is, that if I add a separate more minimalistic play / pause control elsewhere on the page, then the first play/pause buttons dissappear entirely!
<play>▶</play>
<pause>❚❚</pause>
All that I want is to duplicate the functionality of the first play/pause and place them elsewhere on the page, allowing users on mobile to have the play/pause on another location of the page for ease of use.
So in summary, I would like to allow the user to controll the playback from two different places simultaneously. The main one has fancier layout, while the alternative one in location 2 has only play and pause toggle. Both should toggle if either one is pressed. (when play is pressed it shows as a pause button and when pause is pressed it becomes a play button).
What must I change in html and or javascript to achieve this? Thanks in advance!
The javascript looks like this:
window.onload = function(){
var myAudio = document.getElementsByTagName('audio')[0];
var play = document.getElementsByTagName('play')[0];
var pause = document.getElementsByTagName('pause')[0];
function displayControls() {
play.style.display = "block";
}
// check that the media is ready before displaying the controls
if (myAudio.paused) {
displayControls();
} else {
// not ready yet - wait for canplay event
myAudio.addEventListener('canplay', function() {
displayControls();
});
}
play.addEventListener('click', function() {
myAudio.play();
play.style.display = "none";
pause.style.display = "block";
});
pause.addEventListener('click', function() {
myAudio.pause();
pause.style.display = "none";
play.style.display = "block";
});
}
DEMO
So you have the following code...
var myAudio = document.getElementsByTagName('audio')[0];
var play = document.getElementsByTagName('play')[0];
var pause = document.getElementsByTagName('pause')[0];
Step-by-step breakdown...
document.getElementsByTagName('audio')[0]
Get the 0th (1st) element in the document that has the tag name audio.
document.getElementsByTagName('play')[0]
Get the 0th (1st) element in the document that has the tag name play.
Problem #1. You only register the first play button for the code. You must add code for the second play button.
document.getElementsByTagName('pause')[0]
Get the 0th (1st) element in the document that has the tag name pause.
Problem #2. Same problem as #1.
So the solution is:
var audio;
window.onload=function(){
audio=document.getElementsByTagName("audio")[0];
//YOU MUST REGISTER AN EVENT LISTENER FOR EVERY PLAY AND PAUSE BUTTON.
document.getElementsByClassName("playpause")[0].addEventListener("click",playpause);
document.getElementsByClassName("playpause")[1].addEventListener("click",playpause);
}
function playpause(){
var state;
if(audio.paused){
audio.play();
state="Pause";
}else{
audio.pause();
state="Play";
}
for(var i=0;i<document.getElementsByClassName("playpause").length;i++){
document.getElementsByClassName("playpause")[i].innerHTML=state;
}
}
<audio>
<source src="http://www.kozco.com/tech/32.mp3" type="audio/mpeg">
</audio>
<button class="playpause">Play</button>
<button class="playpause">Play</button>
I have a slick.js slider that contains video and I want the slider to pause once it reaches a video slide and resume cycling once the video finishes without user interaction. I can get this functionality to work with the first video in a cycle but on the second video slide, the slider will not resume once the video completes.
Fiddle
I have a console log that writes out when the video completes but it won't say anything once the second video completes. I believe it is not seeing the function to play the slick slider.
function myHandler(e) {
console.log('Video Complete')
$('.sliderMain').slick('slickPlay');
}
You were only binding the first video tag to your myHandler function:
// It only gets the first element
var video = document.getElementsByTagName('video')[0];
video.addEventListener('ended',myHandler,false);
Since you're using jQuery, you can bind an event when the videos have ended like that:
$('video').on('ended',function(){
console.log('Video Complete')
$('.sliderMain').slick('slickPlay');
});
jQuery demo
The JavaScript equivalent would be so:
var videos = document.getElementsByTagName('video');
for (var i=0; i<videos.length; i++) {
videos[i].addEventListener('ended',myHandler,false);
}
JavaScript demo
SlickSlider is responsive and needs to work 360 (across all devices).
Your solution will not work on mobile, since autoplay of a video is forbidden.
Also this solution allows multiple videos to be playing at once, which is sub-optimal.
A better solution would be to pause the carousel only when the video is played by the user, and resume the carousel (pausing the video) when a slide is detected.
This works also on mobile devices. Just make sure, you don't serve a video tag on mobile. Before outputting your slide via PHP template, just check the user agent and serve a fallback image instead. Then use this for your video/autoplay/resume issue:
$('.homepage .hero-slider').on('afterChange', function(event, slick, currentSlide, nextSlide) {
var $active = $('.slick-slide.slick-current.slick-active');
var video = $active.find('video');
if (video.length == 1) {
var $slickInstance = $(this);
// play() only works with a valid id as selector :)
var video = document.getElementById(video.attr('id'));
video.play();
$slickInstance.slick('slickPause');
video.addEventListener('ended', function () {
$slickInstance.slick('slickPlay');
}, false);
}
});
I'm working on a Squarespace website, and they don't allow video upload, so I'm using Dropbox to host a video.
The video starts playing, but he is not repeating.
This is the code:
<video id="htmlVideo" loop="loop">
<source type="video/mp4" src="https://www.dropbox.com/s/videoID/videoplayback.mp4?dl=1">
</video>
What could be the problem?
This is how I create the video
/*
function repeatForDropbox() {
console.log("repeatForDropbox caled" + htmlVideo );
}
*/
function createVideo() {
var video = document.createElement("video");
video.id = "htmlVideo";
video.loop = "loop";
var vidSource = document.createElement("source");
vidSource.type = "video/mp4";
vidSource.src = "https://www.dropbox.com/s/videoID/videoplayback.mp4?dl=1";
video.appendChild( vidSource );
var vidLocation = document.querySelector('#location').parentNode;
vidLocation.appendChild( video );
htmlVideo = document.querySelector(" #htmlVideo ");
// on load, play the video/mp4
window.onload = function () {
setTimeout(function() {
htmlVideo.play();
// htmlVideo.addEventListener("ended", repeatForDropbox);
// I tried here to make the video repeat, using the "ended" event listener
// so when the video ended, the video
// should get another <source> element(same src)
// and delete the old one
// but the event didn't fire
// I also tried htmlVideo.onended = function() {} , but same result
}, 500);
}
}
Just a guess, but I suspect this relates to redirects. A Dropbox share link with ?dl=1 on it will redirect you to a one-time use URL to download the content. Perhaps when the video player tries to loop, it tries to access the target of the redirect again.
This might show up in the network traffic from the browser, so it's worth taking a look. (E.g. the network tab of Chrome inspector, if you're using Chrome.)
I would see if squarespace will let you save the binary of the video into a text file and then import it with AJAX and save it to indexedDB before converting it to video.
Here's some links:
Display a video from a Blob Javascript
https://simpl.info/video/offline/
Just in case anyone still needs the solution, I found a workaround using jQuery:
$('video').on('ended', function () {
this.load();
this.play();
});
However, there is a slight delay between repeats!