I have a really simple bit of javascript that starts audio playback on mouseover of an image, and stops audio playback on mouseout.
How can I change the second function so that it fades the sound out gradually, rather than stopping it abruptly?
I have looked at other similar questions but I'm unfortunately still stuck.
<img onmouseover="PlaySound('mySound')"
onmouseout="StopSound('mySound')"
src="tictactoe.png">
<audio id='mySound' src='audio.mp3'/>
<script>
function PlaySound(soundobj) {
var thissound=document.getElementById(soundobj);
thissound.play();
}
function StopSound(soundobj) {
var thissound=document.getElementById(soundobj);
thissound.pause();
thissound.currentTime = 0;
}
</script>
It works effectively as it is, but it would be nice to add the fade out element. I know it's about setting the volume to decrease over time but I'm unsure of the right way to do that.
did you try use setInterval() and decrement the thissound.volume to 0 and then pause() ?
also maybe an increase for the start of the sound would also be a nice thing to do
Problem
I have a click handler that is meant to remove the class of .fa-pause then add a class of .fa-play if the audio is paused (and vice-versa). However, it doesn't do this until the second time I click the play button.
scripts.js
var audio = document.getElementById("painter");
$(".audio__play").click(function(){
if (audio.paused == true) {
$(this).removeClass("fa-pause");
$(this).addClass("fa-play");
audio.play();
} else {
$(this).removeClass("fa-play");
$(this).addClass("fa-pause");
audio.pause();
}
});
I am just guessing this. You may be mixing up the icon you want to use with the audio playing state.
For example, when audio.paused === true you are playing the audio with audio.play(). Shouldn't your button icon change to a pause icon at this point? If yes, then you should be removing fa-play and adding fa-pause and vice-versa when you pause the audio.
Does this work for you?
var audio = document.getElementById("painter");
$(".audio__play").click(function(){
if (audio.paused == true) {
// Audio is going to play so we set the
// pause icon on the button.
$(this).removeClass("fa-play");
.addClass("fa-pause");
audio.play();
} else {
// Audio is going to pause so we set the
// play icon on the button.
$(this).removeClass("fa-pause");
.addClass("fa-play");
audio.pause();
}
});
Here's a really simplistic working version of what you're trying to do. http://jsfiddle.net/W4Km8/7234/
I think your problem is that you are selecting something by class ".audio__play", then changing the class on it. That seems a little fishy to me. I changed the selector to an ID selector "#audio__play" in my example.
If you can't get it working, you need to post more code from your page.
I am playing a small audio clip on click of each link in my navigation
HTML Code:
<audio tabindex="0" id="beep-one" controls preload="auto" >
<source src="audio/Output 1-2.mp3">
<source src="audio/Output 1-2.ogg">
</audio>
JS code:
$('#links a').click(function(e) {
e.preventDefault();
var beepOne = $("#beep-one")[0];
beepOne.play();
});
It's working fine so far.
Issue is when a sound clip is already running and i click on any link nothing happens.
I tried to stop the already playing sound on click of link, but there is no direct event for that in HTML5's Audio API
I tried following code but it's not working
$.each($('audio'), function () {
$(this).stop();
});
Any suggestions please?
Instead of stop() you could try with:
sound.pause();
sound.currentTime = 0;
This should have the desired effect.
first you have to set an id for your audio element
in your js :
var ply = document.getElementById('player');
var oldSrc = ply.src;// just to remember the old source
ply.src = "";// to stop the player you have to replace the source with nothing
I was having same issue. A stop should stop the stream and onplay go to live if it is a radio. All solutions I saw had a disadvantage:
player.currentTime = 0 keeps downloading the stream.
player.src = '' raise error event
My solution:
var player = document.getElementById('radio');
player.pause();
player.src = player.src;
And the HTML
<audio src="http://radio-stream" id="radio" class="hidden" preload="none"></audio>
Here is my way of doing stop() method:
Somewhere in code:
audioCh1: document.createElement("audio");
and then in stop():
this.audioCh1.pause()
this.audioCh1.src = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAVFYAAFRWAAABAAgAZGF0YQAAAAA=';
In this way we don`t produce additional request, the old one is cancelled and our audio element is in clean state (tested in Chrome and FF) :>
This method works:
audio.pause();
audio.currentTime = 0;
But if you don't want to have to write these two lines of code every time you stop an audio you could do one of two things. The second I think is the more appropriate one and I'm not sure why the "gods of javascript standards" have not made this standard.
First method: create a function and pass the audio
function stopAudio(audio) {
audio.pause();
audio.currentTime = 0;
}
//then using it:
stopAudio(audio);
Second method (favoured): extend the Audio class:
Audio.prototype.stop = function() {
this.pause();
this.currentTime = 0;
};
I have this in a javascript file I called "AudioPlus.js" which I include in my html before any script that will be dealing with audio.
Then you can call the stop function on audio objects:
audio.stop();
FINALLY CHROME ISSUE WITH "canplaythrough":
I have not tested this in all browsers but this is a problem I came across in Chrome. If you try to set currentTime on an audio that has a "canplaythrough" event listener attached to it then you will trigger that event again which can lead to undesirable results.
So the solution, similar to all cases when you have attached an event listener that you really want to make sure it is not triggered again, is to remove the event listener after the first call. Something like this:
//note using jquery to attach the event. You can use plain javascript as well of course.
$(audio).on("canplaythrough", function() {
$(this).off("canplaythrough");
// rest of the code ...
});
BONUS:
Note that you can add even more custom methods to the Audio class (or any native javascript class for that matter).
For example if you wanted a "restart" method that restarted the audio it could look something like:
Audio.prototype.restart= function() {
this.pause();
this.currentTime = 0;
this.play();
};
It doesn't work sometimes in chrome,
sound.pause();
sound.currentTime = 0;
just change like that,
sound.currentTime = 0;
sound.pause();
From my own javascript function to toggle Play/Pause - since I'm handling a radio stream, I wanted it to clear the buffer so that the listener does not end up coming out of sync with the radio station.
function playStream() {
var player = document.getElementById('player');
(player.paused == true) ? toggle(0) : toggle(1);
}
function toggle(state) {
var player = document.getElementById('player');
var link = document.getElementById('radio-link');
var src = "http://192.81.248.91:8159/;";
switch(state) {
case 0:
player.src = src;
player.load();
player.play();
link.innerHTML = 'Pause';
player_state = 1;
break;
case 1:
player.pause();
player.currentTime = 0;
player.src = '';
link.innerHTML = 'Play';
player_state = 0;
break;
}
}
Turns out, just clearing the currentTime doesn't cut it under Chrome, needed to clear the source too and load it back in. Hope this helps.
As a side note and because I was recently using the stop method provided in the accepted answer, according to this link:
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events
by setting currentTime manually one may fire the 'canplaythrough' event on the audio element. In the link it mentions Firefox, but I encountered this event firing after setting currentTime manually on Chrome. So if you have behavior attached to this event you might end up in an audio loop.
shamangeorge wrote:
by setting currentTime manually one may fire the 'canplaythrough' event on the audio element.
This is indeed what will happen, and pausing will also trigger the pause event, both of which make this technique unsuitable for use as a "stop" method. Moreover, setting the src as suggested by zaki will make the player try to load the current page's URL as a media file (and fail) if autoplay is enabled - setting src to null is not allowed; it will always be treated as a URL. Short of destroying the player object there seems to be no good way of providing a "stop" method, so I would suggest just dropping the dedicated stop button and providing pause and skip back buttons instead - a stop button wouldn't really add any functionality.
This approach is "brute force", but it works assuming using jQuery is "allowed". Surround your "player" <audio></audio> tags with a div (here with an id of "plHolder").
<div id="plHolder">
<audio controls id="player">
...
</audio>
<div>
Then this javascript should work:
function stopAudio() {
var savePlayer = $('#plHolder').html(); // Save player code
$('#player').remove(); // Remove player from DOM
$('#FlHolder').html(savePlayer); // Restore it
}
I was looking for something similar due to making an application that could be used to layer sounds with each other for focus. What I ended up doing was - when selecting a sound, create the audio element with Javascript:
const audio = document.createElement('audio') as HTMLAudioElement;
audio.src = getSoundURL(clickedTrackId);
audio.id = `${clickedTrackId}-audio`;
console.log(audio.id);
audio.volume = 20/100;
audio.load();
audio.play();
Then, append child to document to actually surface the audio element
document.body.appendChild(audio);
Finally, when unselecting audio, you can stop and remove the audio element altogether - this will also stop streaming.
const audio = document.getElementById(`${clickedTrackId}-audio`) as HTMLAudioElement;
audio.pause();
audio.remove();
If you have several audio players on your site and you like to pause all of them:
$('audio').each( function() {
$(this)[0].pause();
});
I believe it would be good to check if the audio is playing state and reset the currentTime property.
if (sound.currentTime !== 0 && (sound.currentTime > 0 && sound.currentTime < sound.duration) {
sound.currentTime = 0;
}
sound.play();
for me that code working fine. (IE10+)
var Wmp = document.getElementById("MediaPlayer");
Wmp.controls.stop();
<object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6"
standby="Loading áudio..." style="width: 100%; height: 170px" id="MediaPlayer">...
Hope this help.
What I like to do is completely remove the control using Angular2 then it's reloaded when the next song has an audio path:
<audio id="audioplayer" *ngIf="song?.audio_path">
Then when I want to unload it in code I do this:
this.song = Object.assign({},this.song,{audio_path: null});
When the next song is assigned, the control gets completely recreated from scratch:
this.song = this.songOnDeck;
The simple way to get around this error is to catch the error.
audioElement.play() returns a promise, so the following code with a .catch() should suffice manage this issue:
function playSound(sound) {
sfx.pause();
sfx.currentTime = 0;
sfx.src = sound;
sfx.play().catch(e => e);
}
Note: You may want to replace the arrow function with an anonymous function for backward compatibility.
In IE 11 I used combined variant:
player.currentTime = 0;
player.pause();
player.currentTime = 0;
Only 2 times repeat prevents IE from continuing loading media stream after pause() and flooding a disk by that.
What's wrong with simply this?
audio.load()
As stated by the spec and on MDN, respectively:
Playback of any previously playing media resource for this element stops.
Calling load() aborts all ongoing operations involving this media element
I am working on a iPad HTML app that has two videos in it. The HTML code is loaded dynamically. The page has two videos with text corresponding to them. The videos also have just two controls. Play and Pause. However the issue I am having is the Video will only pause when the other is playing. Basically in my if / else statement the else is not being called at all. Here is my code. Anyone know why it won't pause when trying to click on the overlay again? Thank you in advance!
$('div[class*="video-overlay"]').bind('mousedown', function() {
var video = $(this).next('video')[0];
var text = $(this).attr('data-play');
if (video.paused) {
video.play();
$('p').addClass('fade');
$('#' + text).removeClass('fade');
$(this).removeClass('overlay');
$('div[class*="video-overlay"]').not(this).addClass('overlay');
$(this).children().removeClass('video-play');
$('video').not($(this).next(el)).get(0).pause();
$('.play').not($(this).children()).addClass('video-play');
$(video).on('ended', function() {
$(this).prev('div').children().addClass('video-play');
video.pause();
});
} else {
video.pause();
console.log('Hey mom, I paused all by myself!');
}
});
Without your html, I can't be sure, so I can only guess.
var video = $(this).next('video')[0];
change this line to
var video = $(this).find('video')[0];
To get a more definite answer, please provide your html code.
It was actually in my CSS. I didn't have the overlay in front of the video. So I changed the z-index to a higher value and the fixed it. I had the play button in front so it was playing the video, just not the overlay. Doh!
I'm making a HTML5 video player. I want it so that when the movie stops the play these executes
video.pause();
video.currentTime=0;
document.getElementById('message').innerHTML="Finished";
I tried this but it didn't work
function rewsi() {
var video = document.getElementsByTagName('video')[0];
if (video.currentTime==video.duration) {
video.pause();
video.currentTime=0;
document.getElementById('message').innerHTML="Finished";
}
}
Anyone got a solution for this problem?
Problem = My lack of knowledge in JavaScript
Looking at the following question and asnwer:
HTML5 <video> callbacks?
I would assign a callback to be executed when the video has actually ended like so:
var Media = document.getElementsByTagName('video')[0];
var Message = document.getElementById('message');
Media.bind('ended',function(){
Message.innerHTML = "The media file has completed";
});
You also stated that when the media 'stops' you want to pause the video, can you describe your motives for doing that ?
The next on the agenda is the video resetting as such, looks like you want to set the position of the media to the start if the media stops, you must first make sure that your determining that the video has not been paused, as you do not want to reset the position if the user has gone to make a cup of coffee.
If you only want to set the media position when the movie has actually ended then this would be pointless (unless you have a valid reason to do so), the reason it would be pointless is that when the user clicks play after it has ended, the default action html5 media player takes is to set the position to 0.
The above solution should work out exactly right for you.
i will recommend using Kaltura HTML5 Video Library to help you manage the media player.
First, you can check if the video has ended by simply putting a condition on video.ended. Then you can set the time with this.currentTime(0);