Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how do I create an adaptive buffer for externally loaded mp3's? 1

Status
Not open for further replies.

GD03

Programmer
Oct 20, 2003
22
US
I am completely stuck on how I can create an adaptive buffer for an externally loaded mp3. The code I am working with is as follows:

Code:
function createSoundObject(){
mySound = new Sound(soundControl_mc);
mySound.setVolume(volPercent*2);
}

createSoundObject();
mySound.loadSound ("1_beethoven.mp3", true);

the sound being loaded is contained within the movieclip "soundcontrol_mc" within the main timeline of the movie.

My theory on creating a buffer would be to get the kbps of the user by applying this code:

Code:
function getkbps(seconds,bytes){
var totalBits = bytes * 8;
var totalKBits = totalBits/1024;
var kbps = Math.round(totalKBits/seconds);
return(kbps)
}

and applying the following formula to calculate the buffer:


(1 - User bit rate / Stream bit rate) * duration of sound in seconds


However, how is it possible to calculate the duration of the media in an externally loaded mp3.

I have thought about this problem for a long while with no solution. I am beginning to doubt my skills so any help would be appreciated. Thanks in advance.
 
Wait dont doubt yourself now, your method is genious!

For the duration, you can use the duration property

Code:
trackDuration = mySound.duration
//returns the duration in milliseconds
for example, if the song length is 3:44, the property would return 224000 (224 seconds X 1000)

But one problem is with progressive downloading; if the sound file hasn't fully donwloaded, then flash will only return the duration of the file downloaded so far.

So one way to fix this is this:
Code:
var trackDlProg:Number = _root.mySound.getBytesLoaded() / 1000;
var trackDlTotal:Number = _root.mySound.getBytesTotal() / 1000;
var trackDlPercent:Number = Math.round((trackDlProg/trackDlTotal) * 100);
var trackDlDuration:Number = Math.round((mySound.duration/trackDlPercent) * 100);
This way you can approximate the file duration according to how much of the file has downloaded

Hope that helps!
 
Thank you benny for the input. I have created the following code to perform the function of an adaptive buffer, however, it is not functioning properly. I don't know if you are anyone may have any suggestions.

Code:
function createSoundObject(){
mySound = new Sound(soundControl_mc);
}

function getkbps(seconds,bytes){
	var totalBits = bytes * 8;
	var totalKBits = totalBits/1024;
	var kbps = Math.round(totalKBits/seconds);
	return(kbps)
}

var trackDlProg:Number = _root.mySound.getBytesLoaded() / 1000;
var trackDlTotal:Number = _root.mySound.getBytesTotal() / 1000;
var trackDlPercent:Number = Math.round((trackDlProg/trackDlTotal) * 100);
var trackDlDuration:Number = Math.round((mySound.duration/trackDlPercent) * 100);

var totalBytes = object.getBytesTotal();
var userBandwidth = getkbps(now, object.getBytesLoaded());
var mediaBitrate = getkbps(trackD1Duration,totalBytes);

createSoundObject();
mySound.loadSound ("1_beethoven.mp3", true);
var _soundbuftime = Math.ceil((1 - userBandwidth / mediaBitrate) * trackDlDuration);

Thanks again for the input.
 
Oh so sorry I forgot to metntion something

The duration, getBytesLoaded, and getBytesTotal have to be constantly updated. Every second these values are changing while the sound is downloading.

Try updating them with a constant enterFrame function:

First create an empty movie clip symbol and place it on stage somewhere. Have its instance name say "enterframe"

then add this code

Code:
[COLOR=red]
var trackDlProg:Number;
var trackDlTotal:Number;
var trackDlPercent:Number;
var trackDlDuration:Number;
[/color]

function createSoundObject(){
mySound = new Sound(soundControl_mc);
}

function getkbps(seconds,bytes){
    var totalBits = bytes * 8;
    var totalKBits = totalBits/1024;
    var kbps = Math.round(totalKBits/seconds);
    return(kbps)
}

[COLOR=red]
function checkSound() {
	_root.enterframe.onEnterFrame = function() {
		_root.trackDlProg = _root.mySound.getBytesLoaded()/1000;
		_root.trackDlTotal = _root.mySound.getBytesTotal()/1000;
		_root.trackDlPercent = Math.round((trackDlProg/trackDlTotal)*100);
		_root.trackDlDuration = Math.round((mySound.duration/trackDlPercent)*100);
		if (_root.trackDlProg == _root.trackDlTotal) {
			_root.endEnterFrame();
		}
	};
}

function endEnterFrame() {
	delete _root.enterframe.onEnterFrame;
}
[/color]

var totalBytes = object.getBytesTotal();
var userBandwidth = getkbps(now, object.getBytesLoaded());
var mediaBitrate = getkbps(trackD1Duration,totalBytes);

createSoundObject();
mySound.loadSound ("1_beethoven.mp3", true);
[COLOR=red]checkSound();[/color]
var _soundbuftime = Math.ceil((1 - userBandwidth / mediaBitrate) * trackDlDuration);

that might be a roundabout way of doing it, but i think it should work, so try that and tell me how it goes
 
Thanks again for the help Benny, however, I am having an issue with the output panel giving me this message:


**Error** Symbol=soundControl_mc, layer=sound scripts, frame=1:Line 16: Syntax error.
    var totalBits = bytes * 8;

**Error** Symbol=soundControl_mc, layer=sound scripts, frame=1:Line 17: Syntax error.
    var totalKBits = totalBits/1024;


This seems strange because it appears that there is no syntax error.

I have created an empty movie clip with the instance name "enterframe" within the movie clip "soundcontrol_mc" and placed the following code on a seperate layer from all of the other content. So I am not sure where the problem may be.

Code:
var volPercent = 50;
volumeText = volPercent+"%";

var trackDlProg:Number;
var trackDlTotal:Number;
var trackDlPercent:Number;
var trackDlDuration:Number;


function createSoundObject(){
mySound = new Sound(soundControl_mc);
mySound.setVolume(volPercent*2);
}

function getkbps(seconds,bytes){
    var totalBits = bytes * 8;
    var totalKBits = totalBits/1024;
    var kbps = Math.round(totalKBits/seconds);
    return(kbps)
}


function checkSound() {
    _root.enterframe.onEnterFrame = function() {
        _root.trackDlProg = _root.mySound.getBytesLoaded()/1000;
        _root.trackDlTotal = _root.mySound.getBytesTotal()/1000;
        _root.trackDlPercent = Math.round((trackDlProg/trackDlTotal)*100);
        _root.trackDlDuration = Math.round((mySound.duration/trackDlPercent)*100);
        if (_root.trackDlProg == _root.trackDlTotal) {
            _root.endEnterFrame();
        }
    };
}

function endEnterFrame() {
    delete _root.enterframe.onEnterFrame;
}


var totalBytes = object.getBytesTotal();
var userBandwidth = getkbps(now, object.getBytesLoaded());
var mediaBitrate = getkbps(trackD1Duration,totalBytes);

createSoundObject();
mySound.loadSound ("1_beethoven.mp3", true);
checkSound();
var _soundbuftime = Math.ceil((1 - userBandwidth / mediaBitrate) * trackDlDuration);

mySound.onSoundComplete = function() {
	_level0.soundControl_mc.gotoandplay(2);
}

Thanks again for all of your help. Your assistance does not go unnoticed.
 
well if the enterframe mc is within the soundcontrol_mc (if thats the instance name) movie clip then this coe:

Code:
function checkSound() {
    [highlight]_root.enterframe.onEnterFrame = function() {[/highlight]
        _root.trackDlProg = _root.mySound.getBytesLoaded()/1000;
        _root.trackDlTotal = _root.mySound.getBytesTotal()/1000;
        _root.trackDlPercent = Math.round((trackDlProg/trackDlTotal)*100);
        _root.trackDlDuration = Math.round((mySound.duration/trackDlPercent)*100);
        if (_root.trackDlProg == _root.trackDlTotal) {
            _root.endEnterFrame();
        }
    };
}

function endEnterFrame() {
    [highlight]delete _root.enterframe.onEnterFrame;[/highlight]
}
won't work, it will have to be:
Code:
_root.soundcontrol_mc.enterframe.onEnterFrame...

//or simply

enterframe.onEnterFrame...

make sure you replace the 2 times that this code occurs

about the syntax errors...

i have no idea why that would happen?

maybe strict type them before hand (or remove the ';')?

Code:
var trackDlProg:Number;
var trackDlTotal:Number;
var trackDlPercent:Number;
var trackDlDuration:Number;
[highlight]var totalBits:Number;
var totalKBits:Number;
var kbps:Number[/highlight]

...

function getkbps(seconds,bytes){
[highlight]    _root.totalBits = bytes * 8
    _root.totalKBits = _root.totalBits/1024
    kbps = Math.round(totalKBits/seconds)[/highlight]
    return(kbps)
}

...

try that
 
My final code appears like it should work I can not find any errors with it, yet I still receive an error:

**Error** Symbol=soundControl_mc, layer=sound scripts, frame=1:Line 18: Syntax error.
    _root.totalBits = bytes * 8;

**Error** Symbol=soundControl_mc, layer=sound scripts, frame=1:Line 19: Syntax error.
    _root.totalKBits = _root.totalBits/1024;


I am completely baffled on what could be causing this issue.

Please find below my final code:

Code:
var volPercent = 50;
volumeText = volPercent+"%";

var trackDlProg:Number;
var trackDlTotal:Number;
var trackDlPercent:Number;
var trackDlDuration:Number;
var totalBits:Number;
var totalKBits:Number;
var kbps:Number;

function createSoundObject(){
mySound = new Sound(soundControl_mc);
mySound.setVolume(volPercent*2);
}

function getkbps(seconds,bytes){
    _root.totalBits = bytes * 8;
    _root.totalKBits = _root.totalBits/1024;  
    var kbps = Math.round(totalKBits/seconds);
    return(kbps)
}

function checkSound() {
    _root.soundControl_mc.enterframe.onEnterFrame = function() {
        _root.trackDlProg = _root.mySound.getBytesLoaded()/1000;
        _root.trackDlTotal = _root.mySound.getBytesTotal()/1000;
        _root.trackDlPercent = Math.round((trackDlProg/trackDlTotal)*100);
        _root.trackDlDuration = Math.round((mySound.duration/trackDlPercent)*100);
        if (_root.trackDlProg == _root.trackDlTotal) {
            _root.endEnterFrame();
        }
    };
}

function endEnterFrame() {
    delete _root.soundcControl_mc.enterframe.onEnterFrame;
}


var totalBytes = object.getBytesTotal();
var userBandwidth = getkbps(now, object.getBytesLoaded());
var mediaBitrate = getkbps(trackD1Duration,totalBytes);

createSoundObject();
mySound.loadSound ("1_beethoven.mp3", true);
checkSound();
var _soundbuftime = Math.ceil((1 - userBandwidth / mediaBitrate) * trackDlDuration);

mySound.onSoundComplete = function() {
	_level0.soundControl_mc.gotoandplay(2);
}
 
hmm
im not getting any errors when i use this code...

could you post an fla somewhere for me to look at?
 
I am posting the original .fla on along with the song that pertains to this code. In the .fla you will find the "soundControl_mc" on the bottom left corner of the document. When inside "soundControl_mc" you will find the code on frame 1 of layer "sound scripts". Thanks again for all of your help.
 
GD03

Ok i cured the problem; the bug seemed to be in the spaces before the code, which is weird. i have never run into anything like that before

but i uploaded your file

and another potential problem you might face...

this is how i see your site:
gd033yx.jpg


the font looks ugly right? I dont have your maestro wide font (and neither do most of your viewers probably) so you will have to EMBED your font into your movie if you want others to see it like you want
 
and of course, your fla is here

hope that helps (and feel free to ask if you need help embedding)
 
Thanks for all of your help Benny. As for the font issue I have embedded all of the fonts on the final .swf. If you go to the site should look as intended.
 
Excellent
And i must congradulate you on a job well done on your site!
 
thank you benny for your feedback.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top