Skip to main content
Known Participant
July 14, 2008
Answered

how to calculate second and minisecond for audio cue point

  • July 14, 2008
  • 2 replies
  • 2298 views
I'm trying to do a sound sync for the audio and movie clip in Flash. I found a tutorial on the web and it seems to work. However, I don't know how to calculate the second and mini second from the mp3 file. The first frame has the following lines to define the time for each animation:
// Import class
import net.quip.sound.SoundSync;

// Stop main timeline
stop();

// Create an instance of SoundSync
var ss:SoundSync = new SoundSync();

ss.addCuePoint("IT", 20100);
ss.addCuePoint("admin", 20000);
ss.addCuePoint("maitenance", 19800);
ss.addCuePoint("treatment", 16479);
ss.addCuePoint("engineering", 14598);
as.addCuePoint("logo_epa_npdes", 12356);
ss.addCuePoint("construction", 8967);
ss.addCuePoint("370mgd", 7896);
ss.addCuePoint("mc_650,000",5439 );
ss.addCuePoint("130mgd", 3254);
ss.addCuePoint("1938", 2439);
ss.addCuePoint("vintage_mc", 0);

// Use instance to load external MP3
ss.loadSound("Scn04-05.mp3", true);

// Create a listener object for the
// cuePoint and onSoundComplete events
var listener:Object = new Object();
listener.cuePoint = function():Void {
play();
}
listener.onSoundComplete = function():Void {
play();
}
ss.addEventListener("cuePoint", listener);
ss.addEventListener("onSoundComplete", listener);

and the soundsync.as file as follows:
import mx.events.EventDispatcher;
import mx.utils.Delegate;
class net.quip.sound.SoundSync extends Sound {
// PROPERTIES
private var _cuePoints:Array;
private var _currentCuePoint:Number;
private var _interval:Number;
private var _intervalDuration:Number;
private var _secondOffset:Number;
// Event dispatcher
public var dispatchEvent:Function;
public var addEventListener:Function;
private var removeEventListener:Function;
// CONSTRUCTOR
public function SoundSync(target:MovieClip) {
super(target);
init();
}
// METHODS
private function init():Void {
// Initialize properties
_cuePoints = new Array();
_currentCuePoint = 0;
_intervalDuration = 200;
_secondOffset = 0;
// Initialize class instance as valid event broadcaster
EventDispatcher.initialize(this);
}
// Add Cue Point
public function addCuePoint(cuePointName:String, cuePointTime:Number):Void {
_cuePoints.push(
{
type: "cuePoint",
name: cuePointName,
time: cuePointTime,
target: this
}
);
_cuePoints.sortOn("time", Array.NUMERIC);
}
// Get Cue Point
public function getCuePoint(nameOrTime:Object):Object {
var counter:Number = 0;
while (counter < _cuePoints.length) {
if (typeof(nameOrTime) == "string") {
if (_cuePoints[counter].name == nameOrTime) {
return _cuePoints[counter];
}
} else if (typeof(nameOrTime) == "number") {
if (_cuePoints[counter].time == nameOrTime) {
return _cuePoints[counter];
}
}
counter++;
}
return null;
}
// Get Current Cue Point Index
private function getCurrentCuePointIndex(cuePoint:Object):Number {
var counter:Number = 0;
while (counter < _cuePoints.length) {
if (_cuePoints[counter].name == cuePoint.name) {
return counter;
}
counter++;
}
return null;
}
// Get Next Cue Point Index
private function getNextCuePointIndex(seconds:Number):Number {
seconds = (seconds) ? seconds : 0;
var counter:Number = 0;
while (counter < _cuePoints.length) {
if (_cuePoints[counter].time >= seconds * 1000) {
return counter;
}
counter++;
}
return null;
}
// Remove Cue Point
public function removeCuePoint(cuePoint:Object):Void {
_cuePoints.splice(getCurrentCuePointIndex(cuePoint), 1);
}
// Remove All Cue Points
public function removeAll_cuePoints():Void {
_cuePoints = new Array();
}
// Start
public function start(secondOffset:Number, loops:Number):Void {
super.start(secondOffset, loops);
dispatchEvent({type:"onStart", target:this});
// Reset current cue point
_secondOffset = secondOffset;
_currentCuePoint = getNextCuePointIndex(secondOffset);
// Poll for cue points
clearInterval(_interval);
_interval = setInterval(Delegate.create(this, pollCuePoints), _intervalDuration);
}
// Load Sound
public function loadSound(url:String, isStreaming:Boolean):Void {
super.loadSound(url, isStreaming);
clearInterval(_interval);
_interval = setInterval(Delegate.create(this, pollCuePoints), _intervalDuration);
}
// Stop
public function stop(linkageID:String):Void {
if (linkageID) {
super.stop(linkageID);
} else {
super.stop();
}
dispatchEvent({type:"onStop", target:this});
// Kill polling
clearInterval(_interval);
}
// Poll Cue Points
private function pollCuePoints():Void {
// If current position is near the current cue point's time ...
var time:Number = _cuePoints[_currentCuePoint].time;
var span:Number = (_cuePoints[_currentCuePoint + 1].time) ? _cuePoints[_currentCuePoint + 1].time : time + _intervalDuration * 2;
if (position >= time && position <= span) {
// Dispatch event
dispatchEvent(_cuePoints[_currentCuePoint]);
// Advance to next cue point ...
if (_currentCuePoint < _cuePoints.length) {
_currentCuePoint++;
} else {
_currentCuePoint = getNextCuePointIndex(_secondOffset);
}
}
}
// EVENT HANDLERS
// onSoundComplete
public function onSoundComplete():Void {
// Kill polling
clearInterval(_interval);
// Reset current cue point
_currentCuePoint = 0;
// Dispatch event
dispatchEvent({type:"onSoundComplete", target:this});
}
}

any help will be greatly appreciated.
This topic has been closed for replies.
Correct answer Newsgroup_User
wuzhishan,

> Hi Dave, your tutorial is a cute one and it is very useful.

Thanks! My daughter is the cute one. She inherited all of that from
me, so I don't have any left. ;)

> I'm sorry I didn't make my question clear.

No worries. :)

> I listen to the mp3 in Windows Media Player and try to
> get the time for the cue, I found it on the bottom of the
> player the time shows 00:26.

I'm with ya.

> How do I writer this number in the code? Is it 0026 or 26?

The code is expecting milliseconds, so 26 seconds would be written like
this:

26000

If it said 1:22 (a minute and 22 seconds), you would write it like this:

82000

... which is 60 seconds for the single minute, plus 22 from the seconds
side, then multiplied by 1,000 to get milliseconds.


David Stiller
Adobe Community Expert
Dev blog, http://www.quip.net/blog/
"Luck is the residue of good design."


2 replies

Inspiring
July 14, 2008
wuzhishan,

> I'm trying to do a sound sync for the audio and movie clip in Flash.
> I found a tutorial on the web and it seems to work. However, I
> don't know how to calculate the second and mini second from
> the mp3 file.

I wrote that article and the code, so I'll help if I can. :) But I'm
not sure I understand your question yet.

Are you asking, "How do I convert minutes and seconds into
milliseconds?" If so, here's an example. Let's say you want to add a cue
point at 4 minutes and 41 seconds. Converting the 41 seconds part is easy:
just mutiply that number by 1,000. So far, you've got 41,000 milliseconds.
Now set that number aside for just a moment and turn your attention to the
minutes.

You've got 4 minutes. There are 60 seconds in a minute, so convert to
seconds first. 4 * 60 is 240. At this point, you're back to where you were
before (a seconds value). Multiply that 240 by a thousand -- 240,000 -- and
add it to the other milliseconds value: 240,000 plus 41,000 equals 281,000
milliseconds.

So 4min 41sec is 281,000 milliseconds.

Does that help?


David Stiller
Adobe Community Expert
Dev blog, http://www.quip.net/blog/
"Luck is the residue of good design."


Newsgroup_UserCorrect answer
Inspiring
July 16, 2008
wuzhishan,

> Hi Dave, your tutorial is a cute one and it is very useful.

Thanks! My daughter is the cute one. She inherited all of that from
me, so I don't have any left. ;)

> I'm sorry I didn't make my question clear.

No worries. :)

> I listen to the mp3 in Windows Media Player and try to
> get the time for the cue, I found it on the bottom of the
> player the time shows 00:26.

I'm with ya.

> How do I writer this number in the code? Is it 0026 or 26?

The code is expecting milliseconds, so 26 seconds would be written like
this:

26000

If it said 1:22 (a minute and 22 seconds), you would write it like this:

82000

... which is 60 seconds for the single minute, plus 22 from the seconds
side, then multiplied by 1,000 to get milliseconds.


David Stiller
Adobe Community Expert
Dev blog, http://www.quip.net/blog/
"Luck is the residue of good design."


Inspiring
July 22, 2008
Dave, thank you for your instant reply.
I think they are consistantly early so I delay each movie by 4 seconds but that only work for the first 4 movie clips and all others still out of sync. e.g. this cue point: ss.addCuePoint("engineering", 50000); no matter what time I set it for it, it still appear early

wuzhishan,

> amazingly, I had a typo here: as.addCuePoint("logo_epa_npdes",
> 22000);
> but it makes the cue point in sync!!!!!!

w00t! :)

> but this is not the anwser to the problem.

Aw, shucks. :(

>> I think they are consistantly early so I delay each movie by 4
>> seconds but that only work for the first 4 movie clips and all
>> others still out of sync.

Wow! Well, honestly ... four seconds is a huge discrepancy. I was
thinking you might be seeing issues within a couple hundred milliseconds.
Four seconds is surprising to me. I guess my first question, then, is:
What is your event handler? In other words, what are you asking these cue
points to trigger? You mention movie clips, so I wonder if you're using
your event handler to reference movie clip instance names, asking each movie
clip to play (e.g. myMovieClip.play(), or the like). If that's so, you
could very well see a delay if your movie clips have varying amounts of
unused frames at the beginnings of their timelines.

But you're saying these cue points are triggered four seconds *early*.

What happens if you temporarily take the movie clips out of the
equation, and simply have your event handler trace() out a test message?
Are they early then?


David Stiller
Adobe Community Expert
Dev blog, http://www.quip.net/blog/
"Luck is the residue of good design."


Inspiring
July 14, 2008
Why do you need to compute the milli/second (I assume that is what you mean)? The cuepoints know what the time is and when they need to be called. What are you actually trying to accomplish?

In that part in your file you could change this:

listener.cuePoint = function():Void {
play();
}

to something more useful, perhaps that would help:

listener.cuePoint=function(event:Object):Void{
trace("Cuepoint "+event.name+" at: "+event.time);
play();
}