I have a NetGroup established using Adobe Cirrus. All clients can connect fine and see each other, since I receive NetGroup.Neighbor.Connect and NetGroup.MulticastStream.PublishNotify events when a new stream is being published.
However, if a user subscribes to a published stream, the publisher does not receive a notification (no NetStatusEvent and no callback to the onPeerConnect method). The subscriber receives the stream without problems, though.
All other questions about the non working onPeerConnect method were related to NetStream.DIRECT_CONNECTIONS, but in my case, I am using a NetGroup.
What is wrong here?
// Only the relevant parts, a few things have been stripped (e.g. connect the netGroup only when the NetConnection has been established etc.)
var groupSpecifier:GroupSpecifier = new GroupSpecifier("group");
groupSpecifier.multicastEnabled = true;
groupSpecifier.postingEnabled = true;
groupSpecifier.serverChannelEnabled = true;
groupSpecifier.objectReplicationEnabled = true;
groupSpecifier.ipMulticastMemberUpdatesEnabled = true;
groupSpecifier.routingEnabled = true;
var netGroup:NetGroup = new NetGroup(netConnection, groupSpecifier.groupspecWithAuthorizations());
var netStream:NetStream = new NetStream(netConnection, groupSpecifier.groupspecWithAuthorizations());
netStream.client = {onPeerConnect:onPeerConnect};
netStream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
// Never gets called
public function onPeerConnect(netStream:NetStream):Boolean {
trace("onPeerConnect: "+netStream.farID);
return true;
}
private function onNetStatus(event:NetStatusEvent):void {
trace(event.info.code);
switch(event.info.code) {
case EventCodes.STREAM_CONNECT_SUCCESS :
netStream.attachCamera(camera);
netStream.attachAudio(microphone);
netStream.publish(streamName);
break;
}
}
onPeerConnect is only being called when using DIRECT_CONNECTIONS, not for NetGroups. Unfortunately, this is not mentioned in the documentation or anywhere else.
Related
I'm really not familiar with Action Script 3 at all but I am with other languages.
I'm hoping someone could help me.
I'm attempting to make a modification to JWplayer so that an rtmp stream is retrieved via a PHP script rather than it being supplied in the HTML.
The code I currently have is below:
function useData(event:Event):void {
var data:String = event.target.data.toString();
}
/** Load content. **/
override public function load(itm:PlaylistItem):void {
_item = itm;
_position = 0;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, useData);
loader.load(new URLRequest("http://192.168.0.12/phpauth/play1.php"));
// Set Video or StageVideo
if(!_video) {
_video = new Video(320, 240);
_video.smoothing = true;
_video.addEventListener('renderState', renderHandler);
// Use stageVideo when available
if (_stageEnabled && RootReference.stage['stageVideos'].length > 0) {
_stage = RootReference.stage['stageVideos'][0];
_stage.viewPort = new Rectangle(0,0,320,240);
_stage.addEventListener('renderState', renderHandler);
}
attachNetStream(_stream);
}
// Load either file, streamer or manifest
if (_item.file.substr(0,4) == 'rtmp') {
// Split application and stream
var definst:Number = _item.file.indexOf('_definst_');
In the load function the file name to play is held in _item.file. I'm trying to make a call to a php script which then overwrites the value in _item.file. I've confirmed that the php is being called but I don't know how to get the data from the data string in the useData function into the _item.file string.
Any help would be really appreciated - I suspect this is a simple one but my lack of AS3 knowledge is making it really difficult.
Thanks,
Your problem basically about how to access a local variable in an event handler. A quick and dirty way can be to have an anonymous function used as a handler like:
loader.addEventListener(Event.COMPLETE, function(event:Event):void {
var data:String = event.target.data.toString();
_item.file = data;
});
This approach would work, because this anonymous function has access to the local variables inside load function as is. But, you need to be cautious that the anonymous function uses the variable exactly as the calling function is using. So, let's say there is a loop in load function and _item changes in every iteration of the loop. For that scenario, when load handler gets called, its _item would also have changed to the object which was last assigned to _item.
A far cleaner and OO approach can be to have a handler class like:
package {
public class LoadHandler {
private var _item:PlaylistItem;
public function LoadHandler(item:PlaylistItem) {
_item = item;
}
public function loadHandler(event:Event):void {
var data:String = event.target.data.toString();
_item.file = data;
}
}
and then have loader.addEventListener(Event.COMPLETE, (new LoadHandler(_item)).loadHandler). Hope that helps. BTW, LoadHandler could be made more generic to take and array of objects to be used and a callback function. loadHandler function, then could just call callback function with that array of objects.
If you are returning a simple string from PHP you should be able to use
event.target.data;
e.g. from PHP... echo "hello";
var data:String = event.target.data
You could try tracing the response to ensure you are getting something back from PHP.
You can either test this from within the IDE or install the Debug version of the Flash Player browser plugin.
trace("Response from PHP: "+event.target.data);
_item.file = event.target.data;
trace("_item.file: "+_item.file);
I'm making a connection with netconnection in AS3 Flash CS6. It works fine when I test the swf from my PC to the app on my Android. But when I install the app on 2 android devices they don't connect. Why is that? If I test with my PC and the two android devices it works too. How can I make it work with only the two android devices?
Here's the code I'm using:
var nc:NetConnection;
var group:NetGroup;
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
nc.connect("rtmfp:");
function netStatus(event:NetStatusEvent):void{
switch(event.info.code){
// The connection attempt succeeded
case "NetConnection.Connect.Success":
setupGroup();
break;
// The NetGroup is successfully constructed and authorized to function.
case "NetGroup.Connect.Success":
break;
// A new group posting is received
case "NetGroup.Posting.Notify":
trace("notify");
break;
case "NetGroup.SendTo.Notify":
trace("notify received");
break;
// user joins?
case "NetGroup.Neighbor.Connect":
break;
}
}
// Create a group
function setupGroup():void {
// Create a new Group Specifier object
var groupspec:GroupSpecifier = new GroupSpecifier("test");
// Enable posting
groupspec.postingEnabled = true;
//groupspec.routingEnabled=true;
// Specifies whether information about group membership can be exchanged on IP multicast sockets
groupspec.ipMulticastMemberUpdatesEnabled = true;
// Causes the associated NetStream or NetGroup to join the specified IP multicast group and listen to the specified UDP port.
groupspec.addIPMulticastAddress("225.225.0.1:30000");
// Constructs a NetGroup on the specified NetConnection object and joins it to the group specified by groupspec.
group = new NetGroup(nc,groupspec.groupspecWithAuthorizations());
// Set the NET_STATUS event listener
group.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
}
I suggest adding a default case statement to your switch. It may or may not shed some light on what is happening:
switch (event.info.code)
{
case "NetConnection.Connect.Success":
// etc... Not showing orig code
break;
// rest of the case statements here
// then lastly add this:
default:
trace(event.info.code);
}
I am trying to publish the video of a webcam to a Flash Media Server 2.
My code is working in the Flash standalone player (tested with 10.0 and 10.2), but not in the browser plugin (tested with 10.2, both in IE and Opera.
The connection to my FMS is working successfully, but after the publish, nothing happens, I never get the NetStream.Publish.Start Event. On the server I can see the connection in the management console, even the stream in the streams tab. But I cannot connect to that strea.
Anybody an idea what could be going wrong?
NetConnection.defaultObjectEncoding = ObjectEncoding.AMF0; // needed to get correct connection to FMS2
private function netStatusHandler(event:NetStatusEvent):void {
output.appendText("\n" + event.info.code);
switch (event.info.code) {
case "NetConnection.Connect.Success":
output.text = ("Connection successful, streaming camera...");
connectCamera();
break;
case "NetConnection.Connect.Failed":
break;
case "NetStream.Play.StreamNotFound":
break;
case "NetStream.Publish.Start":
output.appendText("\nPublishing video!");
break;
}
}
private function connectCamera(ev:Event = null):void {
var stream:NetStream = new NetStream(connection);
stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
stream.attachCamera(camera);
videoURL = createGUID();
stream.publish(videoURL, "live");
output.text = "publish stream...";
}
Ok, I found what my problem is here:
I declare the reference to the stream variable inside the connectCamera function:
private function connectCamera(ev:Event = null):void {
var stream:NetStream = new NetStream(connection);
}
So stream is only declared inside the scope of that function.
This doesn't seem to be a problem in the standalone player, but it is in the browser plugin. The browser plugin seems to do a much more thourough job on the garbage collector, garbage collecting my stream after the function has executed.
So what I have to do is declare the stream variable outside of the function scope, inside the class scope.
var stream:NetStream;
private function connectCamera(ev:Event = null):void {
stream = new NetStream(connection);
}
You should always declare stuff that you need later as a field on your class, and not inside a function. You just never know when GC might clean up that stuff.
When trying to send a POST request to an ASP.NET asmx web service I am seeing (in Charles and Firebug) it go through as a GET.
Here is my AS3
public function save(page:SharedPageVO, callback :Function = null): void {
var req:URLRequest = new URLRequest( "service.asmx/CreateSharedPage" );
req.data = page;
req.method = URLRequestMethod.POST;
if (callback != null)
{
//handle removing the event here instead of there
this.complete = callback;
DataService.instance.addEventListener(Event.COMPLETE, onComplete);
}
DataService.instance.load( req );
}
public var complete:Function;
private function onComplete(e:Event)
{
if (complete != null) complete(e);
complete = null;
DataService.instance.removeEventListener(onComplete);
}
This seems to be an issue with flash as it is happening before it even goes to the server. I have uploaded this to a testing server and I still see it come through as a GET. Any help would be appreciated. Thanks.
From actionscript LR (URLRequest class, method property):
Note: If running in Flash Player and the referenced form has no body, Flash Player automatically uses a GET operation, even if the method is set to URLRequestMethod.POST. For this reason, it is recommended to always include a "dummy" body to ensure that the correct method is used.
Are you using that "dummy" body?
I'm using a URLLoader to send a few key/value pairs to a php script, which then turns them into an e-mail, sends it (or not), and then echoes a string with a response.
At first it works fine. The URLLoader posts, and I get my e-mail a minute later, but for some reason I'm not getting my response back. In fact, my COMPLETE event doesn't seem to fire at all. This is confusing me because if I'm getting my e-mail, I know I must be sending everything properly. Here's my code:
public class Mailman{
public static const METHOD:String = URLRequestMethod.POST;
public static const ACTION:String = "mailer.php";
public static var myLoader:URLLoader = new URLLoader();
private static function onMessageProgress(e:Event){
var L:URLLoader = e.target as URLLoader;
Output.trace("PROGRESS: "+L.bytesLoaded+"/"+L.bytesTotal);
for(var k in L){
Output.trace(" "+k+": "+L[k]);
}
}
private static function onOpen(e:Event){
Output.trace("Connection opened");
}
private static function onComplete(e:Event){
Output.trace("Complete!");
}
private static function onStatusChange(e:HTTPStatusEvent){
Output.trace("Status Changed to "+e.status);
}
private static function onMessageFail(e:Event){
PanelManager.alert("ERROR: Could not send your request. Please try again later.");
}
public static function sendMessage(recipient:String,subject:String,message:String){
var _vars:URLVariables = new URLVariables();
_vars.recipient = recipient;
_vars.subject = subject;
_vars.message = message;
var req:URLRequest = new URLRequest(ACTION);
req.data = _vars;
req.method = METHOD;
myLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
myLoader.addEventListener(ProgressEvent.PROGRESS,onMessageProgress);
myLoader.addEventListener(Event.OPEN,onOpen);
myLoader.addEventListener(Event.COMPLETE,onComplete);
myLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS,onStatusChange);
myLoader.addEventListener(IOErrorEvent.IO_ERROR,onMessageFail);
myLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onMessageFail);
myLoader.load(req);
}
public static function test(){
sendMessage("john#example.com","test","this is a test message.");
}
function Mailman(){}
}
When I call Mailman.test(), I get my e-mail exactly like I expect, and this is what traces out:
Connection opened
PROGRESS: 45/45
Status Changed to 0
How can this be? If I'm understanding the documentation properly, the Open event happens when I begin downloading my response, and clearly that is happening, so how can I get back an http status of 0? Any ideas?
I found it.
The problem was with the URLLoader's dataFormat. This is the format for what you're getting BACK, not what you're sending. I switched it to URLLoaderDataFormat.TEXT and it worked perfectly.
Another reason this could happen - if you use weak references when registering your event listeners, and do not keep a reference to your URLLoader instance and the instance handling the event(s), GC may clean them up before they can receive any events.
//make sure the URLLoader and onComplete instances are not local vars
var req:URLRequest = new URLRequest("dosomething.php");
myLoader.addEventListener(Event.COMPLETE, onComplete, false, 0, TRUE);
myLoader.load(req);
Ok I found the answer in my case it was .NET page which was responsible for Status=0 in Chrome. What we were doing that in .net page at the line after writing response to be sent back to flash, we were closing the response object which was reseting the page and because of which Chrome was showing status=0 and couldn't render the result. After commenting out the response.close line it started working fine.
I wrote my experience with this problem and how i was able to solve it at http://viveklakhanpal.wordpress.com/2010/07/01/error-2032ioerror/
Thanks,
Vivek.