Actionscript 3 AMS没有';t有时通过rtmpt接收取消发布命令
这一次至少让我走了一个星期。我正在尝试将视频文件录制到AMS。它几乎在所有时间都工作得很好,除了大约十分之一或15个录制会话之外,我在关闭流时从未在我的NetStream上收到AMS的“NetStream.Unpublish.Success”。我正在使用rtmpt连接AMS。当这种情况发生时,它似乎可以在rtmp上正常工作。而且,这似乎只发生在mac上的safari中,但由于它是如此断断续续,我真的不相信这一点。以下是我的基本流程:Actionscript 3 AMS没有';t有时通过rtmpt接收取消发布命令,actionscript-3,rtmp,netstream,flash-media-server,adobe-media-server,Actionscript 3,Rtmp,Netstream,Flash Media Server,Adobe Media Server,这一次至少让我走了一个星期。我正在尝试将视频文件录制到AMS。它几乎在所有时间都工作得很好,除了大约十分之一或15个录制会话之外,我在关闭流时从未在我的NetStream上收到AMS的“NetStream.Unpublish.Success”。我正在使用rtmpt连接AMS。当这种情况发生时,它似乎可以在rtmp上正常工作。而且,这似乎只发生在mac上的safari中,但由于它是如此断断续续,我真的不相信这一点。以下是我的基本流程: // just a way to use promises w
// just a way to use promises with netStatusEvents
private function netListener(code:String, netObject:*):Promise {
var deferred:Deferred = new Deferred();
var netStatusHandler:Function = function (event:NetStatusEvent):void {
if (event.info.level == 'error') {
deferred.reject(event);
} else if (event.info.code == code) {
deferred.resolve(netObject);
// we want this to be a one time listener since the connection can swap between record/playback
netObject.removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
}
};
netObject.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
return deferred.promise;
}
// set up for recording
private function initRecord():void {
Settings.recordFile = Settings.uniquePrefix + (new Date()).getTime();
// detach any existing NetStream from the video
_view.video.attachNetStream(null);
// dispose of existing NetStream
if (_videoStream) {
_videoStream.dispose();
_videoStream = null;
}
// disconnect before connecting anew
(_nc.connected ? netListener('NetConnection.Connect.Closed', _nc) : Promise.when(_nc))
.then(function (nc:NetConnection):void {
netListener('NetConnection.Connect.Success', _nc)
.then(function (nc:NetConnection):void {
_view.video.attachCamera(_webcam);
// get new NetStream
_videoStream = getNetStream(_nc);
ExternalInterface.call("CTplayer." + Settings.instanceName + ".onRecordReady", true);
}, function(error:NetStatusEvent):void {
ExternalInterface.call("CTplayer." + Settings.instanceName + ".onError", error.info);
});
_nc.connect(Settings.recordServer);
}); // end ncClose
if (_nc.connected) _nc.close();
}
// stop recording
private function stop():void {
netListener('NetStream.Unpublish.Success', _videoStream)
.then(function (ns:NetStream):void {
ExternalInterface.call("CTplayer." + Settings.instanceName + ".onRecordStop", Settings.recordFile);
});
_videoStream.attachCamera(null);
_videoStream.attachAudio(null);
_videoStream.close();
}
// start recording
private function record():void {
netListener('NetStream.Publish.Start', _videoStream)
.then(function (ns:NetStream):void {
ExternalInterface.call("CTplayer." + Settings.instanceName + ".onRecording");
});
_videoStream.attachCamera(_webcam);
_videoStream.attachAudio(_microphone);
_videoStream.publish(Settings.recordFile, "record"); // fires NetStream.Publish.Success
}
更新
我现在每次连接尝试都使用一个新的NetConnection,并且没有强制使用端口80(请参阅下面的“答案”)。这并没有解决我的连接问题,只是使实例更加罕见。现在像每周左右,我仍然有一些随机故障的ams或闪存。最近有人录制了一段视频,但flash player无法加载视频进行播放。ams日志显示连接尝试,然后什么也没有。当我加载元数据时,应该至少记录一个播放事件。这非常令人沮丧,无法调试。我将尝试两个不同的NetConnection对象,一个用于录制,另一个用于回放。这将消除侦听器添加/删除和连接/重新连接/断开连接逻辑的复杂性,而且IMO会更干净。 网络连接很便宜,我总是在手头的每个任务中使用一个。另一个优点是,您可以在启动时同时连接这两个设备,以便立即准备好重播连接
我以前没有看到这里使用过承诺,但我没有资格评论这是否会导致问题 我想我的问题是通过端口80连接。我最初认为必须在rtmpt中使用端口80,因此我将
设置。recordServer
变量设置为rtmpt://myamsserver.net:80/app
。我现在使用的是散弹枪方法,我一次尝试一组端口/协议组合,然后选择第一个连接。它几乎总是选择端口443而不是rtmpt,rtmpt似乎比80快得多,也更稳定,从那以后我就没有过这个问题。也可能是因为没有像Stefan建议的那样重用相同的NetConnection
对象,这很难说。您是否尝试过使用wireshark并进行实际检查?这是否是一个“检查太快”的问题?您是否可以执行try/catch,如果取消发布命令失败,请等待片刻,然后重新尝试取消发布。。?我认为RTMPT(作为RTMP等的HTTP包装器)的性质有时会导致打嗝,因此可能需要定时重试。我遇到了完全相同的问题,您是否找到了解决方案?如果未收到NetStream.Unpublish.Success
,则在一段时间后再次调用close()如何?