Despite my readings I'm still limited in javascipt / soundJS syntax with using flash html5 canvas. I would like to pause and resume my sound with mouseover and mouseout events on the same button. I mean:
You hover the button: the music starts.
You mouseout: the music pauses.
You hover it again: it resumes from the position it has been paused with precedence.
According to the SoundInstance Class doc, you can do that with
myInstance.pause(); and myInstance.resume(); methods. And I suppose "var sound;" behaves likes "myInstance" since sound.pause(); works.
With the js code below I can pause the sound and resume my sound, but not on the same button, I need a button_2 to do that.
I think I'm missing a condition in mouseover function to "check if the sound is paused or not and then resume it or start playing.
var sound;
function fl_MouseOverHandler(){
sound = playSound("monstres");
}
this.mybutton.addEventListener("mouseover", fl_MouseOverHandler);
function fl_MouseOutHandler() {
sound.pause();
}
this.mybutton.addEventListener("mouseout", fl_MouseOutHandler);
function fl_MouseOverHandler_2(){
sound.resume();
}
this.mybutton_2.addEventListener("mouseover", fl_MouseOverHandler_2);
Any hint or link is welcome. Thank you.
what about something like this?
var isPlaying = false;
function togglePlayback(){
if(isPlaying){
isPlaying = false;
sound.pause();
} else {
isPlaying = true;
sound.resume();
}
}
this.some_button.addEventListener("some_event", togglePlayback );
You are an angel sent to earth.
Meanwhile I've found dome docs on javascript and managed to code my beloved function with something in the same spirit using a boolean variable.
Here's my code:
var playing = new Boolean(false);
function fl_MouseOverHandler() {
if (playing == false) {
exportRoot.soundInstance = playSound("monstres");
playing = true;
exportRoot.soundInstance.on("complete", handleComplete);
function handleLoop(event) {
exportRoot.soundInstance = playSound("monstres");
}
} else {
exportRoot.soundInstance.resume();
}
}
this.bout_zone_son.addEventListener("mouseover", fl_MouseOverHandler);
function fl_MouseOutHandler() {
exportRoot.soundInstance.pause();
}
this.bout_zone_son.addEventListener("mouseout", fl_MouseOutHandler);
I can't use if (playing) {....} syntax because:
i must first fire the sound with my button and then check if it's palying or not to resume it or start it.
I think I can't type sound.pause without first instanciating "sound = playSound("mylinkedsoundfromlibrary"); or my case exportRoot.soundInstance = playSound("monstres");
Well, thanx anyway for giving a shot in the right direction.
Related
I have used javascript Audio() before, but now I need to add some reverb effect in the audio and I am using reverb.js which uses the AudioContext api. I have the start property available, but no pause property? How do I pause or stop the audio??
Here is my code:
<script src="http://reverbjs.org/reverb.js"></script>
<script>
// 1) Setup your audio context (once) and extend with Reverb.js.
var audioContext = new (window.AudioContext || window.webkitAudioContext)();
reverbjs.extend(audioContext);
// 2) Load the impulse response; upon load, connect it to the audio output.
var reverbUrl = "http://reverbjs.org/Library/SaintLawrenceChurchMolenbeekWersbeekBelgium.m4a";
var reverbNode = audioContext.createReverbFromUrl(reverbUrl, function() {
reverbNode.connect(audioContext.destination);
});
// 3) Load a test sound; upon load, connect it to the reverb node.
var sourceUrl = "./sample.mp3";
var sourceNode = audioContext.createSourceFromUrl(sourceUrl, function() {
sourceNode.connect(reverbNode);
});
</script>
Play
Stop
Also, I tried using stop(), and it works, but when I fire start() after clicking on stop, the start() doesn't work. Can you you help me out with a solution??
You can use the suspend() and resume() methods of AudioContext to pause and resume your audio: https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/suspend
One way to implement this with a single button for play/pause/resume, would be to add a function that controls the player state. For example:
let started = false;
function pauseOrResume() {
if (!started) {
sourceNode.start();
started = true;
document.getElementById("pauseButton").innerHTML = 'Pause';
} else if (audioContext.state === 'running') {
audioContext.suspend().then(function () {
document.getElementById("pauseButton").innerHTML = 'Resume';
});
} else if (audioContext.state === 'suspended') {
audioContext.resume().then(function () {
document.getElementById("pauseButton").innerHTML = 'Pause';
});
}
}
And replace your existing "Play" button with:
<a id="pauseButton" href="javascript:pauseOrResume()">Play</a>
This does the following:
If the audio hasn't yet been started, the link will say "Play".
If the user clicks "Play", the audio will start playing and the text of the link will change to "Pause".
If the user clicks "Pause" while the audio is playing, it will be paused, and the text of the link will change to "Resume".
I am trying to stream video using links that expire every 2 minutes.
Basically, I use this function to replace the URL, and it works great:
function test(){
var videoFile = 'new.mp4';
var $video = $('#m video');
var curtime = $video[0].currentTime;
videoSrc = $('source', $video).attr('src', videoFile);
$video[0].load();
$video[0].currentTime = (curtime);
$video[0].play();
}
The question I have is how do I fire this function every time the video starts playing/after someone seeks in it? If i fire the ok(); function using a play event then it starts a loop since the function itself causes a play event.
Does anyone have any ideas on how to fix this in a good way?
The solution would be to register the play event once the video has actually started playing. That way it will react after a pause or a seek.
If you need to disable the event on other conditions then you simply disable the play event (as done in the start of the playing function)...
function test(){
var videoFile = 'trailer.mp4';
var $video = $('#video');
var curtime = $video[0].currentTime;
videoSrc = $('source', $video).attr('src', videoFile);
$video[0].load();
$video[0].currentTime = (curtime);
$video[0].play();
$video.on('playing', function () {
$video.off('play') // remove existing Play event if there is one
console.log("Play event bound")
$video.on('play', function () {
console.log("Video play. Current time of videoplay: " + $video[0].currentTime );
});
});
}
I have a template I'm building out using fullPage js to create sliding sections. The page supports video, but scroll and gestures are disabled when users scroll with the cursor on top of the video itself. Likewise, this behavior is observed on mobile.
To work around this, I'm using an empty div overlaying the youtube iframe. This solves the scrolling behavior, but I also lack the ability to directly control the youtube player. I've tried using the youtube API and jquery to fake being able to toggle play/pause with the empty div I have on top of the youtube player, but it's not working.
http://codepen.io/lumpeter/pen/XpayeB
The primary code for youtube is:
function onYouTubePlayerReady(playerId) {
ytplayer = document.getElementById("player");
ytplayer.addEventListener("onStateChange", "onPlayerStateChange");
}
function onPlayerReady(event) {
$('#video-button').click(function(event){
ytplayer.playVideo();
});
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
$('#video-button').click(function(event){
ytplayer.pauseVideo();
});
}
else {
$('#video-button').click(function(event){
ytplayer.playVideo();
});
}
}
Can anybody tell why this isn't working? I have event listeners looking for changes and using a boolean to detect the state of the video to toggle play/pause, but for some reason this doesn't work like I anticipated.
===============UPDATE=================
I've also tried the following:
$(document).on('click', '#pauseVideo', function(){
player = new YT.Player('myVideo')
if (event.data == player.PlayerState.PAUSED) {
$('#myVideo').get(0).contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}','*');
}
if (event.data == player.PlayerState.PLAYING) {
$('#myVideo').get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*');
}
});
However, I get the error "Uncaught ReferenceError: YT is not defined."
As fullpage.js already does part of the job by adding ?enablejsapi=1 and loading the JS script of the API for you, then you only have to do this:
var player;
window.onYouTubeIframeAPIReady = function() {
player = new YT.Player('myVideo');
}
$(document).on('click', '#pauseVideo', function(){
$('#myVideo').get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*');
});
Reproduction online
Thanks Alvaro! Yeah I was overthinking the solution a bit with the youtube api. I just needed to use a boolean with a binary true/false statement. Super easy, should have seen it before. Again thanks for your help!
var player;
window.onYouTubeIframeAPIReady = function() {
player = new YT.Player('myVideo',{
events: { 'onStateChange': onPlayerStateChange }
});
}
var isPlaying = true;
$(document).on('click', '#pauseVideo', function(){
if ( isPlaying == true){
$('#myVideo').get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*');
isPlaying = false;
} else {
$('#myVideo').get(0).contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}','*');
isPlaying = true;
}
});
I have read previous posts on this and documents by microsoft but cannot seem to get my app to run Sound in the background. It plays 100% but when ever the app is then suspended the music also stops. I have added "Background Tasks" declarations selecting Audio and my audio tag looks like this
<audio id="musicplayr" msAudioCategory="BackgroundCapableMedia" controls="controls"><source src="song.mp3"/> </audio
and finally my javascript includes the references to MediaControls
var MediaControls = Windows.Media.MediaControl;
// Add event listeners for the buttons
MediaControls.addEventListener("playpressed", play, false);
MediaControls.addEventListener("pausepressed", pause, false);
MediaControls.addEventListener("playpausetogglepressed", playpausetoggle, false);
// Add event listeners for the audio element
document.getElementById("musicplayr").addEventListener("playing", playing, false);
document.getElementById("musicplayr").addEventListener("paused", paused, false);
document.getElementById("musicplayr").addEventListener("ended", ended, false);
and below in the code i have the event handlers
// Define functions that will be the event handlers
function play() {
document.getElementById("musicplayr").play();
}
function pause() {
document.getElementById("musicplayr").pause();
}
function playpausetoggle() {
if(MediaControls.isPlaying === true) {
document.getElementById("musicplayr").pause();
} else {
document.getElementById("musicplayr").play();
}
}
function playing() {
Windows.Media.MediaControl.isPlaying = true;
}
function paused() {
Windows.Media.MediaControl.isPlaying = false;
}
function ended() {
Windows.Media.MediaControl.isPlaying = false;
}
*Note musicplayr is the reference for the html5 tag
Any help appreciated why this is not working?
You also need an event handler for the stoppressed event. Without any of the four handlers--playpressed, pausepressed, playpausetogglepressed, and stoppressed--background audio won't be enabled. See http://social.msdn.microsoft.com/Forums/en-IN/winappswithhtml5/thread/2ca0c122-df31-401c-a444-2149dd3e8d68 on the MSDN forums where the same problem was raised.
.Kraig
In order to get an HTML5 animation playing with sound on an idevice, I've made a div the size of the entire browser named "theScreen", and use the following code:
audioCont.prototype.iCrapLoadPlayThrough = function () {
if (this.supported) {
theScreen = document.getElementById("theScreen");
var self = this;
theScreen.addEventListener('touchstart', function(){self.iCrapClickedLoadPlayThrough();}, false);
return(1);
} else {
return(0); // Not supported
}
};
audioCont.prototype.iCrapClickedLoadPlayThrough = function () { // Check if supported, then load the audio file
var self = this;
theScreen.removeEventListener('touchstart', function(){self.iCrapClickedLoadPlayThrough();}, false);
this.addCanPlayThrough();
this.load();
}
Now this works, and the sound/animation starts when the user taps on the screen. The problem is, if they tap on it again the sound stops, and each repeat tap you hear a few ms of audio. Does anyone know why?
It's not removing the event listener because it's an anonymous function. Remove the anonymous function and just have the function name instead
theScreen.addEventListener('touchstart',self.iCrapClickedLoadPlayThrough,false)
theScreen.removeEventListener('touchstart',self.iCrapClickedLoadPlayThrough,true)
I've found a solution to the problem:
theScreen.addEventListener('touchstart', eventID=function() {self.iCrapClickedLoadPlayThrough();}, false);
then
theScreen.removeEventListener('touchstart', eventID, false);