截屏遇到"Error #2123: 安全沙箱冲突"等问题(服务端为RED5)
问题描述 :
使用 BitmapData/draw() 方法报错如下
SecurityError: Error #2123: 安全沙箱冲突:BitmapData.draw:http://192.168.141.1:8080/js/flex/SunVideo.swf 不能访问 rtmp://192.168.141.1/SunVST。未被授权访问任何策略文件。
使用 ImageSnapshot.captureBitmapData(panel); 截屏报错如下 :
TypeError: Error #1009: 无法访问空对象引用的属性或方法。
两种方式其实都是一种错 , 都是没有获取到data
解决方案 :
在red5服务端修改任一spring的xml配置文件添加信息如下 :
<bean id="rtmpSampleAccess" class="org.red5.server.stream.RtmpSampleAccess"> <property name="audioAllowed" value="true"/> <property name="videoAllowed" value="true"/> </bean>
相关说明 :
audioAllowed是音频相关的 ,
videoAllowed是视频相关的(截屏的话关改他就行)
red5服务端类 org.red5.server.net.rtmp.Channel 的 sendStatus方法中 :
public void sendStatus(Status status) { final boolean andReturn = !status.getCode().equals(StatusCodes.NS_DATA_START); final Notify event; if (andReturn) { final PendingCall call = new PendingCall(null, "onStatus", new Object[] { status }); event = new Invoke(); if (status.getCode().equals(StatusCodes.NS_PLAY_START)) { IScope scope = connection.getScope(); if (scope.getContext().getApplicationContext().containsBean(IRtmpSampleAccess.BEAN_NAME)) {//加入上面那段spring配置就会进入该if语句内 IRtmpSampleAccess sampleAccess = (IRtmpSampleAccess) scope.getContext().getApplicationContext().getBean(IRtmpSampleAccess.BEAN_NAME); boolean videoAccess = sampleAccess.isVideoAllowed(scope); boolean audioAccess = sampleAccess.isAudioAllowed(scope); if (videoAccess || audioAccess) { final Call call2 = new Call(null, "|RtmpSampleAccess", null); Notify notify = new Notify(); notify.setInvokeId(1); notify.setCall(call2); notify.setData(IoBuffer.wrap(new byte[] { 0x01, (byte) (audioAccess ? 0x01 : 0x00), 0x01, (byte) (videoAccess ? 0x01 : 0x00) })); write(notify, connection.getStreamIdForChannel(id)); } } } event.setInvokeId(1); event.setCall(call); } else { final Call call = new Call(null, "onStatus", new Object[] { status }); event = new Notify(); event.setInvokeId(1); event.setCall(call); } // We send directly to the corresponding stream as for // some status codes, no stream has been created and thus // "getStreamByChannelId" will fail. write(event, connection.getStreamIdForChannel(id)); }
IRtmpSampleAccess.BEAN_NAME的值为rtmpSampleAccess ; 加入上面那段spring配置就会进入该if语句内 ; 然后就可以截屏了...
之前试过 crossdomain.xml , NetStream.send("|RtmpSampleAccess", true, true) 等方法没有成功