Yes, the source code for bandwidth checker is in first post of this thread. You can compile your own version in the Wowza IDE to make adjustments.
Richard
Yes, the source code for bandwidth checker is in first post of this thread. You can compile your own version in the Wowza IDE to make adjustments.
Richard
Did you add the jar file to wowza/lib folder then restart Wowza, and did you add the module to Application.xml. You want to connect to the Wowza server that you added that jar to, and to the application that you added the Module to.
Richard
There is a Actionscript 3 version of ctosbwcheck in [wowza-install-dir]/examples/BWCheck/CtoSBWCheck.fla
The results of the bwcheck do vary from moment to moment, which is normal result of varying network conditions.
Richard
It should be here:
[install dir]\examples\BWChecker\client\CtoSBWCheck.fla
I’ll send it to that email too.
Richard
There is a working AS3 example here:
[wowza-install-dir]/examples/BWChecker/client/bwchecker.fla
Richard
It’s on page 2 of this thread. You have to build it in the Wowza IDE
It tests from client to server. The default one at the top tests from server to client.
Richard
I don’t understand the question. Can you explain?
Richard
I think you are talking about using Netstream.play2() and netstreaminfo object. This what is used to implement Flash Dynamic Streaming, for example JW Player’s implementation
You can search around but here is one article that looks useful
Here is how the simple, before connect method to check bandwidth
https://www.wowza.com/docs/how-to-test-server-to-client-bandwidth-for-rtmp-clients
I think that camera.setQuality() will have an affect on a stream after you do netstream.publish()
Richard
You’re English is great. Thanks for the update.
Richard
i’m having some problems with converting the BWChecker to AS3.
this is what i’ve got :
var constring="rtmp://localhost/bwcheck";
var detected_bw:String;
var counter:Number=0;
var nc:NetConnection=new NetConnection;
nc.client=this;
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler );
function netStatusHandler (e:NetStatusEvent):void{
trace("Level: "+e.info.level+" Code: "+e.info.code);
if (e.info.code == "NetConnection.Connect.Success") {
trace("--- connected to: " + nc.uri); //this.uri
}
}
function onBWCheck(latency:String):Number{
trace("in onBWCheck");
return ++counter; // Serverside, just ignore any return value, For now return the call count
}
function onBWDone(kbitDown, deltaDown, deltaTime, latency):void{
trace("==>in onBW_DONE");
trace("onBWDone: kbitDown:"+kbitDown+" deltaDown:"+deltaDown+" deltaTime:"+deltaTime+" latency:"+latency);
//detected_bw = kbitDown;
nc.close();
}
nc.connect(constring, true);
stop();
and i get this as a result (haven’t changed anything to serverside code, or is it necessary that i do that?):
in onBWCheck
Level: status Code: NetConnection.Connect.Success
— connected to: rtmp://localhost/bwcheck
ok , works like a charm now. Thanks a lot !
Hi Charlie,
like balint.pelhos , I need to calculate the actual bandwidth after the stream has started without start another connection and generating an extra traffic.
I read your reply about it, but I’m not able to use IOPerformanceCounter interface like you suggested…
Is it possible have some indication or some reference how to implement it (server side and client side).
Thanks!
For using the bandwidth checker module, the instruction (posted below) asks for the FLVPlayback module to be removed. I would like to know why this needs to be done?
thanks
maple01
Configuration:
Create a folder named [install-dir]/applications/bwcheck
Create a folder named [install-dir]/conf/bwcheck
Copy [install-dir]/conf/Application.xml into new bwcheck config folder
Edit copied Application.xml file and remove the module reference to ModuleFLVPlayback and add the module reference below as the last entry in the section (it is important that it is the last entry):
A complete built version can be downloaded from here. Follow Charlie’s instructions at the top of the page to install.
Please let me know if there are any problems.
Roger.
This link is dead, can anyone help? Ive tried to compile it myself but im ignorant when it comes java. Thanks.
-jason
thanks! you guys are top notch support - jason
Hi CHarlie,
I have been trying to make the bandwidth test work before we go ahead and purchase the lincense but no luck. I work for a university and we have many extension workers with dial up connection and I have been working with Richard by email to test the bandwidth check but it seems impossible to get it done. I have the plug-in in lib folder and have appropriate video files for each bandwidth here is the code:
var bandwidthVer = “_100”;
if (detected_bw >= 800)
bandwidthVer = “_750”;
else if (detected_bw >= 550)
bandwidthVer = “_500”;
else if (detected_bw >= 300)
bandwidthVer = “_250”;
But on dial up modem still gets the the one with _750, I am soo frustrated here and want to know what am I doing wrong?
thanks ina dvance for your help.
Richard,
how do I know if bandwidthVer have default of “_750”?
thanks
The default is _100
Here is the code:
import flash.geom.*;
var nc:NetConnection;
var nsPlay:NetStream = null;
var serverName:String = “rtmp://server/video”;
var movieName:String = “Extremists”;
var duration:Number = 0;
var progressTimer:Number = 0;
var isPlaying:Boolean = true;
var isProgressUpdate:Boolean = false;
var fastSettings:Array = new Array();
var currFastDir:Number = 0;
var currFastIndex:Number = 0;
var scrubTimer:Number = 0;
var isScrubbing:Boolean = false;
var scrubTime:Number = 0;
var scrubIsPlaying:Boolean;
var stageListener:Object = new Object();
var saveVideoObjX:Number;
var saveVideoObjY:Number;
var saveVideoObjW:Number;
var saveVideoObjH:Number;
var adjVideoObjW:Number;
var adjVideoObjH:Number;
var videoSizeTimer:Number = 0;
var videoLastW:Number = 0;
var videoLastH:Number = 0;
var fullscreenCapable:Boolean = false;
var hardwareScaleCapable:Boolean = false;
function mainInit()
{
// get movie name from parameter is defined
if (_root.zmovieName != undefined)
movieName = _root.zmovieName;
// initialize player control events
_root.controls.doPlay.onPress = _root.doPlayToggle;
_root.controls.doRewind.onPress = _root.doRewind;
_root.slider.onPress = _root.startScrub;
_root.slider.onRelease = _root.stopScrub;
_root.slider.onReleaseOutside = _root.stopScrub;
// uncomment this to monitor frame rate and buffer length
//setInterval(_root, “updateStreamValues”, 500);
_root.connect.connectStr.text = serverName;
_root.connect.streamStr.text = movieName;
_root.connect.connectButton.onPress = _root.doConnect;
_root.doFullscreen.onPress = _root.enterFullscreen;
enablePlayControls(false);
stageListener.onFullScreen = enterLeaveFullscreen;
Stage.addListener( stageListener );
saveVideoObjX = videoObj._x;
saveVideoObjY = videoObj._y;
adjVideoObjW = (saveVideoObjW = videoObj._width);
adjVideoObjH = (saveVideoObjH = videoObj._height);
videoObj._visible = false;
fullscreenCapable = testVersion(9, 0, 28, 0);
hardwareScaleCapable = testVersion(9, 0, 60, 0);
}
function doConnect()
{
// connect to the Wowza Media Server
if (nc == null)
{
enablePlayControls(true);
nc = new NetConnection();
nc.onStatus = function(infoObject)
{
trace(“nc.onStatus: “+infoObject.code+” (”+infoObject.description+")");
for (var prop in infoObject)
{
trace("\t"+prop+":\t"+infoObject[prop]);
}
// once we are connected to the server create the nsPlay NetStream object
if (infoObject.code == “NetConnection.Connect.Success”)
{
enablePlayControls(true);
createPlayStream();
videoLastW = 0;
videoLastH = 0;
videoSizeTimer = setInterval(_root, “updateVideoSize”, 500);
}
else if (infoObject.code == “NetConnection.Connect.Failed”)
_root.prompt.text = “Connection failed: Try rtmp://[server-ip-address]/simplevideostreaming”;
else if (infoObject.code == “NetConnection.Connect.Rejected”)
_root.prompt.text = infoObject.description;
}
nc.connect(_root.connect.connectStr.text);
// uncomment this to monitor frame rate and buffer length
//debugInterval = setInterval(_root, “updateStreamValues”, 500);
_root.connect.connectButton.label = “Stop”;
}
else
{
videoObj.attachVideo(null);
videoObj.attachAudio(null);
videoObj.clear();
videoObj._visible = false;
if (videoSizeTimer)
clearInterval(videoSizeTimer);
videoSizeTimer = 0;
videoLastW = 0;
videoLastH = 0;
nc.close();
nc = null;
if (debugInterval > 0)
clearInterval(debugInterval);
debugInterval = 0;
enablePlayControls(false);
setProgress(0);
_root.connect.connectButton.label = “Play”;
_root.prompt.text = “”;
}
}
function enablePlayControls(isEnable:Boolean)
{
_root.controls.doPlay.enabled = isEnable;
_root.controls.doRewind.enabled = isEnable;
_root.doFullscreen._visible = isEnable & fullscreenCapable;
}
// function to monitor the frame rate and buffer length
function updateStreamValues()
{
var newVal:String = “”;
if (nsPlay != null)
newVal = (Math.round(nsPlay.currentFps1000)/1000)+" fps/"+(Math.round(nsPlay.bufferLength1000)/1000)+" secs";
fpsText.text = newVal;
}
// create the nsPlay NetStream object
function createPlayStream()
{
nsPlay = new NetStream(nc);
nsPlay.onStatus = function(infoObject)
{
trace("onStatus: ");
for (var propName:String in infoObject)
{
trace(" "+propName + " = " + infoObject[propName]);
}
if (infoObject.code == “NetStream.Play.Start”)
_root.isProgressUpdate = true;
else if (infoObject.code == “NetStream.Play.StreamNotFound” || infoObject.code == “NetStream.Play.Failed”)
_root.prompt.text = infoObject.description;
};
nsPlay.onMetaData = function(infoObject:Object)
{
trace(“onMetaData”);
// print debug information about the metaData
for (var propName:String in infoObject)
{
trace(" "+propName + " = " + infoObject[propName]);
}
// grab the movies duration from the metadata
if (_root.duration == 0)
{
_root.duration = infoObject.duration;
progressTimer = setInterval(_root, “updateProgress”, 250);
}
};
// print debug information when we encounter a cuePoint
nsPlay.onCuePoint = function(infoObject)
{
trace(“onCuePoint: “+infoObject.name+” (”+infoObject.type+")");
for(param in infoObject.parameters)
{
trace(" param: “+param+”="+infoObject.parameters[param]);
}
};
// print debug information when we play status changes
nsPlay.onPlayStatus = function(infoObject:Object)
{
trace(“onPlayStatus”);
for (var prop in infoObject)
{
trace("\t"+prop+":\t"+infoObject[prop]);
}
};
// set the buffer time and attach the video and audio
nsPlay.setBufferTime(3);
_root.videoObj.attachVideo(nsPlay);
_root.videoObj.attachAudio(nsPlay);
// start playback
_root.isProgressUpdate = false;
_root.isPlaying = true;
var bandwidthVer = “_100”;
if (detected_bw >= 800)
bandwidthVer = “_750”;
else if (detected_bw >= 550)
bandwidthVer = “_500”;
else if (detected_bw >= 300)
bandwidthVer = “_250”;
_root.connect.streamStr.text = _root.connect.streamStr.text+bandwidthVer;
nsPlay.play(_root.connect.streamStr.text);
}
the rest:
// play video (no fast play)
function doPlay()
{
currFastDir = 0;
currFastIndex = 0;
trace(“doPlay”);
var timecode:Number = nsPlay.time;
_root.isProgressUpdate = false;
if (!_root.isPlaying)
nsPlay.pause(false);
nsPlay.seek(timecode);
_root.isPlaying = true;
}
// event for clicking the play button
// if we are paused or in fast play mode just play the video
// else pause the video
function doPlayToggle()
{
if (!isPlaying)
doPlay();
else
{
_root.isProgressUpdate = false;
_root.isPlaying = false;
nsPlay.pause(true);
}
}
// rewind to the beginning of the movie and start playing
function doRewind()
{
_root.isProgressUpdate = false;
nsPlay.seek(0);
}
// update the progress bar
function setProgress(timecode:Number)
{
var totalWidth:Number = slider.sliderBack._width;
var newTimecode:Number = timecode;
var newWidth = (totalWidth*newTimecode)/duration;
if (newWidth > totalWidth)
newWidth = totalWidth;
if (!_root.isScrubbing && _root.isProgressUpdate)
slider.sliderSlide._width = newWidth;
}
function updateProgress()
{
setProgress(nsPlay.time);
}
// calculate the movie scrub location based on current mouse position
function calcScrub()
{
var xpos:Number = _root.slider._xmouse;
var xmax:Number = _root.slider._width;
if (xpos < 0)
xpos = 0;
else if (xpos > xmax)
xpos = xmax;
scrubTime = (duration*xpos)/xmax;
slider.sliderSlide._width = xpos;
}
// update the scrub location as we are scrubbing
function updateScrub()
{
calcScrub();
}
// start scrubbing
function startScrub()
{
scrubTimer = setInterval(_root, “updateScrub”, 250);
isScrubbing = true;
scrubTime = -1;
calcScrub();
scrubIsPlaying = _root.isPlaying;
if (_root.isPlaying)
nsPlay.pause(true);
}
// stop scrubbing and setup new play position
function stopScrub()
{
if (scrubTimer)
clearInterval(scrubTimer);
scrubTimer = 0;
if (scrubTime != -1)
{
_root.isProgressUpdate = false;
if (scrubIsPlaying)
{
_root.isPlaying = true;
nsPlay.pause(false);
nsPlay.seek(scrubTime);
}
else
{
_root.isPlaying = false;
nsPlay.seek(scrubTime);
}
}
isScrubbing = false;
}
function updateVideoSize()
{
// when we finally get a valid video width/height resize the video frame to make it proportional
if (videoObj.width != videoLastW || videoObj.height != videoLastH)
{
videoLastW = videoObj.width;
videoLastH = videoObj.height;
var videoAspectRatio:Number = videoLastW/videoLastH;
var frameAspectRatio:Number = saveVideoObjW/saveVideoObjH;
adjVideoObjW = saveVideoObjW;
adjVideoObjH = saveVideoObjH;
if (videoAspectRatio > frameAspectRatio)
adjVideoObjH = saveVideoObjW/videoAspectRatio;
else
adjVideoObjW = saveVideoObjH*videoAspectRatio;
videoObj._width = adjVideoObjW;
videoObj._height = adjVideoObjH;
videoObj._y = saveVideoObjY + saveVideoObjH - adjVideoObjH;
videoObj._x = (Stage.width - adjVideoObjW)/2;
videoObj._visible = true;
}
}
// show/hide the controls when we enter/leave fullscreen
function hideAllControls(doHide:Boolean)
{
_root.fpsText._visible = !doHide;
_root.bufferLenText._visible = !doHide;
_root.logo._visible = !doHide;
_root.connect._visible = !doHide;
_root.controls._visible = !doHide;
_root.doFullscreen._visible = !doHide;
_root.slider._visible = !doHide;
_root.backdrop._visible = !doHide;
_root.playerVersion._visible = !doHide;
}
function enterLeaveFullscreen(isFullscreen:Boolean)
{
trace("enterLeaveFullscreen: "+enterLeaveFullscreen);
hideAllControls(isFullscreen);
if (!isFullscreen)
{
// reset back to original state
Stage.scaleMode = “noScale”;
videoObj._width = adjVideoObjW;
videoObj._height = adjVideoObjH;
videoObj._y = saveVideoObjY + saveVideoObjH - adjVideoObjH;
videoObj._x = (Stage.width - adjVideoObjW)/2;
}
}
function enterFullscreen()
{
if (hardwareScaleCapable)
{
// best settings for hardware scaling
videoObj.smoothing = false;
videoObj.deblocking = 0;
// set the video frame size to the actual video size
videoObj._width = videoObj.width;
videoObj._height = videoObj.height;
// grab the portion of the stage that is just the video frame
Stage[“fullScreenSourceRect”] = new Rectangle(
videoObj._x, videoObj._y,
videoObj.width, videoObj.height);
}
else
{
Stage.scaleMode = “noBorder”;
var videoAspectRatio:Number = videoObj.width/videoObj.height;
var stageAspectRatio:Number = Stage.width/Stage.height;
var screenAspectRatio:Number = System.capabilities.screenResolutionX/System.capabilities.screenResolutionY;
// calculate the width and height of the scaled stage
var stageObjW:Number = Stage.width;
var stageObjH:Number = Stage.height;
if (stageAspectRatio > screenAspectRatio)
stageObjW = Stage.height*screenAspectRatio;
else
stageObjH = Stage.width/screenAspectRatio;
// calculate the width and height of the video frame scaled against the new stage size
var fsVideoObjW:Number = stageObjW;
var fsVideoObjH:Number = stageObjH;
if (videoAspectRatio > screenAspectRatio)
fsVideoObjH = stageObjW/videoAspectRatio;
else
fsVideoObjW = stageObjH*videoAspectRatio;
// scale the video object
videoObj._width = fsVideoObjW;
videoObj._height = fsVideoObjH;
videoObj._x = (stageObjW-fsVideoObjW)/2.0;
videoObj._y = (stageObjH-fsVideoObjH)/2.0;
}
Stage[“displayState”] = “fullScreen”;
}
function testVersion(v0:Number, v1:Number, v2:Number, v3:Number):Boolean
{
var version:String = System.capabilities.version;
var index:Number = version.indexOf(" ");
version = version.substr(index+1);
var verParts:Array = version.split(",");
var i:Number;
var ret:Boolean = true;
while(true)
{
if (Number(verParts[0]) < v0)
{
ret = false;
break;
}
else if (Number(verParts[0]) > v0)
break;
if (Number(verParts[1]) < v1)
{
ret = false;
break;
}
else if (Number(verParts[1]) > v1)
break;
if (Number(verParts[2]) < v2)
{
ret = false;
break;
}
else if (Number(verParts[2]) > v2)
break;
if (Number(verParts[3]) < v3)
{
ret = false;
break;
}
break;
}
trace(“testVersion: “+System.capabilities.version+”>=”+v0+","+v1+","+v2+","+v3+": "+ret);
return ret;
}
var h264Capable:Boolean = testVersion(9, 0, 115, 0);
playerVersion.text = (h264Capable?“H.264 Ready (”:“No H.264 (”)+System.capabilities.version+")";
if (!h264Capable)
playerVersion.textColor = 0xee0000;
Stage.align = “TL”;
Stage.scaleMode = “noScale”;
nc.onBWDone = function(kbitDown, deltaDown, deltaTime, latency) {
trace(“onBWDone: kbitDown:”+kbitDown+" deltaDown:"+deltaDown+" deltaTime:"+deltaTime+" latency:"+latency);
// app logic based on the bandwidth detected follows here
detected_bw = kbitDown;
// close the Netconnection to bwcheck
this.close();
}
nc.onBWCheck = function() {
trace(“onBWCheck”);
return ++counter; // Serverside, just ignore any return value, For now return the call count
}
mainInit();
setProgress(0);
© 2007–2024 Wowza Media Systems™, LLC. All rights reserved. Security & Privacy PolicyLegalSystem Status