Created
July 11, 2016 15:26
-
-
Save mondain/975db7985d952a0e0f904fc440f79d0b to your computer and use it in GitHub Desktop.
Publisher flex mxml to show sending of onStreamSend data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" | |
xmlns:s="library://ns.adobe.com/flex/spark" | |
xmlns:mx="library://ns.adobe.com/flex/mx" | |
width="320" height="400" minWidth="220" minHeight="176" | |
currentState="start" creationComplete="init()"> | |
<fx:Script><![CDATA[ | |
import flash.events.*; | |
import flash.media.*; | |
import flash.net.*; | |
import mx.core.FlexGlobals; | |
import mx.events.FlexEvent; | |
import org.osmf.net.StreamType; | |
import spark.components.mediaClasses.DynamicStreamingVideoItem; | |
import spark.components.mediaClasses.DynamicStreamingVideoSource; | |
{ | |
private static var nc:NetConnection; | |
private static var ns:NetStream; | |
private static var playerVideo:Video; | |
private static var cam:Camera; | |
private static var mic:Microphone; | |
[Bindable] | |
private static var WIDTH:int = 320; | |
[Bindable] | |
private static var HEIGHT:int = 240; | |
[Bindable] | |
public var host:String; | |
[Bindable] | |
public var appName:String; | |
[Bindable] | |
public var roomName:String; | |
[Bindable] | |
public var streamName:String; | |
// whether or not you are publishing | |
[Bindable] | |
public var publishing:Boolean = false; | |
[Bindable] | |
public var autoPublish:Boolean = false; | |
public var camIndex:int = 0; | |
private function init():void { | |
Security.allowDomain("*"); | |
if (FlexGlobals.topLevelApplication.parameters.hasOwnProperty('host')) { | |
// host override parameter | |
host = FlexGlobals.topLevelApplication.parameters.host; | |
} else { | |
var url:String; | |
if (stage.loaderInfo) { | |
url = stage.loaderInfo.url; | |
} else { | |
url = loaderInfo.url; | |
} | |
var pattern:RegExp = new RegExp("(http|https)://([^/]*)/"); | |
if (pattern.test(url) == true) { | |
var results:Array = pattern.exec(url); | |
host = results[2]; | |
//need to strip the port to avoid confusion | |
if (host.indexOf(":") > 0) { | |
host = host.split(":")[0]; | |
} | |
} | |
} | |
// get app name | |
appName = FlexGlobals.topLevelApplication.parameters.appName; | |
// get room name | |
roomName = FlexGlobals.topLevelApplication.parameters.roomName; | |
// get stream name | |
streamName = FlexGlobals.topLevelApplication.parameters.streamName; | |
if (FlexGlobals.topLevelApplication.parameters.hasOwnProperty('width')) { | |
WIDTH = new int(FlexGlobals.topLevelApplication.parameters.width); | |
} | |
if (FlexGlobals.topLevelApplication.parameters.hasOwnProperty('height')) { | |
HEIGHT = new int(FlexGlobals.topLevelApplication.parameters.height); | |
} | |
if (FlexGlobals.topLevelApplication.parameters.hasOwnProperty('autoPublish')) { | |
autoPublish = new Boolean(FlexGlobals.topLevelApplication.parameters.autoPublish); | |
} | |
// setup our callbacks for javascript | |
ExternalInterface.addCallback("connect", connect); | |
ExternalInterface.addCallback("disconnect", disconnect); | |
ExternalInterface.addCallback("isPublishing", isPublishing); | |
} | |
public function isPublishing():Boolean { | |
log("isPublishing: " + streamName); | |
return currentState === "publish" && publishing; | |
} | |
// change the camera | |
public function changeCamera(... evt):void { | |
camIndex += 1; | |
if (camIndex >= Camera.names.length) { | |
camIndex = 0; | |
} | |
if (ns) { | |
ns.attachCamera(null); | |
} | |
// publish / update netstream | |
flash.utils.setTimeout(publish, 500); | |
} | |
// publish our stream | |
public function publish(... evt):void { | |
//ExternalInterface.call("alert", "Trying to publish..."); | |
// get the first camera | |
if (Camera.names.length > 0) { | |
currentState = "publish"; | |
try { | |
log("Camera index: " + camIndex + " name: " + Camera.names[camIndex]); | |
cam = Camera.getCamera(String(camIndex)); | |
mic = Microphone.getEnhancedMicrophone(); | |
} catch (e:Error) { | |
log("Error: " + e.message); | |
} | |
if (cam) { | |
// set props | |
cam.setMode(WIDTH, HEIGHT, 15); | |
cam.setQuality(0, 96); | |
cam.setKeyFrameInterval(150); | |
//ExternalInterface.call("alert", "Camera selected: " + Camera.names[camIndex]); | |
// change video display to the new camera | |
flash.utils.setTimeout(attachCamera, 500); | |
// add h.264 settings | |
var h264Settings:H264VideoStreamSettings = new H264VideoStreamSettings(); | |
h264Settings.setProfileLevel(H264Profile.BASELINE, H264Level.LEVEL_3); | |
ns.videoStreamSettings = h264Settings; | |
// add camera to the netstream | |
ns.attachCamera(cam); | |
log("Camera: " + cam.name); | |
} else { | |
log("There was a problem connecting to your camera"); | |
cam = null; | |
ns.attachCamera(cam); | |
} | |
if (mic) { | |
// audio attach | |
mic.codec = SoundCodec.SPEEX; | |
mic.enhancedOptions.mode = MicrophoneEnhancedMode.FULL_DUPLEX; | |
mic.enhancedOptions.echoPath = 256; | |
mic.encodeQuality = 6; | |
mic.rate = 22; // 16 kHz | |
mic.gain = 80; | |
//mic.framesPerPacket = 5; // 20 ms each | |
mic.setUseEchoSuppression(true); | |
mic.setLoopBack(false); | |
mic.enableVAD = true; | |
ns.attachAudio(mic); | |
} else { | |
log("There was a problem connecting to your microphone"); | |
mic = null; | |
ns.attachAudio(mic); | |
} | |
if (cam || mic) { | |
// if we're already publishing dont restart it | |
if (!publishing) { | |
// publish | |
ns.publish(streamName, "live"); | |
} | |
} | |
} else { | |
ExternalInterface.call("alert", "No media capture device detected"); | |
} | |
} | |
public function stopPublish(evt:Event):void { | |
if (ns) { | |
ns.attachCamera(null); | |
ns.attachAudio(null); | |
disconnect(evt); | |
} | |
currentState = "start"; | |
} | |
// connect | |
public function connect(... evt):void { | |
if (nc != null && nc.connected) { | |
flash.utils.setTimeout(publish, 500); | |
return; | |
//disconnect(evt); | |
} | |
// create the netConnection | |
nc = new NetConnection(); | |
nc.objectEncoding = ObjectEncoding.AMF3; | |
// set it's client/focus to this | |
nc.client = this; | |
nc.proxyType = "best"; | |
// add listeners for netstatus and security issues | |
nc.addEventListener(NetStatusEvent.NET_STATUS, nc.client.onStatus); | |
var uri:String = "rtmp://" + host + "/" + appName + "/" + roomName; | |
log("Connect uri: " + uri); | |
nc.connect(uri, null); | |
} | |
// disconnect | |
public function disconnect(... evt):void { | |
if (nc != null && nc.connected) { | |
log("Disconnecting"); | |
try { | |
nc.close(); | |
} catch(e:Error) { | |
log("Error on disconnect: " + e.message); | |
} | |
} | |
} | |
public function onBWDone(... obj):void { | |
// have to have this for an RTMP connection | |
log('Bandwidth check completed'); | |
} | |
public function onBWCheck(... rest):uint { | |
log("onBWCheck"); | |
//have to return something, so returning anything :) | |
return 0; | |
} | |
public function onResult(val:*):void { | |
log("onResult: " + val); | |
} | |
public function onStatus(evt:NetStatusEvent):void { | |
log("NetConnection.onStatus: " + evt.info.code + " Description: " + evt.info.description); | |
if (evt.info !== '' || evt.info !== null) { | |
var desc:String = evt.info.description; | |
switch (evt.info.code) { | |
case "NetConnection.Connect.Success": | |
log("Connected"); | |
// setup the netstream | |
ns = new NetStream(nc); | |
ns.addEventListener(NetStatusEvent.NET_STATUS, onStatus); | |
ns.client = this; | |
// auto publish | |
if (autoPublish) { | |
flash.utils.setTimeout(publish, 500); | |
} | |
break; | |
case "NetConnection.Connect.Failed": | |
ExternalInterface.call("alert", "Connection failed"); | |
break; | |
case "NetConnection.Connect.Rejected": | |
log("Connection rejected"); | |
break; | |
case "NetConnection.Connect.Closed": | |
log("Disconnected"); | |
// reset publishing flag | |
publishing = false; | |
break; | |
case "NetConnection.Call.Failed": | |
ExternalInterface.call("alert", "Remote call failed"); | |
break; | |
// NS events | |
case "NetStream.Publish.Start": | |
log("Publishing: " + streamName); | |
publishing = true; | |
break; | |
case "NetStream.Publish.BadName": | |
ExternalInterface.call("alert", "Publish error - A stream already exists for the name requested: " + streamName); | |
break; | |
case "NetStream.Unpublish.Success": | |
case "NetStream.Publish.Stop": | |
log("Publish has stopped"); | |
publishing = false; | |
currentState = "start"; | |
break; | |
case "NetStream.Failed": | |
log("Stream error - An error has occured in the net stream"); | |
break; | |
case "NetStream.Video.DimensionChange": | |
log("Stream video change"); | |
break; | |
default: | |
log("Unhandled status"); | |
break; | |
} | |
} | |
} | |
public function attachCamera(... evt):void { | |
if (cam) { | |
// attach the camera | |
if (playerVideo) { | |
playerVideo.clear(); | |
playerVideo.attachCamera(null); | |
} else { | |
playerVideo = new Video(WIDTH, HEIGHT); | |
playerVideo.smoothing = true; | |
} | |
playerVideo.attachCamera(cam); | |
publishDisplay.addChild(playerVideo); | |
log("Camera dimensions: " + cam.width + " x " + cam.height); | |
} | |
} | |
public function log(message:String):void { | |
ExternalInterface.call("log", streamName, message); | |
} | |
} | |
// send 100 NS.send messages and then disconnect after 500 ms | |
protected function sendBtn_clickHandler(event:MouseEvent):void { | |
log("NS.send"); | |
var i:uint = 0; | |
while (i !== 100) { | |
log("Sending: " + i); | |
ns.send("onStreamSend", "[index:"+ i +"]"); | |
i += 1; | |
} | |
flash.utils.setTimeout(disconnect, 500); | |
} | |
protected function sendDFBtn_clickHandler(event:MouseEvent):void { | |
log("NS.send @setDataFrame"); | |
var map:Object = { | |
rnd: "" + Math.ceil(Math.random() * 9999) | |
}; | |
ns.send("@setDataFrame", "onStreamSend", map); | |
} | |
protected function disconnBtn_clickHandler(event:MouseEvent):void { | |
if (nc.connected) { | |
nc.close(); | |
} | |
} | |
]]></fx:Script> | |
<s:states> | |
<s:State name="start"/> | |
<s:State name="publish"/> | |
</s:states> | |
<s:Image includeIn="start" x="0" y="0" width="{WIDTH}" height="{HEIGHT}" smooth="false" | |
source="assets/red5-button.png" click="connect(event)"/> | |
<s:SpriteVisualElement includeIn="publish" id="publishDisplay" | |
x="0" y="0" minWidth="220" minHeight="176" width="{WIDTH}" height="{HEIGHT}" | |
opaqueBackground="#0000ff" click="changeCamera(event)"/> | |
<s:HGroup x="10" y="332" width="301" height="58" horizontalAlign="center" | |
verticalAlign="middle"> | |
<s:Button label="Send" click="sendBtn_clickHandler(event)" | |
x.publish="10" y.publish="369"/> | |
<s:Button label="Send DF" click="sendDFBtn_clickHandler(event)"/> | |
<s:Button label="Disconnect" click="disconnBtn_clickHandler(event)" | |
x.publish="88" y.publish="369"/> | |
</s:HGroup> | |
</s:Application> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment