rubing Posted May 28, 2008 Share Posted May 28, 2008 hey all! i'm working with an mp3 streaming javascript (soundmanager2). I have a function for switching a play button to a pause button while playing and vise versa: <script type="text/javascript"> var playing = false; function playMusic(soundID) { if (playing) { document.player.src='/images/bigplay.png'; soundManager.pause(soundID); playing = false; } else { soundManager.play(soundID); playing = true; document.player.src='/images/bigpause.png'; } } </script> However after it finishes playing the song it does not switch back to the play button :-( I tried adding the following code based on a soundmanager event to my anchor tag, which didn't work: onfinish:function() {document.player.src='/images/bigplay.png'}; Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted May 28, 2008 Share Posted May 28, 2008 Without looking at the soundmanager code, your custom code looks a bit odd. Basically, you want a toggle, so you'd have to attach an onclick function to your button that does two things: toggles between playing and pausing music, and toggles between showing the play button image and the pause button image. So, pseudo-code, it would be something like: <script type="text/javascript"> //this assumes window.onload = blah blah blah var playerButton = document.getElementById("playerButton"); //whatever element you're using to control the play. playerButton.onclick = function() { if(this.src == "/images/bigplay.png") { this.src = "/images/bigpause.png"; soundManager.play(soundID); } else { this.src="/images/bigplay.png"; soundManager.pause(soundID); } } </script> Again, this is all without looking at the actual sound manager code. Does the sound manager script have an onfinish event you can attach a function to? Because I don't believe something like that exists natively in JavaScript (although I could be wrong). Quote Link to comment Share on other sites More sharing options...
rubing Posted May 28, 2008 Author Share Posted May 28, 2008 Yup, soundmanager does have a native onfinish. Its used to play a sequence of sounds, for example: soundManager.play('aDrumSound',{onfinish:function(){soundManager.play('aCymbalSound');}}) How is setting the image tag to toggle instead of the anchor going to reset the image when its done playing? It didn't seem to work. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted May 28, 2008 Share Posted May 28, 2008 Yup, soundmanager does have a native onfinish. Its used to play a sequence of sounds, for example: soundManager.play('aDrumSound',{onfinish:function(){soundManager.play('aCymbalSound');}}) How is setting the image tag to toggle instead of the anchor going to reset the image when its done playing? It didn't seem to work. I see what the problem is. You're mixing/matching code without really understanding how to implement the changes that Aaron and I suggested. Okay, here's what to do: 1. Remove the anchor tag. You don't need a hyperlink in order to do onclick things, and since you don't want the user to go to another page, it's ultimately useless to have an anchor there anyway. So, in its stead, simply have: <img id="player" src="images/bigplay.png" alt="audio player control" /> 2. Use unobtrusive JavaScript. What does that mean? It means the elimination of JavaScript function calls from your HTML markup. See how my modified img tag has no JavaScript in it? That's a good thing. It keeps your script code centralized, and makes it easier to implement and debug. Not only that, but there's no need for your markup to have any knowledge of your script. So, replace ALL script code with the following: <script type="text/javascript" src="soundmanager2.js"></script> <script type="text/javascript"> window.onload = function() //this ensures the DOM exists before we start trying to play with it { soundManager.url = 'soundmanager2.swf'; // override default SWF url soundManager.debugMode = false; soundManager.consoleOnly = false; soundManager.onload = function() { soundManager.createSound({id:'mySound',url:'Rick.mp3'}); //NOTE: if this doesn't work, replace it with: soundManager.createSound("mySound", "Rick.mp3"); } var playerButton = document.getElementById("player"); playerButton.onclick = function() { if(this.src == "images/bigplay.png") { this.src = "images/bigpause.png"; soundManager.play("mySound"); } else { this.src="images/bigplay.png"; soundManager.pause("mySound"); } } soundManager.onfinish = function() { playerButton.src = "images/bigstop.png"; //if you have a big stop image...if not, use bigpause.png } } </script> With this, your code will (hopefully) work correctly, and be easier to maintain. Keep in mind, however, that some of this code is making assumptions on how the soundmanager package works. The best thing you can do to test it is to try it in Firefox, and report back any errors the error console finds. Let me know if you need any help doing that. Quote Link to comment Share on other sites More sharing options...
rubing Posted May 28, 2008 Author Share Posted May 28, 2008 I am all in favor of unobtrusiveness! Unfortunately, it doesn't seem to work now that i took out the anchor. Maybe you could also clue me in to your code workings, for instance: if(this.src == "images/bigplay.png") { this.src = "images/bigpause.png"; soundManager.play("mySound"); } else { this.src="images/bigplay.png"; soundManager.pause("mySound"); } My understanding is as follows: If when clicked the image is bigplay.png, we want to change it to bigpause.png and start playing the music (Great!!). ,but the next 2 lines I don't get: Else the image is bigplay.pn, and we tell it to pause. Shouldn't this be an elseif statement that basically says if the image is bigpause.png when clicked, then change it to bigplay.png and pause the music. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted May 29, 2008 Share Posted May 29, 2008 I am all in favor of unobtrusiveness! Unfortunately, it doesn't seem to work now that i took out the anchor. Maybe you could also clue me in to your code workings, for instance: if(this.src == "images/bigplay.png") { this.src = "images/bigpause.png"; soundManager.play("mySound"); } else { this.src="images/bigplay.png"; soundManager.pause("mySound"); } My understanding is as follows: If when clicked the image is bigplay.png, we want to change it to bigpause.png and start playing the music (Great!!). ,but the next 2 lines I don't get: Else the image is bigplay.pn, and we tell it to pause. Shouldn't this be an elseif statement that basically says if the image is bigpause.png when clicked, then change it to bigplay.png and pause the music. Nope, because you only have two choices - play or pause. So, to clarify, here's a verbal run through the code: When the image is clicked, we check the current value assigned to its source attribute. If it is the play button, we change it to be the pause button and play the song. Else we know it's currently the pause button (because there are only two possible choices), so we change it to be the play button, and we pause the song. Since there are only two possible choices, we only have to check for one of them. If the check fails (i.e., this.src != "images/bigplay.png"), then you can be sure the other option is the one currently in play. You'll find that most code that toggles element properties is written in a similar fashion. Quote Link to comment Share on other sites More sharing options...
rubing Posted May 29, 2008 Author Share Posted May 29, 2008 Yes... of course you only need to check for 1 value!! For some reason the relative path in my first if statement: if(this.src == "images/bigplay.png") is evaulated as false, so instead I have to use the full URL. wierd. i still haven't gotten that onfinish:function() to work. i'm gonna try to poke around on the soundmanager2 site for more info. maybe i can use one of the class variables - playState instead. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted May 29, 2008 Share Posted May 29, 2008 Does the image toggle work with the full path, though? Quote Link to comment Share on other sites More sharing options...
rubing Posted May 29, 2008 Author Share Posted May 29, 2008 Yes, it works fine...so no problem i guess, just strange. My problem seems to be in getting onfinish function to work right. If i tell it to do something like: alert(this.sID+' finished playing'); It works fine and throws out an alert on finish, however if I try to get it to replace the image as follows: this.src="http://www.birminghammusiclive.com/images/bigplay.png" The whole player breaks and shows this error in the debug window: Warning: soundManager.onload() is undefined. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted May 29, 2008 Share Posted May 29, 2008 Looking at your code...yeah, it's still a mess. Quick question: is this the code you're actually trying to use, or are you in the middle of rewriting it? Because, right now, things look to be thrown together rather randomly (such as adding the onfinish part to the onclick handler, etc, which is definitely not what I had written before). Onfinish fails, most likely, because the code used to create a sound (createSound("mySound", "Rick.mp3")) is commented out. The '//' in front of it tells the browser to ignore it and treat it like code documentation rather than an actual instruction. Chances are, since there's no sound, as the code that creates it is virtually non-existant, the onfinish event fires automatically. Here's another attempt at getting it to work. Once again, replace ALL of your script code with the following: <script type="text/javascript" src="soundmanager2.js"></script> <script type="text/javascript"> window.onload = function() { soundManager.url = 'soundmanager2.swf'; // override default SWF url soundManager.debugMode = false; soundManager.consoleOnly = false; soundManager.onload = function() { soundManager.createSound('mySound','Rick.mp3'); } var playerButton = document.getElementById("player"); playerButton.onclick = function() { if(this.src == "http://www.birminghammusiclive.com/images/bigplay.png") { this.src = "http://www.birminghammusiclive.com/images/bigpause.png"; soundManager.play("mySound"); } else { this.src = "http://www.birminghammusiclive.com/images/bigplay.png"; soundManager.pause("mySound"); } } //END OF ONCLICK FUNCTION -- DO NOT ADD ANYTHING ELSE TO THIS!!!!!!!!!!!!!!!! soundManager.onfinish = function() { playerButton.src = "http://www.birminghammusiclive.com/images/bigplay.png"; } //END OF ONFINISH FUNCTION -- DO NOT TOUCH!!!!!!!!!!!!!!!! } </script> Here's a verbal description of the code: We wait until the entire page is loaded (window.onload) before we attach our JavaScript to the page. Once it is loaded, we initialize some values, and create functions that are invoked when certain events fire. Event 1: When the sound manager script is loaded (soundManager.onload), we load the correct song (createSound("mySound", "Rick.mp3")). Event 2: When the play button is clicked (playerButton.onclick), we do two simultaneous toggles -- one for the button's image (changing it from pause to play, and back again), and one for the song itself (actually playing and pausing the audio file). Event 3: When the song is finished (soundManager.onfinish), we make sure that the play button has the correct image, telling the user that it can be played again. If soundManager.onload still fails, let me know, but DO NOT attempt to fix it by randomly mashing functions together. They are separate for a reason. Regarding soundManager.onload failing, chances are, you simply need to do a simple assignment to initialize that variable, something like: var soundManager = new SoundManager(); Hold off on doing that, however, until you test the code I wrote above. If it doesn't fix the issue, let me know, so I can find some sound manager documentation and initialize the variable correctly. Quote Link to comment Share on other sites More sharing options...
rubing Posted May 29, 2008 Author Share Posted May 29, 2008 Ok, I put it back your script, but commented out the onfinish function. B/c it turns out there is no there is no global soundManager.onfinish() handler. It works other than being stuck with a big pause button at the end of the clip. The basic api with onfinish examples can be found here: http://schillmania.com/projects/soundmanager2/demo/basic/ Usually, it's used to play a series of sounds (which, is what i eventually want to do). So, I rather find some other means of resetting the play button. One of the SMSound (Sound Object) Properties listed is playState: playState Numeric value indicating the current playing state of the sound. 0 = stopped/uninitialised 1 = playing or buffering sound (play has been called, waiting for data etc.) Note that a 1 may not always guarantee that sound is being heard, given buffering and autoPlay status. Maybe I can tell it to switch to /images/bigplay.png if playState==0 ?? Unfortunately, I tried coding something like that before and it failed. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted May 29, 2008 Share Posted May 29, 2008 I think you can still use the onfinish event to swap images. Try the following: <script type="text/javascript"> window.onload = function() { soundManager.url = 'soundmanager2.swf'; // override default SWF url soundManager.debugMode = false; soundManager.consoleOnly = false; soundmanager.onload = function() { var playerButton = document.getElementById("player"); //need it before the onfinish event var mySoundObj = soundmanager.createSound( { id: "mySound", url: "Rick.mp3", onfinish: function() { playerButton.src = "http://www.birminghammusiclive.com/images/bigplay.png"; } }); //uses object literal notation just to be safe playerButton.onclick = function() { if(this.src == "http://www.birminghammusiclive.com/images/bigplay.png") { this.src = "http://www.birminghammusiclive.com/images/bigpause.png"; mySoundObj.play(); } else { this.src = "http://www.birminghammusiclive.com/images/bigplay.png"; mySoundObj.pause(); } //end else } //end onclick } //end soundmanager.onload } //end window.onload </script> The biggest difference here is that instead of using the quick version of createSound, I decided to switch it to the object version instead. It allows us to use the playState property in case the above code doesn't work. We can just swap out a few lines of code if need be. Also, onfinish is now part of createSound as well. Since we're now creating a new sound object, it makes sense to add it to the list of object properties. The function is the same, just in a different spot. Let me know if this works. Quote Link to comment Share on other sites More sharing options...
rubing Posted May 29, 2008 Author Share Posted May 29, 2008 Before I got your code I got it to work on this page: http://www.birminghammusiclive.com/indexd.php , althought your code is very similar for some reason it does not work (see page indexb.php) I rather reset the image by referencing the playState property. Unless, I can use onfinish for playing a sequence of music clips and resetting the image ??? Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted May 29, 2008 Share Posted May 29, 2008 Unfortunately, from a logical standpoint, you can't use the playState property by itself. It makes no sense to check for it just once, and trying to create a custom loop to keep testing it is a major pain. So, using onfinish is the way to go. Unfortunately, it looks like the soundmanager is having some issues loading. I'm not sure what's causing it, though, because according to the script's documentation, a soundManager object should be globally available from the get-go. So, here's one last attempt at getting it to work. If it doesn't, I suggest contacting the people who made the soundManager library itself. It shouldn't be this difficult to combine it with normal, simple JavaScript. Anyway, here is another attempt: <script type="text/javascript"> window.onload = function() { soundmanager.onload = function() { soundManager.url = 'soundmanager2.swf'; // override default SWF url soundManager.debugMode = false; soundManager.consoleOnly = false; var playerButton = document.getElementById("player"); //need it before the onfinish event var mySoundObj = soundmanager.createSound( { id: "mySound", url: "Rick.mp3", onfinish: function() { playerButton.src = "http://www.birminghammusiclive.com/images/bigplay.png"; } }); //uses object literal notation just to be safe playerButton.onclick = function() { if(this.src == "http://www.birminghammusiclive.com/images/bigplay.png") { this.src = "http://www.birminghammusiclive.com/images/bigpause.png"; mySoundObj.play(); } else { this.src = "http://www.birminghammusiclive.com/images/bigplay.png"; mySoundObj.pause(); } //end else } //end onclick } //end soundmanager.onload } //end window.onload </script> Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted May 29, 2008 Share Posted May 29, 2008 I just tried this test. It seems to work okay, but it can't connect to your .swf file, so I can't see if the onclick event handler is working (apparently, sound manage disables everything if something can't load correctly). Let me know if the following works: <script type="text/javascript"> soundManager.onload = function() { soundManager.url = "http://www.birminghammusiclive.com/soundmanager2.swf"; // override default SWF url soundManager.debugMode = false; soundManager.consoleOnly = false; var playerButton = document.getElementById("player"); //need it before the onfinish event var mySoundObj = soundManager.createSound( { id: "mySound", url: "http://www.birminghammusiclive.com/Rick.mp3", onfinish: function() { playerButton.src = "http://www.birminghammusiclive.com/images/bigplay.png"; } }); //uses object literal notation just to be safe playerButton.onclick = function() { if(this.src == "http://www.birminghammusiclive.com/images/bigplay.png") { this.src = "http://www.birminghammusiclive.com/images/bigpause.png"; mySoundObj.play(); } else { this.src = "http://www.birminghammusiclive.com/images/bigplay.png"; mySoundObj.pause(); } //end else } //end onclick } //end onload </script> Quote Link to comment Share on other sites More sharing options...
rubing Posted May 30, 2008 Author Share Posted May 30, 2008 Yup it works perfect! I owe you a beer whenever you're in bham. This has been quite a fast and dirty intro javascript...much better than reading the beginning wrox book at my library. Now, I gotta try and make an array of sound objects with php. Quote Link to comment Share on other sites More sharing options...
KevinM1 Posted May 30, 2008 Share Posted May 30, 2008 Yup it works perfect! I owe you a beer whenever you're in bham. This has been quite a fast and dirty intro javascript...much better than reading the beginning wrox book at my library. Now, I gotta try and make an array of sound objects with php. Phew! I'm happy it's finally working. It looks like there was a conflict between the window.onload event and the soundManager.onload event. When you get more comfortable with JavaScript, I recommend getting the book Pro JavaScript Techniques by John Resig. It's a fast-paced book, but it really helped clarify JS for me. Good luck with the PHP backend. Let me know if you need any assistance. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.