I'm trying to play audio when the div .deley change to display: block, but something does not work. The online audio clips are correct, it's not the problem. My problem is in my script, but I can not find it. Maybe .pause is not a function?
What could be wrong?
function see() {
var x = document.getElementById("deley");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
};
// === Scrip for audio play ====
$(document).ready(function(){
$(".deley").hide();
// if sound is currently playing, stop it and reset
if(!$("#notify").paused) {
$("#notify").pause();
$("#notify").currentTime = 0;
}
setTimeout(function () {
$(".deley").show();
$("#notify").play();
}, 0);
});
#cont {
width:200px;
margin:0 auto
}
.deley {
display:none;
width:96px;
height:40px;
background:red;
margin:20px 0;
text-align:center;
line-height:40px;
font-family:Arial, sans-serif;
color:#fff
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="cont">
<div class="deley" id="deley">Deley</div>
<audio id="notify">
<source src="https://notificationsounds.com/soundfiles/8b16ebc056e613024c057be590b542eb/file-sounds-1113-unconvinced.ogg" type="audio/ogg">
<source src="https://notificationsounds.com/soundfiles/8b16ebc056e613024c057be590b542eb/file-sounds-1113-unconvinced.mp3" type="audio/mpeg">
</audio>
<button onclick="see()">Open / Close</button>
</cont>
jQuery Objects✱ and JavaScript Objects🞳 are different. They do not recognize one another which is why the following statements do not work:
if (!$(".notify").paused) {
$(".notify").pause();
$(".notify").currentTime = 0;
...
$(".notify").play();
The MediaElement API is Plain JavaScript only. Any methods/properties/events from said API is not recognized by jQuery -- Plain JavaScript Objects are needed to use methods .pause() and .play(), and properties .paused and .currentTime.
Solutions
Reference a Plain JavaScript Object🞳
document.querySelector(selector)
Dereference a jQuery Object✱
$(selector)[0]
OR
$(selector).get(0)
There are a couple of other important things to remember about jQuery:
Never use onevent attributes: <buttononclick='func();'</button>
Assign .class attributes to elements avoid #id attributes.
The versatility jQuery affords to us makes such antiquated practices unnecessary and wasteful. Also, the function see() is no longer needed -- functionality of see() is now integrated into function audioSwitch().
$('button').on('click', audioSwitch);
function audioSwitch(e) {
if (!$(".notify")[0].paused || $('.delay').is(':visible')) {
$(".notify")[0].pause();
$(".notify")[0].currentTime = 0;
$(".delay").hide();
} else {
setTimeout(function() {
$(".notify")[0].play();
$(".delay").show();
}, 750);
}
}
.cont {
width: 200px;
margin: 0 auto
}
.delay {
display: none;
width: 96px;
height: 40px;
line-height: 40px;
background: red;
color: #fff;
margin: 20px 0;
text-align: center;
font-family: Arial, sans-serif;
}
<section class="cont">
<figure class="delay">
<figcaption>Delay</figcaption>
</figure>
<audio class="notify" src="https://notificationsounds.com/soundfiles/8b16ebc056e613024c057be590b542eb/file-sounds-1113-unconvinced.mp3">
</audio>
<button>Open / Close</button>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Here is a working example.
function see() {
var x = document.getElementById("deley");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
};
// === Scrip for audio play ====
$(document).ready(function(){
$(".deley").hide();
// if sound is currently playing, stop it and reset
if(!$("#notify")[0].paused) {
$("#notify")[0].pause();
$("#notify")[0].currentTime = 0;
}
setTimeout(function () {
$(".deley").show();
$("#notify")[0].play();
}, 0);
});
#cont {
width:200px;
margin:0 auto
}
.deley {
display:none;
width:96px;
height:40px;
background:red;
margin:20px 0;
text-align:center;
line-height:40px;
font-family:Arial, sans-serif;
color:#fff
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="cont">
<div class="deley" id="deley">Deley</div>
<audio id="notify">
<source src="https://notificationsounds.com/soundfiles/8b16ebc056e613024c057be590b542eb/file-sounds-1113-unconvinced.ogg" type="audio/ogg">
<source src="https://notificationsounds.com/soundfiles/8b16ebc056e613024c057be590b542eb/file-sounds-1113-unconvinced.mp3" type="audio/mpeg">
</audio>
<button onclick="see()">Open / Close</button>
</cont>
Jq object dose not have play, pause events. you will have to change it to a simple javascript to access those events.
emphasized text
Have a look below and i also simplified the function fot you
function see() {
$(".deley").toggle("fast", function(){
var player= $("#notify")[0];
// is the player hidden then pause and reset
if($(this).is("hidden")) {
player.pause();
player.currentTime = 0;
}else
player.play();
});
};
#cont {
width:200px;
margin:0 auto
}
.deley {
display:none;
width:96px;
height:40px;
background:red;
margin:20px 0;
text-align:center;
line-height:40px;
font-family:Arial, sans-serif;
color:#fff
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="cont">
<div class="deley" id="deley">Deley</div>
<audio id="notify">
<source src="https://notificationsounds.com/soundfiles/8b16ebc056e613024c057be590b542eb/file-sounds-1113-unconvinced.ogg" type="audio/ogg">
<source src="https://notificationsounds.com/soundfiles/8b16ebc056e613024c057be590b542eb/file-sounds-1113-unconvinced.mp3" type="audio/mpeg">
</audio>
<button onclick="see()">Open / Close</button>
</cont>
$(document).ready(function(){
$(".deley").hide();
// if sound is currently playing, stop it and reset
if(!$("#notify")[0].paused) {
$("#notify")[0].pause();
$("#notify")[0].currentTime = 0;
}
setTimeout(function () {
$(".deley").show();
$("#notify")[0].play();
}, 0);
});
https://stackoverflow.com/a/16093819/11343720
Or
document.getElementById('notify').play();
Related
I've been trying to do the following on my website's main page : a video in fullscreen plays (no controls, no loop, muted, autoplays, stored locally) and when it ends, the video is hidden and a div element shows.
I'm used to working with HTML and CSS but not so much JavaScript, so what I've done thus far is put the video, and used a checkbox to hide/show the elements (as shown here) and then tried to modify it so it would detect when the video ends, but I can't make it work.
The code I'm using is probably wrong, as it was meant for a checkbox, but I've also tried the solutions written there and it seems like the issue comes from the function used to detect when the video ends not working.
Here is what I've tried to automatize it :
#menudisplay {
display: none;
text-align: center;
margin-top: 20vh;
font-family: 'Montserrat';
}
#menudisplay ul {
list-style-type: none;
}
#menudisplay ul li {
padding: 110px;
}
.style {
width: 100vw;
height: 100vh;
object-fit: contain;
position: fixed;
top: 0;
left: 0;
z-index: -1;
background-color:lightgray;
}
<!DOCTYPE html>
<html>
<head>
<title>Website</title>
<meta http-equiv="Content-Type" content="charset=UTF-8" />
<link rel="stylesheet" href="./mystyle.css" type="text/css">
<link href='https://fonts.googleapis.com/css?family=Amatic SC|Montserrat' rel='stylesheet'>
</head>
<video autoplay muted class="style">
<source src="./video.mp4" type="video/mp4">
The video is not working.
</video>
<div id="menudisplay">
<img class="style" src="./img.jpg">
<ul>
<li>
EXEMPLE 1
</li>
<li>
EXEMPLE 2
</li>
</ul>
</div>
<script>
function myFunction() {
var video = document.getElementById("video");
var menudisplay = document.getElementById("menudisplay");
if (video.ended == true) {
menudisplay.style.display = "block";
video.style.display = "none";
} else {
menudisplay.style.display = "none";
}
}
</script>
</html>
I use Visual Studio Code and my web browser is Edge.
Thank you in advance, I'm really stuck !
In this example I added both an evenlistener for DOMContentLoaded (for making sure that the document has been loaded) and for the video ending.
document.addEventListener('DOMContentLoaded', e => {
var video = document.getElementById("video");
var menudisplay = document.getElementById("menudisplay");
video.addEventListener('ended', e => {
menudisplay.style.display = "block";
video.style.display = "none";
});
});
#menudisplay {
display: none;
text-align: center;
margin-top: 20vh;
font-family: 'Montserrat';
}
#menudisplay ul {
list-style-type: none;
}
#menudisplay ul li {
padding: 110px;
}
.style {
width: 100vw;
height: 100vh;
object-fit: contain;
position: fixed;
top: 0;
left: 0;
z-index: -1;
background-color: lightgray;
}
<!DOCTYPE html>
<html>
<head>
<title>Website</title>
<meta http-equiv="Content-Type" content="charset=UTF-8" />
<link rel="stylesheet" href="./mystyle.css" type="text/css">
<link href='https://fonts.googleapis.com/css?family=Amatic SC|Montserrat' rel='stylesheet'>
</head>
<body>
<video autoplay muted class="style" id="video">
<source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm" type="video/webm">
<p>The video is not working.</p>
</video>
<div id="menudisplay">
<img class="style" src="./img.jpg">
<ul>
<li>
EXEMPLE 1
</li>
<li>
EXEMPLE 2
</li>
</ul>
</div>
</body>
</html>
this should work,
const video = document.querySelector('video');
const menuDisplay = document.querySelector('#menudisplay');
video.addEventListener('ended', (event) => {
menuDisplay.style.display = 'block';
//you can also do things with 'event' obj
});
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended_event
you can use this script to detect when the video finished and what should be displayed after that:
video not supported
<script type='text/javascript'>
document.getElementById('myVideo').addEventListener('ended',myHandler,false);
function myHandler(e) {
// What you want to do after the event
}
</script>
like the others.
var video = document.getElementById("video");
var videoPl = document.getElementById("menudisplay");
video.addEventListener('ended', function(e) {
videoPl.style.display = 'block'
})
https://www.w3schools.com/jsref/event_onended.asp
My code is as follows
"use strict";
console.clear();
((d,w) => {
const cloneVideo = vid => {
const clone = vid.cloneNode(true);
clone.id += '-'
clone.style.display = 'none'
vid.parentElement.insertBefore(clone, vid);
return clone;
}
const getVideoSources = el => Array.from(el.querySelectorAll(":scope > source"));
const isTypeSupported = type => d.createElement("video").canPlayType(type);
const isMatchMedia = media => w.matchMedia(media).matches;
const onLoadeddata = (vid, clone) => e => {
const t = vid.currentTime;
vid.remove()
clone.currentTime = t;
clone.style.display = ''
clone.removeEventListener('loadeddata', onLoadeddata(vid, clone))
clone.play();
}
const updateVideoSources = vid => {
let changes = getVideoSources(vid).findIndex(src => isMatchMedia(src.media))
if (changes > 0) {
const clone = cloneVideo(vid);
let changes = getVideoSources(clone).filter(src => isMatchMedia(src.media))
changes.reverse().forEach(src => clone.prepend(src))
const id = vid.id
clone.addEventListener('loadeddata', onLoadeddata(vid, clone))
clone.load();
clone.id = id
return clone
}
return vid
};
const checkMedia = (video) => {
return (e) => {
// console.log(e)
video = updateVideoSources(video);
// console.log(39, video, video.parentElement)
}
}
w.checkMedia = checkMedia;
})(document,window);
{
const delay = 250;
const video = document.getElementById("vid");
const check = checkMedia(video)
window.addEventListener("DOMContentLoaded", check);
window.addEventListener("resize", debounce(check, delay));
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this,
args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
}
.container {
max-width: 925px;
margin: auto;
}
.clip {
position: relative;
width: 50%;
overflow: hidden;
display: -webkit-box;
display: flex;
}
.clip:before {
content: '';
padding-bottom: calc(100% * 506 / 448);
visibility: hidden;
pointer-events: none;
flex-basis: 0;
}
.clip:after {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #c3a88c;
background: #8a5d2f;
background: #ca935a;
background: #af8457;
mix-blend-mode: soft-light;
-webkit-clip-path: circle(farthest-side at 56.4% 50%);
clip-path: circle(farthest-side at 56.4% 50%);
}
#vid {
-webkit-clip-path: circle(farthest-side at 56.4% 50%);
clip-path: circle(farthest-side at 56.4% 50%);
-o-object-fit: cover;
object-fit: cover;
-o-object-position: 56.4% 50%;
object-position: 56.4% 50%;
}
#vid {
line-height: 0;
display: inline-block;
width: 100%;
}
body {
margin: 0;
padding: 0;
}
<div class="container">
<div class="clip">
<video id="vid" autoplay muted loop playsinline preload="auto" width="100%" height="auto">
<source data-number="1" src="https://assets.codepen.io/96344/pleyces-landing-page-video_240p.webm" type="video/webm" media="(max-width:527px)">
<source data-number="2" src="https://assets.codepen.io/96344/pleyces-landing-page-video_240p.ogv" type="video/ogg" media="(max-width:527px)">
<source data-number="3" src="https://assets.codepen.io/96344/pleyces-landing-page-video_240p.mp4" type="video/mp4" media="(max-width:527px)">
<source data-number="4" src="https://assets.codepen.io/96344/pleyces-landing-page-video_360p.webm" type="video/webm" media="(max-width: 719px) and (min-width:528px)">
<source data-number="5" src="https://assets.codepen.io/96344/pleyces-landing-page-video_360p.ogv" type="video/ogg" media="(max-width: 719px) and (min-width:528px)">
<source data-number="6" src="https://assets.codepen.io/96344/pleyces-landing-page-video_360p.mp4" type="video/webm" media="(max-width: 719px) and (min-width:528px)">
<source data-number="7" src="https://assets.codepen.io/96344/pleyces-landing-page-video_480p.webm" type="video/webm" media="(max-width: 899px) and (min-width:720px)">
<source data-number="8" src="https://assets.codepen.io/96344/pleyces-landing-page-video_480p.ogv" type="video/ogg" media="(max-width: 899px) and (min-width:720px)">
<source data-number="9" src="https://assets.codepen.io/96344/pleyces-landing-page-video_480p.mp4" type="video/mp4" media="(max-width: 899px) and (min-width:720px)">
<source data-number="10" src="https://assets.codepen.io/96344/pleyces-landing-page-video_600p.webm" type="video/webm" media="(min-width:900px)">
<source data-number="11" src="https://assets.codepen.io/96344/pleyces-landing-page-video_600p.ogv" type="video/ogg" media="(min-width:900px)">
<source data-number="12" src="https://assets.codepen.io/96344/pleyces-landing-page-video_600p.mp4" type="video/mp4" media="(min-width:900px)">
</video>
</div>
</div>
What this code does?
Since there is no support for media attributes of <source> elements inside <video> elements (See MDN), I needed to code a workaround. What I coded is: Listen to resize events (debounced) and check the media queries of each source, if it matches with window matchMedia. If some sources match, I change the order of the <source> tags and move the matches to be first children of the <video> elements.
After that I load the video again and jump to the memorized time.
Because this had the disadvantage of flickering when the sources changed (video disappeared and then appeared again), I needed a workaround. For this I clone the video before sorting and loading and then remove the original video after the clone has loaded (event loadeddata).
This prevents the flickering, but has another slight unpleasant behavior. The video jumps to the first video frame and then immediately to the time frame I memorized earlier.
Why does it do that? I set the currentTime before the play() action.
For this issue to show you need to test this in Full page mode and change the window width: I have three break points defined, where the video source should change: 528, 720 and 900 pixels. You can check that it's working by inspecting the Network tab in your Browser's Developer Tools.
I'm coding one audio player which play/pause on button but its also autoplaying. So first button that appears is Pause button and when its clicked it pauses the audio and changes to Play button. Now I tried to add text under it that says Playing or Paused. I managed to do that but its only happening when the button is clicked. So when I refresh the website there is no text under playing audio, then I have to click it and it will appear first Paused and then after one more hit Playing.
So I want Playing to be under Pause Button without needing to click it.
function changeImage() {
var image = document.getElementById('player');
if (image.src.match("pause")) {
image.src = "assets/img/icons/play.png";
document.getElementById("fetch").innerHTML = "Paused";
} else {
image.src = "assets/img/icons/pause.png";
document.getElementById("fetch").innerHTML = "Playing";
}
}
var playing = true;
function action() {
var audio = document.getElementById("audio");
if (playing === false) {
audio.play();
playing = true;
document.getElementById("append").innerHTML = "Playing";
} else {
audio.pause();
playing = false;
}
}
#audioplayer {
position: relative;
left: 65px;
bottom: 11px;
float: right;
z-index: 100;
cursor: pointer;
height: 81px;
width: 81px;
border-radius: 50%;
background-color: #0FB6D1;
}
#audioplayer:hover {
-moz-box-shadow: 0 0 20px #6854e7;
-webkit-box-shadow: 0 0 20px #6854e7;
box-shadow: 0px 0px 20px #6854e7;
}
#fetch {
font-family: 'gothic';
text-align: center;
font-weight: 500;
margin-left: 1.9px;
}
<div id="audioplayer">
<img id="player" onclick="action();changeImage();" src="assets/img/icons/pause.png" />
<audio id="audio" src="assets/music/music.wav" loop autoloop autoplay></audio>
<p id="fetch"></p>
<p id="append"></p>
</div>
I am not sure why you have "fetch" & "append" divs so I have removed one for this example.
document.getElementById('player').addEventListener('click', function() {
action();
});
var playing = true;
var image = document.getElementById('player');
function action() {
var audio = document.getElementById("audio");
if (playing === false) {
audio.play();
playing = true;
document.getElementById("fetch").innerHTML = "Playing";
image.src = "assets/img/icons/pause.png";
} else {
audio.pause();
playing = false;
document.getElementById("fetch").innerHTML = "Paused";
image.src = "assets/img/icons/play.png";
}
}
HTML:
<div id="audioplayer">
<img id="player" src="assets/img/icons/pause.png" />
<audio id="audio" src="assets/music/music.wav" loop autoloop autoplay></audio>
<p id="fetch">Playing</p>
</div>
Firstly I'm trying not to use the default html5 standard controls and I'd be happy to use jQuery if possible but I've taken it out for now as I was unsure of what the problem is.
At the moment I'm simply trying to have a play button which plays some music once clicked, which will change to a pause button. This pause button will then obviously pause the music once clicked.
I will leave some annotation in so you can see some of the things I have tried. Currently the play button appears but nothing happens when it is clicked.
Any help would be greatly appreciated.
HTML:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="javascript/audio-controls.js"></script>
<link rel="stylesheet" href="css/menu.css">
</head>
<div id="content-container">
<audio id="music">
<source src="media/mexico-music.mp3" type="audio/mpeg"/>
</audio>
<button id="play-music-button" class="play"></button>
</div>
CSS:
#play-music-button {
height:60px;
width: 60px;
border: none;
background-size: 50% 50%;
background-position: center;
}
.play {
background: url("../assets/play.png") no-repeat;
}
.pause {
background: url("../assets/pause.png") no-repeat;
}
JS:
$(document).ready(function() {
var music = document.getElementById("music");
var play_music_button = document.getElementById("play-music-button");
function playAudio() {
if (music.paused) {
music.play();
play_music_button.innerHTML = "Pause";
/*play-music-button.className = "";
play-music-button.className = "pause";*/
} else {
music.pause();
play_music_button.innerHTML = "Resume";
/*play-music-button.className = "";
play-music-button.className = "play";*/
}
music.addEventListener('ended',function() {
play_music_button.innerHTML = "Play";
});
}
play-music-button.addEventListener("click", playAudio);
});
You're calling play_music_button as play-music-button, and you've defined that twice when you only need it inside of your defined function. And you need to add an ended event listener to set the button back to "Play"
$(document).ready(function() {
var music = document.getElementById("music");
var play_music_button = document.getElementById("play-music-button");
function playAudio() {
if (music.paused) {
music.play();
play_music_button.className = 'pause';
} else {
music.pause();
play_music_button.className = 'play';
}
music.addEventListener('ended',function() {
play_music_button.className = 'play';
});
}
play_music_button.addEventListener("click", playAudio);
});
#play-music-button {
height: 60px;
width: 60px;
border: none;
background-size: 50% 50%;
background-position: center;
}
.play {
background: url("https://image.flaticon.com/icons/png/512/0/375.png") no-repeat;
}
.pause {
background: url("http://downloadicons.net/sites/default/files/pause-icon-14021.png") no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content-container">
<audio id="music">
<source src="http://skwaat.com/clips/iloveyou.mp3" type="audio/mpeg">
</audio>
<button id="play-music-button" class="play"></button>
</div>
This question already has answers here:
Using jQuery to control HTML5 <audio> volume
(4 answers)
Closed 9 years ago.
I know about the .play(), and the .stop() methods.
But is there a way to link up a slider to the volume? Or a slider to the track position? Is that possible?
And help is appreciated. Thanks!
jQuery UI makes it quite simple:
$(function() {
var $aud = $("#audio"),
$pp = $('#playpause'),
$vol = $('#volume'),
$bar = $("#progressbar"),
AUDIO= $aud[0];
AUDIO.volume = 0.75;
AUDIO.addEventListener("timeupdate", progress, false);
function getTime(t) {
var m=~~(t/60), s=~~(t % 60);
return (m<10?"0"+m:m)+':'+(s<10?"0"+s:s);
}
function progress() {
$bar.slider('value', ~~(100/AUDIO.duration*AUDIO.currentTime));
$pp.text(getTime(AUDIO.currentTime));
}
$vol.slider( {
value : AUDIO.volume*100,
slide : function(ev, ui) {
$vol.css({background:"hsla(180,"+ui.value+"%,50%,1)"});
AUDIO.volume = ui.value/100;
}
});
$bar.slider( {
value : AUDIO.currentTime,
slide : function(ev, ui) {
AUDIO.currentTime = AUDIO.duration/100*ui.value;
}
});
$pp.click(function() {
return AUDIO[AUDIO.paused?'play':'pause']();
});
});
#player{
position:relative;
margin:50px auto;
width:300px;
text-align:center;
font-family:Helvetica, Arial;
}
#playpause{
border:1px solid #eee;
cursor:pointer;
padding:12px 0;
color:#888;
font-size:12px;
border-radius:3px;
}
#playpause:hover{
border-color: #ccc;
}
#volume, #progressbar{
border:none;
height:2px;
}
#volume{
background:hsla(180,75%,50%,1);
}
#progressbar{
background:#ccc;
}
.ui-slider-handle{
border-radius:50%;
top: -5px !important;
width: 11px !important;
height: 11px !important;
margin-left:-5px !important;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-3.1.0.js"></script>
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="player">
<audio id="audio" src="http://upload.wikimedia.org/wikipedia/en/4/45/ACDC_-_Back_In_Black-sample.ogg" autoplay loop>
<p>Your browser does not support the audio element </p>
</audio>
<div id="volume"></div><br>
<div id="progressbar"></div><br>
<div id="playpause"></div>
</div>