hi wowza team
I am using wowza rtmp player but very poor quality.
How can I improve the quality of the player in?
hi wowza team
I am using wowza rtmp player but very poor quality.
How can I improve the quality of the player in?
Hello there.
Can you please provide a little more detail about the stream in question:
What is the bandwidth in kbps / mbps
What is the stream resolution set to?
What is the codec of the stream? (H.264/AAC-44.1kHz/FPS/KeyFrame Intervals/etc…)
Is the stream live or VOD?
If live what is the source?
We look forward to hearing back from you and getting this issue resolved.
Kind regards,
Salvadore
only the quality problem with wowza rtmp player
flow, VLC, f4player no problem
modified Wowza RTMP player coding
VOD content
import flash.geom.*;
import com.wowza.encryptionAS3.TEA;
var nc:NetConnection;
var nsPlay:NetStream = null;
var sharedSecret:String = "#ed%h0#w@1"; //<--- SecureToken change here - set sharedSecret
var serverName:String = "rtmp://localhost:1935/vod";
var movieName:String = "mp4:sample.mp4";
var debugInterval:Number = 0;
var duration:Number = 0;
var progressTimer:Number = 0;
var isPlaying:Boolean = false;
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 saveStageW:Number;
var saveStageH: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;
var muted:Boolean=false;
var fullscreen:Boolean=false;
var knobWidth:Number;
var trackWidth:Number;
var trackX:Number;
var boundsWidth:Number;
var boundsRect:Rectangle;
var draggingBug:Boolean=false;
var sliderBugY:Number;
var silderBug:MovieClip;
var sliderTrack:MovieClip;
var videoSound:SoundTransform = new SoundTransform(0.5);
var playControlsX = playControls.x;
var playControlsY = playControls.y;
flash.system.Security.LOCAL_TRUSTED;
flash.system.Security.allowDomain('*');
mainInit();
viewbutton.addEventListener(MouseEvent.MOUSE_OVER, movieBar);
viewbutton.addEventListener(MouseEvent.ROLL_OUT, movieBarOut);
slider.addEventListener(MouseEvent.MOUSE_OVER, movieBar);
slider.addEventListener(MouseEvent.ROLL_OUT, movieBarOut);
playControls.addEventListener(MouseEvent.MOUSE_OVER, movieBar);
playControls.addEventListener(MouseEvent.ROLL_OUT, movieBarOut);
function movieBar (e:MouseEvent):void
{
if (playControlsY > playControls.y) {
trace ("konum zaten yukarda:"+playControlsY);
} else {
trace ("konum yukari tasindi"+playControlsY);
playControls.y = playControls.y - 30;
slider.y = slider.y -30
}
}
function movieBarOut (e:MouseEvent):void
{
if (playControlsY > playControls.y) {
trace ("konum asahi tasindi");
playControls.y = playControls.y + 30;
slider.y = slider.y +30
} else {
trace ("konum zaten asagida");
}
}
function mainInit()
{
knobWidth=playControls.volumeContainer.sliderBug.width;
trackWidth=playControls.volumeContainer.sliderTrack.width;
trackX=playControls.volumeContainer.sliderTrack.x;
boundsWidth=trackWidth-knobWidth;
sliderBugY=playControls.volumeContainer.sliderBug.y;
boundsRect=new Rectangle(trackX,sliderBugY,boundsWidth,0);
trace(boundsRect);
playerVersion.text = Capabilities.version+" (Flash-AS3)";
stage.align = "TL";
stage.scaleMode = "showAll";
// get movie name from parameter is defined
if (root.loaderInfo.parameters.zmovieName != undefined)
movieName = root.loaderInfo.parameters.zmovieName;
playControls.doPause.visible=false;
// initialize player control events
playControls.doPlay.addEventListener(MouseEvent.CLICK, doPlayToggle);
playControls.doPause.addEventListener(MouseEvent.CLICK, doPlayToggle);
playControls.doRewind.addEventListener(MouseEvent.CLICK, doRewind);
playControls.doFullscreen.addEventListener(MouseEvent.CLICK, enterFullscreen);
slider.addEventListener(MouseEvent.MOUSE_DOWN, startScrub);
slider.addEventListener(MouseEvent.MOUSE_UP, stopScrub);
playControls.volumeContainer.sliderBug.addEventListener(MouseEvent.MOUSE_DOWN, volumeMouseDown);
playControls.volumeContainer.sliderBug.addEventListener(MouseEvent.MOUSE_UP, volumeMouseUp);
addEventListener(MouseEvent.MOUSE_UP, volumeMouseUp);
playControls.volumeContainer.addEventListener(MouseEvent.CLICK, volumeClick);
addEventListener(MouseEvent.MOUSE_MOVE, volumeMouseMove);
playControls.doMute.visible=false;
playControls.doMute.addEventListener(MouseEvent.MOUSE_DOWN, muteSound);
playControls.doUnmute.addEventListener(MouseEvent.MOUSE_DOWN, muteSound);
// uncomment this to monitor frame rate and buffer length
setInterval(updateStreamValues, 500);
connect.connectStr.text = serverName;
try {
var str:String=ExternalInterface.call("getVODRTMPServer");
if(str!=null && str!="") {
connect.connectStr.text = str;
}
}
catch (error:Error) {
}
connect.streamStr.text = movieName;
try {
var streamStr:String=ExternalInterface.call("getVODRTMPStream");
if(str!=null && streamStr!="") {
connect.streamStr.text = streamStr;
}
}
catch (error:Error) {
}
connect.connectButton.addEventListener(MouseEvent.CLICK, doConnect);
enablePlayControls(false);
stage.addEventListener( FullScreenEvent.FULL_SCREEN, enterLeaveFullscreen );
saveVideoObjX = videoObj.x;
saveVideoObjY = videoObj.y;
saveStageW = stage.width;
saveStageH = stage.height;
adjVideoObjW = (saveVideoObjW = videoObj.width);
adjVideoObjH = (saveVideoObjH = videoObj.height);
//videoObj.visible = false;
fullscreenCapable = testVersion(9, 0, 28, 0);
hardwareScaleCapable = testVersion(9, 0, 60, 0);
setProgress(0);
}
function stopAll()
{
if(nsPlay != null) {
playControls.doPause.visible=false;
playControls.doPlay.visible=true;
setProgress(0);
videoObj.attachNetStream(null);
videoObj.clear();
videoObj.visible = false;
if (videoSizeTimer)
clearInterval(videoSizeTimer);
videoSizeTimer = 0;
videoLastW = 0;
videoLastH = 0;
duration = 0;
nsPlay = null;
}
if(nc!=null) {
nc.close();
nc = null;
}
if (debugInterval > 0)
clearInterval(debugInterval);
debugInterval = 0;
enablePlayControls(false);
connect.connectButton.label = "Start";
prompt.text = "Disconnected";
}
function setServer(server:String)
{
connect.connectStr.text=server;
}
function setStream(stream:String)
{
connect.streamStr.text=stream;
}
function volumeMouseDown(event:MouseEvent)
{
if(!isPlaying) {
return;
}
playControls.volumeContainer.sliderBug.y=sliderBugY;
playControls.volumeContainer.sliderBug.startDrag(false, boundsRect);
draggingBug=true;
nsPlay.soundTransform = new SoundTransform(playControls.volumeContainer.sliderBug.x/playControls.volumeContainer.sliderTrack.width);
muted = false;
trace(playControls.volumeContainer.sliderBug.x/playControls.volumeContainer.sliderTrack.width);
playControls.doMute.visible=false;
playControls.doUnmute.visible=true;
}
function volumeMouseMove(event:MouseEvent)
{
playControls.volumeContainer.sliderBug.y=sliderBugY;
if(!isPlaying || !draggingBug ) {
return;
}
nsPlay.soundTransform = new SoundTransform(playControls.volumeContainer.sliderBug.x/playControls.volumeContainer.sliderTrack.width);
muted = false;
trace(playControls.volumeContainer.sliderBug.x/playControls.volumeContainer.sliderTrack.width);
playControls.doMute.visible=false;
playControls.doUnmute.visible=true;
}
function volumeMouseUp(event:MouseEvent)
{
if(!isPlaying || !draggingBug) {
return
}
trace(playControls.volumeContainer.sliderBug.x/playControls.volumeContainer.sliderTrack.width);
playControls.volumeContainer.sliderBug.stopDrag();
draggingBug=false;
}
function volumeClick(event:MouseEvent)
{
if(!isPlaying || draggingBug) {
return
}
nsPlay.soundTransform = new SoundTransform(playControls.volumeContainer.sliderBug.x/playControls.volumeContainer.sliderTrack.width);
playControls.doMute.visible=false;
playControls.doUnmute.visible=true;
}
function muteSound(event:MouseEvent)
{
if(!isPlaying) {
return;
}
if(muted) {
muted = false;
playControls.doMute.visible=false;
playControls.doUnmute.visible=true;
nsPlay.soundTransform = new SoundTransform(playControls.volumeContainer.sliderBug.x/playControls.volumeContainer.sliderTrack.width);
} else {
muted = true;
playControls.doMute.visible=true;
playControls.doUnmute.visible=false;
nsPlay.soundTransform = new SoundTransform(0);
}
}
function ncOnStatus(infoObject:NetStatusEvent)
{
trace("nc.onStatus: "+infoObject.info.code+" ("+infoObject.info.description+")");
for (var prop in infoObject)
{
trace("\t"+prop+":\t"+infoObject.info[prop]);
}
// once we are connected to the server create the nsPlay NetStream object
if (infoObject.info.code == "NetConnection.Connect.Success")
{
if (infoObject.info.secureToken != undefined) //<--- SecureToken change here - respond with decoded secureToken
{
var secureResult:Object = new Object();
secureResult.onResult = function(isSuccessful:Boolean)
{
trace("secureTokenResponse: "+isSuccessful);
}
nc.call("secureTokenResponse", new Responder(secureResult.onResult), TEA.decrypt(infoObject.info.secureToken, sharedSecret));
}
enablePlayControls(true);
createPlayStream();
videoLastW = 0;
videoLastH = 0;
videoSizeTimer = setInterval(updateVideoSize, 0);
}
else if (infoObject.info.code == "NetConnection.Connect.Failed")
prompt.text = "Connection failed: Try rtmp://[wowza-ip-address]/vod";
else if (infoObject.info.code == "NetConnection.Connect.Rejected")
prompt.text = infoObject.info.description;
}
function doConnect(event:MouseEvent)
{
// connect to the Wowza Media Server
if (nc == null)
{
enablePlayControls(true);
nc = new NetConnection();
var str:String = connect.connectStr.text.substr(0,5) ;
if(str.toLowerCase() == "rtmps")
{
nc.proxyType="best";
}
nc.addEventListener(NetStatusEvent.NET_STATUS, ncOnStatus);
nc.connect(connect.connectStr.text);
// uncomment this to monitor frame rate and buffer length
//debugInterval = setInterval(updateStreamValues, 500);
connect.connectButton.label = "Stop";
prompt.text = "Connected";
}
else
{
stopAll();
}
}
function enablePlayControls(isEnable:Boolean)
{
playControls.doPlay.enabled = isEnable;
playControls.doRewind.enabled = isEnable;
playControls.doFullscreen.visible = isEnable && fullscreenCapable;
}
// function to monitor the frame rate and buffer length
function updateStreamValues()
{
var newVal:String = "";
if (nsPlay != null && isPlaying) {
newVal = (Math.round(nsPlay.currentFPS*1000)/1000)+" fps/"+(Math.round(nsPlay.bufferLength*1000)/1000)+" secs";
playControls.currentBitrate.text = "Current bitrate: "+Math.round((nsPlay.info.playbackBytesPerSecond*8)/1000)+"kbps";
} else {
playControls.currentBitrate.text = "";
}
}
function nsOnStatus(infoObject:NetStatusEvent)
{
trace("onStatus: ");
for (var propName:String in infoObject.info)
{
trace(" "+propName + " = " + infoObject.info[propName]);
}
if (infoObject.info.code == "NetStream.Play.Start")
isProgressUpdate = true;
else if (infoObject.info.code == "NetStream.Play.StreamNotFound" || infoObject.info.code == "NetStream.Play.Failed")
prompt.text = "Source stream or file could not be found or access was denied.";
else
prompt.text = infoObject.info.description;
}
// create the nsPlay NetStream object
function createPlayStream()
{
trace ("createPlaystream");
nsPlay = new NetStream(nc);
nsPlay.addEventListener(NetStatusEvent.NET_STATUS, nsOnStatus);
var nsPlayClientObj:Object = new Object();
nsPlay.client = nsPlayClientObj;
nsPlayClientObj.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 (duration == 0)
{
duration = infoObject.duration;
progressTimer = setInterval(updateProgress, 250);
}
};
// print debug information when we encounter a cuePoint
nsPlayClientObj.onCuePoint = function(infoObject)
{
trace("onCuePoint: "+infoObject.name+" ("+infoObject.type+")");
var param;
for(param in infoObject.parameters)
{
trace(" param: "+param+"="+infoObject.parameters[param]);
}
};
// print debug information when we play status changes
nsPlayClientObj.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.bufferTime = 3;
videoObj.attachNetStream(nsPlay);
videoSound = new SoundTransform(0.5);
nsPlay.soundTransform = videoSound;
playControls.doPause.visible=true;
playControls.doPlay.visible=false;
// start playback
isProgressUpdate = false;
isPlaying = true;
nsPlay.play(connect.streamStr.text);
}
// play video (no fast play)
function doPlay()
{
if(nsPlay != null) {
currFastDir = 0;
currFastIndex = 0;
trace("doPlay");
isProgressUpdate = false;
if (!isPlaying)
nsPlay.resume();
nsPlay.seek(nsPlay.time);
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(event:MouseEvent)
{
if(nsPlay == null) {
doConnect(event);
}
if (!isPlaying)
{
playControls.doPause.visible=true;
playControls.doPlay.visible=false;
doPlay();
}
else
{
playControls.doPause.visible=false;
playControls.doPlay.visible=true;
isProgressUpdate = false;
isPlaying = false;
nsPlay.pause();
}
}
// rewind to the beginning of the movie and start playing
function doRewind(event:MouseEvent)
{
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 (!isScrubbing && isProgressUpdate)
slider.sliderSlide.width = newWidth;
}
function updateProgress()
{
if(nsPlay != null)
setProgress(nsPlay.time);
}
// calculate the movie scrub location based on current mouse position
function calcScrub()
{
var xpos:Number = slider.mouseX;
var xmax:Number = 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(event:MouseEvent)
{
scrubTimer = setInterval(updateScrub, 250);
isScrubbing = true;
scrubTime = -1;
calcScrub();
scrubIsPlaying = isPlaying;
if (isPlaying)
nsPlay.pause();
}
// stop scrubbing and setup new play position
function stopScrub(event:MouseEvent)
{
if (scrubTimer)
clearInterval(scrubTimer);
scrubTimer = 0;
if (scrubTime != -1)
{
isProgressUpdate = false;
if (scrubIsPlaying)
{
isPlaying = true;
nsPlay.resume();
nsPlay.seek(scrubTime);
}
else
{
isPlaying = false;
nsPlay.seek(scrubTime);
}
}
isScrubbing = false;
}
function updateVideoSize()
{
//trace("updateVideoSize: "+stage["displayState"]);
// when we finally get a valid video width/height resize the video frame to make it proportional
if (videoObj.videoWidth != videoLastW || videoObj.videoHeight != videoLastH)
{
videoLastW = videoObj.videoWidth;
videoLastH = videoObj.videoHeight;
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)/2;
videoObj.x = saveVideoObjX + (saveVideoObjW - adjVideoObjW)/2;
videoObj.visible = true;
}
}
// show/hide the controls when we enter/leave fullscreen
function hideAllControls(doHide:Boolean)
{
//fpsText.visible = !doHide;
//logo.visible = !doHide;
connect.visible = !doHide;
controls.visible = !doHide;
playControls.doFullscreen.visible = !doHide;
slider.visible = !doHide;
backdrop.visible = !doHide;
playerVersion.visible = !doHide;
}
function enterLeaveFullscreen(fsEvent:FullScreenEvent)
{
trace("enterLeaveFullscreen: "+fsEvent.fullScreen);
hideAllControls(fsEvent.fullScreen);
if (!fsEvent.fullScreen)
{
// reset back to original state
stage.scaleMode = "showAll";
videoObj.width = adjVideoObjW;
videoObj.height = adjVideoObjH;
videoObj.y = saveVideoObjY + (saveVideoObjH - adjVideoObjH)/2;
videoObj.x = saveVideoObjX + (saveVideoObjW - adjVideoObjW)/2;
}
}
function enterFullscreen(event:MouseEvent)
{
trace("enterFullscreen: "+hardwareScaleCapable);
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.videoWidth;
videoObj.height = videoObj.videoHeight;
// 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 = "showAll";
var videoAspectRatio:Number = videoObj.width/videoObj.height;
var stageAspectRatio:Number = saveStageW/saveStageH;
var screenAspectRatio:Number = Capabilities.screenResolutionX/Capabilities.screenResolutionY;
// calculate the width and height of the scaled stage
var stageObjW:Number = saveStageW;
var stageObjH:Number = saveStageH;
if (stageAspectRatio > screenAspectRatio)
stageObjW = saveStageH*screenAspectRatio;
else
stageObjH = saveStageW/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 = 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: "+Capabilities.version+">="+v0+","+v1+","+v2+","+v3+": "+ret);
return ret;
}
try {
ExternalInterface.addCallback("playerStop", stopAll);
ExternalInterface.addCallback("setStream", setStream);
ExternalInterface.addCallback("setServer", setServer);
} catch(error:Error) {
prompt.text=""+error;
}
Are you able to reproduce the problems you experience with the default player that ships with Wowza? [install-dir]/examples/VideoOnDemandStreaming/FlashRTMPPlayer/player.html
If you have the same issues with the default player, please send your findings to support@wowza.com to open a ticket.
You can use the code in the default player as a starting place/reference to develop a custom player. Assisting in the development of a custom player is beyond the scope of the support forum.
You will find many talented developers eager to assist you in the find a consultant forum
Kind regards,
Salvadore