• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

HTML5 Canvas: Method for calling Sound Effects no longer working

Explorer ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

Hello,

This is my second post within the year about calling simple sound effects from within my Animate HTML5 Canvas project. My work is to create interactive children's lessons which involve a main timeline of 6 frames with navigation buttons allowing the user to cycle through the 6 frames forward and backward. On each of the 6 frames are numerous simple animations and interactive elements such as nested movieclips, buttons, drag and drop with targets, etc. Throughout the program I use very short sound effects which are played when certain frames are reached within my nested movieclips, or when a button is clicked, etc. Currently, I have been importing the .mp3s to my library, giving them a Linkage name in the library (i.e. "SELsound1"), and then using this code on the appropriate frame or in the appropriate function to play the sound effect:

 

createjs.Sound.play("SELsound1", false, 0, 0, 0, 1);

 

This had been working fine until my last update of Animate. (I am now using Animate 20.0). Now when I publish my HTML 5 Canvas document, the sound effects do not play and I get this error over and over: 

 

TypeError: undefined is not an object (evaluating 'd.startTime')

 

I simply do not understand the correct way of calling simple sound effects from my library using code on specific timline frames. After receiving the above error, I am attempting now to call sound effects with this code:

 

createjs.Sound.registerSound("sounds1/SPsound1.mp3", "RegSPsound1");

createjs.Sound.play("RegSPsound1");

 

This works the first time the timeline is cycled through forward, however when I used the navigational arrows to cycle backwards through my main timeline, all the sound effects called within each frame (even those late within the timeline of nested MovieClips on that frame) all play at once.

 

I should say that I have read documentation on SoundJS, I just do not understand it. Most the of examples I see include a function that plays the sound after fileload, but I want to play the sound when a certain frame is reached in a timeline, and perhaps the same sound effects on multiple timeline frames, not just once initially after the file has loaded:

 

createjs.Sound.on("fileload", handleLoad);
function handleLoad(){
createjs.Sound.play("RegSPsound1");
}
 

 This task was so easy to accomplish in Flash/AS3. Any guidance is appreciated. Thanks in advance...

TOPICS
Code , Error , Timeline

Views

987

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

Animate 2020 switched to CreateJS 1.0.0, which changed the syntax of the play method.

https://createjs.com/docs/soundjs/classes/Sound.html#method_play

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

Ok I beleive this is a start. But I am still very confused and not achieving what I'd like. What am I doing incorrectly?

 

I have a main timeline with 6 frames. On frame 1, I have a nested movieclip. On frame 10 of the nested movieclip I have placed this code:

 

createjs.Sound.on("fileload", handleLoad);
createjs.Sound.registerSound("sounds1/SPsound1.mp3", "RegSPsound1", 3);
function handleLoad(event) {
createjs.Sound.play("RegSPsound1");
// store off AbstractSoundInstance for controlling
var myInstance = createjs.Sound.play("RegSPsound1", {interrupt: createjs.Sound.INTERRUPT_ANY, loop:0});
}

 

This works fine the first time frame 10 of the movieclip is reached, however when I want to play a different sound effect on a later frame of that movieclip, I put this code again with a new ID and run into issues:

 

(For example, this code is in frame 50 of the same nested movieclip:)

createjs.Sound.on("fileload", handleLoad2);
createjs.Sound.registerSound("sounds1/SPsound2.mp3", "RegSPsound2", 3);
function handleLoad2(event) {
createjs.Sound.play("RegSPsound2");
// store off AbstractSoundInstance for controlling
var myInstance2 = createjs.Sound.play("RegSPsound2", {interrupt: createjs.Sound.INTERRUPT_ANY, loop:0});
}

 

What happens is BOTH sound effects play at the same time when frame 50 is reached.

 

Another issue: When I advance the main timeline to frame 2, and then return to play frame 1, neither sound effect plays the second time. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

Update:

I have tried using this code on the nested movieclip frames 10 and 50 with some success:

 

(Frame 10:)

var props = new createjs.PlayPropsConfig().set({interrupt: createjs.Sound.INTERRUPT_ANY, loop: 0, startTime: 0, duration: 2000})
createjs.Sound.play("SPsound1", props);

 

(Frame 50:)

var props = new createjs.PlayPropsConfig().set({interrupt: createjs.Sound.INTERRUPT_ANY, loop: 0, startTime: 0, duration: 2000})
createjs.Sound.play("SPsound2", props);

 

Each sound effect plays once when its respected frame is reached within the nested movieclip, HOWEVER, when I navigate within the main timeline, from frame 1 (where the nested movieclip is located) to frame 2, and then back to frame 1, both sound effects play instantly upon returning to frame 1 of the main timeline. Then, they play correctly as the nested movieclip plays (when frames 10 and 50 are reached within the nested movieclip). This is the same issue I was having with previous code attempts-- why are the sound effects playing instantly before their respective frames are reached within the nested movieclip? (Note, the nested movieclip is not even set play automatically– I have a button triggering its start.)

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

If you have a start button to play the movieclips I would not even put the sound oon the movie timeline.

Since you have a linkage name here is what I would use on the click event. I would put that in Frame 1 of main timeline. then you can use the variable to control the sound like

this.SPsound2.paused = true;

 

var root = this;
this.startBtn.addEventListener("click", startSound.bind(this));

function startSound() {
	root.movieclip.gotoAndPlay(framename or number);  // or whatever you want
	this.SPsound2= createjs.Sound.play("SPsound2", "none", 0, 0, -1, 0.4);

// play ( src  [interrupt="none"|options]  [delay=0]  [offset=0]  [loop=0]  [volume=1]  [pan=0]  [startTime=null] [duration=null] )
// here I set loop to -1 which means it is looping

}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

Thank you for your help redesign, however most of my sound effects are not triggered by buttons, but simply when a nested movieclip reaches a specific frame. I was just including one example of hundreds of instances of sound effects needed in my project.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

Another update:

After doing some problem-solving, I have discovered that the instant playing of all sound clips which are called in nested movieclips on the main timeline frame only happens to one level nested movieclips. If I nest all my movieclips within OTHER nested movieclips (two levels nested), then their respective sound effects do not instantly play when the user returns to Frame 1 of the main timeline from Frame 2. The sound effects called in the double nested movieclips play normally, when their appropriate frames are reached.

So, this is a work-around. However it seems I must be doing something basically wrong and I'd like to learn the correct methods. Thanks again for potential help...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

You realize you're never removing your sound load event listeners, right? Of course it keeps firing all of them as you keep adding them. It's doing exactly what you're telling it to do.

 

And unless you have a hundred different sounds, loading the sound files on demand is a bad idea. You should load all the sounds you'll need up front so they'll play immediately when needed.

https://createjs.com/docs/soundjs/classes/Sound.html#method_registerSounds

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

Thank you ClayUUID, this is very helpful. Could you please guide me how to remove the event listener of each added sound? I know how to remove event listeners from button functions, but I'm lost with this createjs.Sound. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

I don't understand where I am adding new sound load event listeners, since the code to load the sound effects is not listed until frames 10 and 50 of the nested movieclip. The sounds are all playing simultaneously when the user returns simply to the main timeline frame where the nested movieclip is located, before the movieclip is even triggered to play.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

.on() adds an event listener. If you only want it to fire once, you have to add true as fourth argument.

https://www.createjs.com/docs/easeljs/classes/EventDispatcher.html#method_on

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 04, 2019 Dec 04, 2019

Copy link to clipboard

Copied

ClayUUID I am not using .on() anywhere.

I am registering the sounds in frame 1 of my main timeline like this:

createjs.Sound.registerSound("sounds1/SPsound1.mp3", "RegSPsound1");
createjs.Sound.registerSound("sounds1/SPsound2.mp3", "RegSPsound2");

 

Then I am calling them from specific frames of a nested movieclip like this:

(Frame 10 within nestest movie clip:)

createjs.Sound.play("RegSPsound1");

 

(Frame 50 within nestest movie clip:)

createjs.Sound.play("RegSPsound2");

 

If the movieclip is only nested one level deep, all sound effects play simultaneously when the main timeline frame where the nested movieclip is located is returned to a second time. Then, each sound effect plays normally when its repsective frame within the nested movieclip is reached.

 

If I use the below code to call sound effects, there are many issues. 1.) It seems I can only call the sound effect one single time– when the file loads. When the user plays the nested movieclip twice, the second time no sound effects play. 2.) I am unable to call the same sound effect again in a different frame-- is this possible? 3.) When I try to add a different sound effect, on a new frame, using this code structure, both sound effects play instead of just the new sound effect-- why is that happening?

 

createjs.Sound.on("fileload", handleLoad);
createjs.Sound.registerSound("sounds1/SPsound5.mp3", "RegSPsound5", true);
function handleLoad(event) {
createjs.Sound.play("RegSPsound5");
// store off AbstractSoundInstance for controlling
var myInstance = createjs.Sound.play("RegSPsound5", {interrupt: createjs.Sound.INTERRUPT_ANY, loop:0});
}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 05, 2019 Dec 05, 2019

Copy link to clipboard

Copied

You: "I am not using .on() anywhere."

Also you: "createjs.Sound.on("fileload", handleLoad);"

 

Look, you have to ask yourself "What is this code actually doing?" You can't just blindly copy-paste code without understanding what it does, because then you'll perpetually end up in situations like this where things aren't working and you have no clue why.

 

Put in plain English, this is what the above code does: Load and register a sound, and then when the sound finishes loading, play it. So why isn't the sound playing the second time?

 

.

 

.

 

.

 

Because it's already loaded. You put your play statement in your load handler, which is only ever called exactly once, when the sound first loads. CreateJS isn't going to load the same sound twice, is it? That wouldn't be very efficient.

 

Like I already said, you should be preloading all your sounds first at the beginning of the page, then just playing them as needed.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 05, 2019 Dec 05, 2019

Copy link to clipboard

Copied

Hi Clay UUID,

I do thank you for your energy, and I'm aware my post has gotten quite confusing due to my own attempts at problem-solving and updating. 

 

I of course aim to be aware of what the code I am using is acutally doing and am not blindly cutting and pasting, although I am indeed very new to HTML5 Canavs and the CreateJS library. 

 

So to explain more clearly my current dilema:

I have a main timeline which consists of 6 frames, and multiple nested movieclips within each of those 6 frames. I am attempting to call short sound effects (mp3s which have beed added to my library) to play when a specific frame is reached within the nested movieclips.

 

I initially acheived this by placing this code in the desired frame of any movieclip:

createjs.Sound.play("SELsound1", false, 0, 0, 0, 1); //"SELsound1" being the linkage name from my library.

 

I am now receiving an error with this code and as you have informed me, CreateJS 1.0.0 changed the syntax of the play method. 

 

So I attempted to use the correct method of calling sound effects and I am registering all my sound effects in frame 1 of my main timeline like this:

 

createjs.Sound.registerSound("sounds1/SPsound1.mp3", "RegSPsound1");
createjs.Sound.registerSound("sounds1/SPsound2.mp3", "RegSPsound2");
createjs.Sound.registerSound("sounds1/SPsound3.mp3", "RegSPsound3");

 

And then I am calling the sounds to play in specific frames of nested movieclips within the main timeline like this:

(Frame 10 of a movieclip nested on Frame 1 of the main timeline:)

createjs.Sound.play("RegSPsound1");

 

(Frame 10 of a movieclip nested on Frame 2 of the main timeline:)

createjs.Sound.play("RegSPsound2");

 

(Frame 50 of a movieclip nested on Frame 2 of the main timeline:)

createjs.Sound.play("RegSPsound3");

 

This works fine when the main timeline is played forward. Is this a correct way to register and call sound clips from my library?

 

The issue I am experiencing and need help problem-solving: After a user has navigated through the main timeline and played all nested movieclips within the main timeline (all sound effects have played correctly), and the user then navigates backwards through the main timeline (let's say from frame 2 to frame 1) what happens is ALL the sound effects in level one nested movieclips on frame 1 play at once, before their respective movieclips even reach the frame where the 'createjs.Sound.play' code is located and where the sound effect should play. This is what I don't understand. Why is that happening? 

 

As I mentioned above, if I double nest my movieclips, this does not happen and the sound effects play correctly when the nested movieclips reach the frame holding the 'createjs.Sound.play' code.

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 05, 2019 Dec 05, 2019

Copy link to clipboard

Copied

You don't appear to have any load event listeners, so there's nothing stopping your page from attempting to play a sound before it's loaded.

 

All the sound effects are probably playing because all the movieclips are playing. Put a console.log(this.currentFrame); statement with each play command to monitor when they're being hit.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 05, 2019 Dec 05, 2019

Copy link to clipboard

Copied

ClayUUID- Again, thank you for your continued help with this.

 

Yes I see what you are saying about the load event listeners, and I will indeed add a load event listener for my longer sound effects, however most are very small file size.

 

Regarding the issue about all the sound effects playing at once, I know that all the movieclips are not playing at once because they are coded to start playing with a button click, therefore it is obvious to see that all the nested movieclips are stopped on frame 0 (until I click their respective buttons). I added the console.log code to the same function with the sound effect, which is located on frame 10 of the nested movieclip (which is on frame 1 of the main timeline). When frame 1 of the main timeline is visited the first time, the sound effect plays normally when frame 10 of the nested movieclip is reached, and the console logs "10", however, the second time the main timeline frame 1 is visited and all the sound effects play at once (the issue I'm trying to figure out), the console logs "0" and plays the sound effect.

 

function Soundtest() {
createjs.Sound.play("RegSPsound1");
console.log(exportRoot.Lesson1_instructions_brave.currentFrame);
}

Soundtest();

 

Like I said, the simultaneous playing of all sound effects automatically only happens when the main timeline frames are visited a second time. The first time the main timeline is cycled through, all sound effects in nested movieclips play normally at the appropriate time. This is what has stumped me. 

 

It seems as if all code on all frames of all level one nested movieclips is read and fired, however the movieclips themselves are not playing. This has baffled me and I get the feeling there is something fundamental about javascript within the Adobe HTML5 Canvas timeline that I am doing wrong or do not understand.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 06, 2019 Dec 06, 2019

Copy link to clipboard

Copied

Sounds like you need to manage the state of your movieclips more explicitly. In CreateJS 1.0.0, unlike the previous version, single-frame movieclips run continuously instead of running once then stopping. There may be other differences too.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 08, 2019 Dec 08, 2019

Copy link to clipboard

Copied

Ok, I see. These movieclips are not single framed and are not automatically running, however it seems that all the code in their timeline (regardless of the frame) is fired when the movieclip is viewed a second time. This feed has been very helpful and I will continue to troubleshoot this issue.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 08, 2019 Dec 08, 2019

Copy link to clipboard

Copied

LATEST

I have solved my issue by simply stopping ALL sound effects at the start of each main timeline frame.

 

this.stop();

createjs.Sound.stop();

 

Then, as my nested movieclips advance, their sound effects play as expected.

 

Thank you for your part in my long  troubleshooting adventure.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines