Is there any CSS (or anything) I can add to my media queries that would recognize what the device the video is playing on? I am looking to have a play button appear on my site when the video attempts to play on any device that does not allow auto play. Let me know your thoughts, my site is live and published at http://www.rosemont.edu/admissionstest
Javascript to hide button:
var supports_video_autoplay = function(callback) {
var v = document.createElement("video");
v.paused = true;
var p = "play" in v && v.play();
typeof callback === "function" && callback(!v.paused || "Promise" in window && p instanceof Promise);
};
// usage
supports_video_autoplay(function(supported) {
if (supported) {
// video autoplay supported!
document.getElementById("Playing1").style.display = "none";
} else {
// no video autoplay support :(
document.getElementById("playing1")
}
});
I don't think there is a clean css solution for this. There is a related question here
Maybe you could display the play button by default and hide it when the media element's playing event(not the play event, but playing) is triggered? If you add transitions to it it won't blink for devices that has auto-play support.
Something like
var video = document.getElementsByTagName("video")[0];
video.addEventListener("playing", function() {
// Hide or fade out the initial play button
});
Related
I'm trying to make background audio remember the play/pause state. I have achieved pausing it and storing the pause state in the cookie, so when I go between page one and two it stays paused (vs autoplaying initially on both pages), but when I click play after that and refresh the page, even though the cookie is changing to "false" in the inspector, the audio doesn't play and the div colour doesn't change to green.
Live demo https://timcliss.webflow.io/audio-test
Codepen
Here is the code
External Scripts
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie#2.2.1/src/js.cookie.min.js"></script>
HTML
<div class="div" id="toggle"> PLAY/PAUSE </div>
<audio id="player" src="https://storage.yandexcloud.net/timcliss/About.mp3" autoplay loop>
CSS
.div {
background-color:green;
height: 50px;
color: white;
text-align: center;
}
JS
var audio = $('#player')[0];
audio.volume = 0.5;
var isMuted = Cookies.get('playerMuted'); // Receive stored cookie
if(isMuted) // If muted, stop the player
{
$('#player')[0].pause();
$('#toggle').css({'background-color': 'red'});
}
else
{
$('#player')[0].play();
$('#toggle').css({'background-color': 'green'});
}
// This function will be called when you click the toggle div
function toggleMute()
{
if(isMuted) // If player is muted, then unmute it
{
$('#player')[0].play();
$('#toggle').css({'background-color': 'green'});
isMuted = false;
} else // Else mute it
{
$('#player')[0].pause();
$('#toggle').css({'background-color': 'red'});
isMuted = true;
}
Cookies.set('playerMuted', isMuted); // Save current state of player
}
$('#toggle').click(toggleMute);
In new browsers audio autoplay is not supported and user has to explicitly play audio that is why play part is not working. You can read more about it here
(https://developers.google.com/web/updates/2017/09/autoplay-policy-changes).
Solved, turns out I just needed to use
if(isMuted=='true')
and then isMuted = 'false'; or isMuted = 'true';
Here is the updated pen
Works like a clock in Chrome with autoplay enabled! :)
Safari is more strict with the autoplay, so I added a check and only run this code for Chrome, and run standard player for Safari
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
if(isSafari){
alert('Is safari');
//Do something
} else {
alert('Is other browser');
// Do something
}
If someone finds a workaround for autoplay in Safari, or if you need help with implementing it in Chrome please let me know!
I am using Flickity to create a slider of images and videos. When changing slides, I want to play the video on the current slide (which has a class of .is-selected), and then pause again once I move to the next slide.
The code below manages to find any videos within the slider, but plays them on any slide change, rather than specifically for the slide they are within. Any help would be much appreciated.
// Init Flickity
var $carousel = $('.carousel');
$carousel.flickity();
// On slide change
$carousel.on('change.flickity', function() {
// Find videos
var currentSlide = $(this).find('.is-selected');
var video = $(this).find('video');
// Play videos
video[0].play();
});
What you want to do is pause all videos on every slide change and only play the one on the selected slide. I did something similar (without jQuery):
var carousel = document.querySelector(".carousel");
var flkty = new Flickity(carousel, {
// ..
});
flkty.on("change", function() {
console.log("Flickity active slide: " + flkty.selectedIndex);
flkty.cells.forEach(function(cell, i) {
if (cell.element == flkty.selectedElement) {
// play video if active slide contains one
// use <video playsinline ..> in your html to assure it works on ios devices
var video = cell.element.querySelector("video");
if (video) {
console.log("playing video " + i);
video.play();
}
return;
}
// pause all other videos
var video = cell.element.querySelector("video");
if (video) {
console.log("pausing video " + i);
video.pause();
}
});
});
As I stated in the comment, you might wanna use the "playsinline" attribute for your videos, otherwise you'll run into problems on iOS.
Also: using the "settle" event instead of "change" allows you to start playing once the active slide settled at its end position.
I am a total JavaScript amateur. I want to create a section where people can switch between 2 audios with a video running along with it. I want to show a before and after version of the audio.
Basically, the video should run with the "before" version of the audio initially. Then there should be a button to switch the audio to the "after" version, and go back and forth.
I tried the "audioTracks" method, but the browser compatibility is not good with it. What is the best possible way to achieve it?
Thanks in advance.
You just use two HTML Audio elements and then sync their times:
var audio1 = new Audio()
var audio2 = new Audio()
audio1.src = 'pathToSource',
audio2.src = 'pathToSource2',
var video = document.getElementByID('myvideo');
video.muted = true; //mute video cuz we have audio already
function switchAudio(one, two, vid) {
if(one.paused) {
two.pause();
one.currentTime = vid.currentTime;
one.play
} else {
one.pause();
two.currentTime = vid.currentTime;
two.play()
}
}
That did it :) I made some changes though. The audio seems to be working great. I could play and switch it. But the video was not starting up with the button. So I changed the code to this:
function switchAudio(one, two, vid) {
if (one.paused) {
two.pause();
vid.play();
one.play();
one.currentTime = vid.currentTime;
} else {
vid.pause();
one.pause();
vid.play();
two.play();
two.currentTime = vid.currentTime;
}
}
After this the video is playing along with the audio. But when I switch the audio, their timing does not match. The audio seems to be playing just a little bit late.
I am working on a video where during some seconds, an overlay element appears to promote a product.
I would like to know if is possible to pause the video when someone clicks the overlay element and at the same time this will display a window showing the product details. So:
Video plays and displays an overlay element
User clicks the overlay element so:
2.1: Video pauses on the background
2.2: Overlay element opens a window over the paused video to show the product details.
This is my code where the video shows the overlay element for a few seconds during the video:
<video id="myVideo" controls>
<source id='mp4' src="video.mp4" type='video/mp4'>
</video>
<div id="overlay">
Something
</div>
<script>
//Shows link between seconds 5 and 10
var overlay = document.getElementById('overlay');
var video = document.getElementById('myVideo');
video.addEventListener('timeupdate', function() {
console.log( video.currentTime );
var show = video.currentTime >= 5 && video.currentTime < 10;
overlay.style.opacity = show ? '1' : '0';
}, false);
</script>
some sample code:
overlay.addEventListener('click', function() { video.pause() })
You should proably add in something that would play the video once the overlay is clicked again - but i think you get the idea.
Have a look here for the documentation on what is available on the video element:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
Video can be paused using video.pause()
https://www.w3schools.com/tags/ref_av_dom.asp
You can attach an click event listener to your overlay,
and call the video pause function when the user click on the overlay.
Instead of using opacity on your overlay,
you can perhaps try using display: none instead.
So that, you won't need to handle the situation where the overlay
is always blocking in front of your elements.
See demo: https://jsfiddle.net/amoshydra/pan306jt/
//Shows link between seconds 5 and 10
var overlay = document.getElementById('overlay');
var video = document.getElementById('myVideo');
video.addEventListener('timeupdate', function() {
console.log( video.currentTime );
var show = video.currentTime >= 5 && video.currentTime < 10;
// Try using display style?
overlay.style.display = show ? 'block' : 'none';
}, false);
overlay.addEventListener('click', function() {
var urlToOpen = 'http://stackoverflow.com/questions/14132122/open-url-in-new-window-with-javascript';
window.open(urlToOpen, '_blank');
// Pause video using the video API
video.pause();
});
I'm using the following code to trigger fullscreen when a user clicks on the play button on a <video> element:
var video = $("#video");
video.on('play', function(e){
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.mozRequestFullScreen) {
video.mozRequestFullScreen();
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen();
}
});
But nothing happens when I click the play button.
Any idea's why?
EDIT: Here's my HTML code:
<video width="458" height="258" controls id='video' >
<source src='<?= bloginfo('template_directory'); ?>/inc/pilot.mp4' type="video/mp4">
<source src='<?= bloginfo('template_directory'); ?>/inc/pilot.ogv' type="video/ogg">
<source src='<?= bloginfo('template_directory'); ?>/inc/pilot.webm' type="video/webm">
</video>
There are a couple things going on here:
First, in your code, video is a jQuery object, not the actual video element. For a jQuery object, you can reference it like this:
var actualVideo = video[0]; // (assuming '#video' actually exists)
Second, for security and good user experience, browsers will only let you trigger full screen inside a user-triggered event, like a 'click'. You can't have every web page going to full screen as soon as you visit it, and you can cause a video to start playing automatically, which would violate that rule.
So an alternative solution would be to request fullscreen in a click event, like this:
var video = $("#video");
video.on('click', function(e){
var vid = video[0];
vid.play();
if (vid.requestFullscreen) {
vid.requestFullscreen();
} else if (vid.mozRequestFullScreen) {
vid.mozRequestFullScreen();
} else if (vid.webkitRequestFullscreen) {
vid.webkitRequestFullscreen();
}
});
Ideally, you'd probably want to build out a more complete player ui, but this should give you the general idea.
A less verbose way to toggle full screen combining answers from this and other questions.
This should handle all browser flavours: chromium- and webkit-based, firefox, opera, and MS-based browsers.
var p = document.querySelector('#videoplayer');
if (!window.isFs) {
window.isFs = true;
var fn_enter = p.requestFullscreen || p.webkitRequestFullscreen || p.mozRequestFullScreen || p.oRequestFullscreen || p.msRequestFullscreen;
fn_enter.call(p);
} else {
window.isFs = false;
var fn_exit = p.exitFullScreen || p.webkitExitFullScreen || p.mozExitFullScreen || p.oExitFullScreen || p.msExitFullScreen;
fn_exit.call(p);
}
p represents the DOM object of the video element, and window.isFs is just a random variable for storing the current fullscreen state.
If your player is a jQuery object then you can get the underlying DOM-element with var p = player.get(0).