Hi,
The bug of 'SecurityError: Error #2123: Security sandbox violation: BitmapData.draw: file:///xxx/xxx.swf cannot access rtmfp://fms4.acrobat.com/cocomo/na2-sdk-xxx/xxx. No policy files granted access.' was first reported in lccs forum over a year ago:
http://forums.adobe.com/message/2803074
But the bug is still around. The bug can be generated by calling BitmapData.draw() on a flash.media.Video object which is attached to a p2p stream. It looks like the solution is to have the publisher to call:
send("|RtmpSampleAccess", true, true)
on the NetStream object _before_ the subscriber calls NetStream.play(), in order to give the permission to subscribers for audio and video streams.
In lccs library, the above permission authorisation happens in WebcamPublisher:
protected function onNetStatus(p_evt:NetStatusEvent):void
{
if (p_evt.info.code=="NetStream.Connect.Success") {
setTimeout(sendSnapShotPermission, 500);
_stream.send("|RtmpSampleAccess", true, true);
}
}
protected function sendSnapShotPermission():void
{
_stream.send("|RtmpSampleAccess", true, true);
}
but it doesn't help the problem. In fact, it is not clear to me when this 'snap shot permission' is sent to the subscriber.
One more note: This is not a critisism for the lccs development quality, but rather a question on how ready lccs is for production use. After encountering this bug, I had to go through the lccs code (the open source parts), and found out that the library is not really written, well, carefully, and it is full of temporary quick-n-dirty fixes.
For instance in the above example, sendSnapShotPermission() is called after 500 milliseconds, probably to allow something to happen before calling the method, but how can you be sure that it will happen in 500 milliseconds? Probably,an event listener should have been used. Immediately in the next line, we see:
_stream.send("|RtmpSampleAccess", true, true);
which is a duplicate of sendSnapShotPermission(). many examples like this can be found throughout the library.
Aureliano
Views
Replies
Total Likes
Hi there,
To the best of my knowledge, this bug was fixed - can you give more precise
steps to reproduce? If it's still reproduced, there's likely still some
tricky timing case.
I don't want to criticize you (you can always tell when someone starts a
sentence this way, they're about to say something indelicate), but based on
your post I'd suggest that you don't really understand the code well enough
to critique it - which event listener would you need to listen to to make
this work? There's actually a pretty good reason why the message is sent on
a regular interval. Can you tell me what it is? And please, if you're
looking for help from us, try to refrain from insulting us in the same post.
respect
nigel
Views
Replies
Total Likes
Hi Nigel,
Two questions:
1. When the publisher sends the access permission to the subcriber by:
netStream.send("|RtmpSampleAccess", true, true)
, on the subscriber side, what event or function can handle the guaranteed receipt of the access permission? Currently it is possible to draw the incoming stream video upon receiving NetStream.Play.Star and waiting for 5 seconds or so:
public class MyWebcamSubscriber extends WebcamSubscriber {
override protected function layoutCameraStreams():void
{
// trying the event listener seems to work here.
_streamManager.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
}
override protected function onNetStatus(e:NetStatusEvent):void
{
super.onNetStatus(e);
case "NetStream.Play.Start":
setTimeout(function():void {
// draw the video from the incoming stream here.
}, 5000);
}
}
The questions is, which event can let the subscriber know that it has the access permission to the video stream?
2. In WebcamPublisher, why is that the access permission is sent 3 times?
a. Once on receiving NetStream.Connect.Success with 0.5 second delay, as in below.
b. Once immediately upon receiving NetStream.Connect.Success, as in below.
protected function onNetStatus(p_evt:NetStatusEvent):void
{
if (p_evt.info.code=="NetStream.Connect.Success") {
setTimeout(sendSnapShotPermission, 500);
_stream.send("|RtmpSampleAccess", true, true);
}
}
protected function sendSnapShotPermission():void
{
_stream.send("|RtmpSampleAccess", true, true);
}
c. Once in onConnectionTypeChange() with 2 seconds delay:
protected function onConnectionTypeChange(p_evt:StreamEvent):void
{
//...
if ( _streamManager.isP2P) {
_stream= new NetStream(_connectSession.sessionInternals.session_internal::connection as NetConnection,NetStream.DIRECT_CONNECTIONS);
setTimeout(sendSnapShotPermission, 2000);
}
//...
}
Views
Replies
Total Likes
Any updates on the above two questions?
Views
Replies
Total Likes
Could someone from the lccs team address the above 2 questions.
Views
Replies
Total Likes
A week later, still waiting for a response about the above 2 questions.
Views
Replies
Total Likes
Karma's a pain, I agree.
nigel
Views
Replies
Total Likes
In all seriousness, could you answer my original question - how are you
reproducing this issue? The more precise the better. I've just done a quick
test, and was able to get a snapshot working. There must be some timing
element here - anything you can do to narrow it down would be appreciated.
nigel
Views
Replies
Total Likes
I tried to answer that question in my previous post, I explain it here again. Consider this subclass of WebcamSubscriber:
public class MyWebcamSubscriber extends WebcamSubscriber {
override protected function onNetStatus(e:NetStatusEvent):void
{
super.onNetStatus(e);
case "NetStream.Play.Start":
var t:int = 5000;
setTimeout(function():void {
// draw the video from the incoming stream here, using BitmapData#draw()
}, t);
}
}
In the above, if you decrease t to 0, you'll get the security sandbox violation error.
You need to use BitmapData#draw() to get the error. The VideoComponent class does not seem to call this method explicitly.
Maybe it's a good idea to define and dispatch a snapshot permission event after:
_stream.send("|RtmpSampleAccess", true, true);
so that calling BitmapData#draw() can be done with more confidence, rather than trying an ad hoc timeout.
Views
Replies
Total Likes
Nigel: any updates on the above two questions?
Views
Replies
Total Likes
Hi,
Not sure what your answer to my question is - you say that if you mess with
the code, you get the error? I realize you need to do a BitmapData.draw -
I'm asking when are you calling this? Decreasing the interval to 0 means
that the permissions message will never get received, so, yeah, you'll hit
the error.
Here's the deal (I honestly don't know why I'm helping here) - for each
subscriber, they need to receive the permissions message AFTER they connect
to the stream but BEFORE they take a snapshot. To accomplish this, we have
the publisher send a regular permissions message on a 5s interval - this
does mean that there's a window of time where the stream is connected but
not snapshot-ready. An easy way to workaround the issue is to use a
try-catch block around your BitmapData.draw, and, should it catch the error,
try again in a few seconds.
I'll try to preempt your complaint here : yes, there's a way you could make
this more precise. You could have each subscriber send a message to the
publisher each time a subscriber connects to the stream. That message would
tell the publisher to please send the permissions message to the new
subscriber. Upon doing so, the publisher could then send another message to
the subscriber to tell it that it has done so. When the subscriber receives
the message, it could dispatch an event notifying the dev that Bitmap
capture is now enabled. But ultimately, this is a fairly intricate piece of
coordination, and would likely introduce even further timing issues and
bugs. And at the end of the day for the dev, doing a try-catch solution
isn't a significant amount more work than waiting for an event to declare
the stream is ready (they're both asynchronous, ultimately). We considered
both solutions, and opted for the simpler one.
hope that helps
nigel
Views
Replies
Total Likes
Views
Likes
Replies