Can't connect to host using rtmfp - actionscript-3

I have a p2p game using Adobe's rtmfp protocol and cirrus server. Everything seems to be working fine when I try it in stand alone flash player, but when I embed the game to the web page, suddenly nobody can't connect to my game. There are no errors, the connection just timeouts after a while.
here is how I create NetConnection on the host:
netConnection = new NetConnection();
netConnection.maxPeerConnections = 20;
netConnection.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
netConnection.connect("rtmfp://p2p.rtmfp.net/3a34e[redacted]af45f80/");
public function onNetStatus(event:NetStatusEvent) : void
{
var peer:P2PNetPeer = null;
switch(event.info.code) {
case "NetConnection.Connect.Success":
streamOut = new NetStream(netConnection, NetStream.DIRECT_CONNECTIONS);
streamOut.client = {onPeerConnect:onPeerConnect};
streamOut.publish(netConnection.nearID);
break;
}
It's almost same on client side, except when I get NetConnection.Connect.Success I create inStream:
streamIn = new NetStream(netConnection, farId);
streamIn.client = {msg:onMessageReceived};
streamIn.addEventListener(NetStatusEvent.NET_STATUS, onInStreamStatus, false, 0, true);
streamIn.play(farId);
This inStream is the one that causes problem, it never connects to the host specified by his farId (I pair players and exchange near/farIds using my own server) if the game is run from web page. When I run it locally using stand alone player, it connects almost immediatelly.
I am checking for other states and errors as well, but they are not important here (as said, I am not getting any errors, just timeout after a while)
Any idea what might be going on here?

Related

Getting Bitmap from Video decoded with Nestream AppendBytes (AS3)?

I am wondering if someone who has handled NetStream.appendBytes in Flash knows how to get the bitmapData from a decoded video frame? I have already looked at this question but that is from 3 years ago and the more recent comment/answer seems to be gone. In 2014 has anyone managed to turn those bytes into a bitmap? I am working with Flash Player 11.8 and this is not a desktop/AIR app.
In the image below I can do steps 1) and 2) but there's a brick wall at step 3)
The problem is that simply using bitmapdata.draw(video_container); does not work but instead it throws a Policy File error even though I am using a byteArray (from local video file in the same directory as the SWF). No internet is even involved but Flash tells me that "No Policy File granted permission from the server" or such nonsense. I think the error is just a bail-out insteading of straight up saying "You are not allowed to do this.."
I have tried: trying to appease this Crossdomain.xml issue anyway and looking into all known security/domain settings. I came to the conclusion that the error is not the problem but a side effect of the issue.. The issue here being that: Flash Player is aware of the SWF's location and of any files local to it. That's okay when you pass a String as URL etc but when the Netstream data is not local to the SWF domain then it becomes a Policy File issue. Problem is my data is in the Memory not in a folder like the SWF and therefore cannot alllow bitmapData.draw since it cannot "police" an array of bytes, any known fixes for this?... (I can't even say the words I really wanted to use).
What I am trying to achieve: Is to essentially use Netstream as an H.263 or H.264 image decoder in the same way Loader is a JPEG-to-Bitmap decoder or LoadCompressed.. is an MP3-to-PCM decoder. You know, access the raw material (here RGB pixels), apply some effects functions and then send to screen or save to disk.
I know it is a little late, but I think I found a solution for your problem.
So, to avoid the Security sandbox violation #2123 Error, you have just to do like this :
// ...
net_stream.play(null);
net_stream.play('');
// ...
Hope that can help.
I know this question is a couple months old, but I wanted to post the correct answer (because I just had this problem as well and other will too).
Correct answer:
It's a bug that has been open at adobe for almost 2 years
Link to the bug on Adobe
Work Around until the bug gets fixed (I am using this and it works great):
Workaround using Sprite and graphics
To take a snapshot from a video stream we don't need NetStream.appendBytes which inject data into a NetStream object.
For that we can use BitmapData.draw which has some security constraints. That's why in many times we get a flash security error. About that, Adobe said :
"... This method is supported over RTMP in Flash Player 9.0.115.0 and later and in Adobe AIR. You can control access to streams on Flash Media Server in a server-side script. For more information, see the Client.audioSampleAccess and Client.videoSampleAccess properties in Server-Side ActionScript Language Reference for Adobe Flash Media Server. If the source object and (in the case of a Sprite or MovieClip object) all of its child objects do not come from the same domain as the caller, or are not in a content that is accessible to the caller by having called the Security.allowDomain() method, a call to the draw() throws a SecurityError exception. This restriction does not apply to AIR content in the application security sandbox. ...".
For crossdomain file creation and some other security config for AMS server, you can take a look on this post : Crossdomain Video Snapshot - Fixing BitmapData.draw() Security Sandbox Violation.
After allowing our script to get data from our video stream, we can pass to the code.
I wrote a code that play a video stream ( rtmp or http ) and take a snapshot to show it in the stage or save it as a file after applying a pixel effect :
const server:String = null; //'rtmp://localhost/vod'
const stream:String = 'stream'; // 'mp4:big_buck_bunny_480p_h264.mp4';
var nc:NetConnection;
var ns:NetStream;
var video:Video;
const jpg_quality:int = 80;
const px_size:int = 10;
nc = new NetConnection();
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, function(e:AsyncErrorEvent):void{});
nc.addEventListener(NetStatusEvent.NET_STATUS, function(e:NetStatusEvent):void{
if(e.info.code == 'NetConnection.Connect.Success'){
ns = new NetStream(nc);
ns.addEventListener(NetStatusEvent.NET_STATUS, function(e:NetStatusEvent):void{});
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, function(e:AsyncErrorEvent):void{});
video = new Video(320, 180);
video.x = video.y = 10;
video.attachNetStream(ns);
addChild(video);
ns.play(stream);
}
})
nc.connect(server);
btn_show.addEventListener(
MouseEvent.CLICK,
function(e:MouseEvent): void{
var bmp:Bitmap = pixelate(video, px_size);
bmp.x = 10;
bmp.y = 220;
addChild(bmp);
}
)
btn_save.addEventListener(
MouseEvent.CLICK,
function(e:MouseEvent): void{
var bmp:Bitmap = pixelate(video, px_size);
var jpg_encoder:JPGEncoder = new JPGEncoder(80);
var jpg_stream:ByteArray = jpg_encoder.encode(bmp.bitmapData);
var file:FileReference = new FileReference();
file.save(jpg_stream, 'snapshot_'+int(ns.time)+'.jpg');
}
)
function pixelate(target:DisplayObject, px_size:uint):Bitmap {
var i:uint, j:uint = 0;
var s:uint = px_size;
var d:DisplayObject = target;
var w:uint = d.width;
var h:uint = d.height;
var bmd_src:BitmapData = new BitmapData(w, h);
bmd_src.draw(d);
var bmd_final:BitmapData = new BitmapData(w, h);
var rec:Rectangle = new Rectangle();
rec.width = rec.height = s;
for (i = 0; i < w; i += s){
for (j = 0; j < h; j += s){
rec.x = i;
rec.y = j;
bmd_final.fillRect(rec, bmd_src.getPixel32(i, j));
}
}
bmd_src.dispose();
bmd_src = null;
return new Bitmap(bmd_final);
}
Of course, this is just a simple example to show the manner to get a snapshot from a video stream, you should adapt and improve it to your needs ...
I hope all that can help you.

Pulling up to 12 RTMP streams

I am VERY new to this site! I have been reading the codes for the past few nights! From Publishing a flash project with network access so it can contact the internet to RTMP applications and streaming. But I have hit a wall and I do not want to go off the wrong path as most of my work is bits and pieces of helpful information on this site. And please appologize I'm not the boss of a company, so I do not do much of the coding any more and i have surely forgotten most of my PHP coding background, Please do not smite me for dumb or"noob". But since I have made it this far with the flash and actionscripts3 programming I thought it would not hurt if I asked a few questions from much smarter people!
Currently I am working on a single windowed flash project that will allow me to pull up to 12 live RTMP streams. Currently with everything i have been able to do, I have a working code so far to JUST pull a single RTMP string. Took me 3 days of code that was pulled off the internet, to get it to work. i have been successful in getting one stream with action script
package com.endseven {
import flash.events.NetStatusEvent;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import com.endseven.RTMPStream;
public class Downstream extends RTMPStream {
/* the constructor. */
public function Downstream():void {
trace("Downstream object has been created."); // debug trace..
this.oVideo = new Video(640, 480);
this.oConnection = new NetConnection();
this.oConnection.addEventListener(NetStatusEvent.NET_STATUS, eNetStatus, false, 0, true);
this.oConnection.connect(this.sMediaServerURL);
}
/* triggered when a net status event is received. */
private function eNetStatus(oEvent1:NetStatusEvent) {
trace("NetStatusEvent: " + oEvent1.info.code); // debug trace..
switch (oEvent1.info.code) {
case "NetConnection.Connect.Success":
// create a stream for the connection..
this.oNetStream = new NetStream(oConnection);
this.oNetStream.addEventListener(NetStatusEvent.NET_STATUS, eNetStatus, false, 0, true);
this.oNetStream.bufferTime = 5; // set this to whatever is comfortable..
// listen for meta data..
this.oMetaData.onMetaData = eMetaDataReceived;
this.oNetStream.client = this.oMetaData;
// attach the stream to the stage..
this.oVideo.attachNetStream(oNetStream);
this.oNetStream.play(sStreamName);
this.addChildAt(this.oVideo, 0);
trace("Connected to the RTMP server."); // debug trace..
break;
case "NetConnection.Connect.Closed":
trace("Disconnected from the RTMP server."); // debug trace..
break;
case "NetStream.Play.StreamNotFound":
trace("This stream is currently unavailable."); // debug trace..
break;
}
}
}
}
This is the actionscript3 code that is the only code i have gotten to work. But this only pulls in a single stream on a single display. I mean I could work with this and just have twelve of them. But that seems to be a waste. What is the best method to get this to work. I am very new so this next question seems even dumb to me! But cant i just create 12 flash files and import them and arrange them in a single project?

Connect to IP in application layer, Adobe Air

I'm working on a project about "controlling embedded system by smartphones via wifi",
I developed my app on adobe Air, and built my system on PIC microcontroller to accept connections on application layer (Http), the ip address is 192.168.20.60:80(responsed when browsing from web browsers).
Instead of using sockets to connect through port 80, I used urlloader to read HTML pages (urlrequest("x.com")).
But when I tried to connect to ip address IOexception appears,
here's the code:
var PicPage:URLLoader=new URLLoader();
PicPage.load(new URLRequest("192.168.20.60")); //worked using DNS
lgn.addEventListener(Event.COMPLETE,ff);
function ff(e:Event):void{
var s:String=e.target.data;
trace(s);
}
As Pixel Elephant said, You need to have http:// in front of the IP you are trying to contact. You don't need to specify port 80 though.
Try the following code:
var PicPage:URLLoader = new URLLoader();
PicPage.addEventListener(Event.COMPLETE, onLoaded);
PicPage.addEventListener(IOErrorEvent.IO_ERROR, onError);
PicPage.load(new URLRequest("http://192.168.20.60/"));
protected function onLoaded(e:Event):void {
var s:String = e.target.data;
trace(s)
}
protected function onError(e:Event):void {
// Handle the error in any way you'd like
}
I've used this code ( and variations of it ) multiple times myself and it has served me well.

record video using flash media server 4.5

Hello i am trying to capture my camera as an flv file with fms 4.5 i am doing the following:
protected function rec_clickHandler(event:MouseEvent):void
{
nc = new NetConnection();
nc.client = { onBWDone: function():void{ trace("onBWDone") } };
nc.connect("rtmp://localhost/vod");
nc.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
}
private function netStatusHandler(e:NetStatusEvent):void {
var code:String = e.info.code;
if(code == "NetConnection.Connect.Success"){ //in case of recording...
ns = new NetStream(nc);
ns.attachCamera(cam);
ns.attachAudio(mic);
ns.publish("filename","record");
}
else{
trace(code);
}
}
but i get the following error:
Error #2044: Unhandled NetStatusEvent:. level=error, code=NetStream.Record.NoAccess
Can anyone help? what am i doing wrong?
This status message, NetStream.Record.NoAccess, generally indicates that you don't have write permissions to the stream. Check the permissions of your streams dir to see if it is read only.
If that is not the issue, check which application are you trying to publish to, does not SSAS that has code to deny write access to stream
Make sure the previously recorded video is not being opened in any video player. If it is being accessed by some other program, it will not allow you to record or rewrite it.

Flash SecurityDomain, P2P settings and multiply swfs

I have two swfs:
application swf
p2p client swf that allows to load data using rtmfp replication
technology (through cirrus service)
The main idea is to have one p2p loader on the certain domain that will able to work in p2p network without asking many times for permission for each domain, so for instance:
application 1 (http://domain1.com/app.swf) |
application 2 (http://domain2.com/app.swf) | <--> p2p data loader (http://domainp2p.com/p2pcli.swf)
application N (http://domainN.com/app.swf) |
The p2p client loads binary data by request, content really does not matter I believe.
So, I load p2pclient swf using following class (app.swf)
public class ClientLoader {
// .. some code
public function load(cb:Function, err:Function):void
{
_cb = cb;
_err = err;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onLoaded);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, _onIoError);
loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _onSecurityError);
// note that context has neither application domain nor security domain
loader.load(new URLRequest(_url), new LoaderContext());
}
private function _onLoaded(e:Event):void
{
trace("Loaded. Connecting to the p2p network...");
_client = e.target.content;
_client.addEventListener(Event.CONNECT, _onClientReady);
_client.connect();
}
private function _onClientReady(e:Event):void
{
_cb(_client);
}
}
}
The p2pclient itself (p2pcli.swf):
public class P2P extends Sprite
{
public function SqP2P() {
Security.allowDomain("*");
}
public function connect():void
{
_connection = new NetConnection();
_connection.addEventListener(NetStatusEvent.NET_STATUS, _netStatus);
_connection.connect(CIRRUS_ADDRESS, CIRRUS_KEY);
// after successful connect this method called
_loadGroup();
}
private method _loadGroup():void
{
var spec:GroupSpecifier = new GroupSpecifier(_name);
spec.serverChannelEnabled = true;
spec.objectReplicationEnabled = true;
_group = new NetGroup(connection, spec.groupspecWithAuthorizations());
_group.addEventListener(NetStatusEvent.NET_STATUS, _netStatus);
}
private function _netStatus(event:NetStatusEvent):void
{
trace("NetStatusEvent:", event.info.code);
}
}
But it looks like that Flash Player ignores the security session and is trying to save the pop-up settings for the domain that app.swf belongs to, but not for the p2pcli.swf domain. Why?!
I have absolutely same code, but p2pcli.swf replaced with swf that stores data in Local Shared Object and all the domain1-2-N.com has access to it.
Any ideas?
I know, my English is crap :(
I really am not totally sure, but I'll throw my answer out there in case it is helpful.
Based on the general purpose of such security messages, I'm not entirely sure you CAN keep that dialog from showing up. In some cases, I'm certain Peer Assisted Networking can be a security risk for some people (and anyway, it is using their bandwidth.) The settings for turning on and off that notification are user-side, in the Flash settings dialog (Control Panel in Windows 7...), thus that hints that it is inherently hardwired into the Flash platform.
Of course, since I'm more of an Adobe AIR specialist, I could be completely wrong...for your project's sake, I'm sincerely hoping I AM!
And, for the record, your English was almost perfect. I tweaked one paragraph for clarity, but otherwise, spot on. :D