在Flash客户端,如何检测服务器何时故意关闭与其视频流的TCP连接?发生这种情况时我需要采取措施 - 可能会尝试重新启动视频或显示错误消息。目前,连接关闭和连接缓慢对我来说是一样的。在这两种情况下,NetStream
对象都会引发NetStream.Play.Stop
事件。当连接速度很慢时,它通常会在几秒钟内自行恢复。我希望只在连接关闭时采取行动,而不是在连接缓慢时采取行动。
以下是我的常规设置的样子。这是基本的NetConnection
- > NetStream
- > Video
设置。
this.vidConnection = new NetConnection();
this.vidConnection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, this.connectionAsyncError);
this.vidConnection.addEventListener(IOErrorEvent.IO_ERROR, this.connectionIoError);
this.vidConnection.addEventListener(NetStatusEvent.NET_STATUS, this.connectionNetStatus);
this.vidConnection.connect(null);
this.vidStream = new NetStream(this.vidConnection);
this.vidStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, this.streamAsyncError);
this.vidStream.addEventListener(IOErrorEvent.IO_ERROR, this.streamIoError);
this.vidStream.addEventListener(NetStatusEvent.NET_STATUS, this.streamNetStatus);
this.vid.attachNetStream(this.vidStream);
当服务器关闭TCP或连接冻结时,不会触发任何错误事件。只有NetStream.Play.Stop
事件触发。以下是从最初播放视频到TCP连接关闭所发生的情况。
connection net status = NetConnection.Connect.Success
playStream(http://192.168.0.44/flv/4d29104a9aefa)
NetStream.Play.Start
NetStream.Buffer.Flush
NetStream.Buffer.Full
NetStream.Buffer.Empty
checkDimensions 0 0
onMetaData
NetStream.Buffer.Full
NetStream.Buffer.Flush
checkDimensions 960 544
NetStream.Buffer.Empty
NetStream.Buffer.Flush
NetStream.Play.Stop
当我在连接关闭和连接缓慢期间对各种属性进行转储时,我看不到可以帮助我区分结束和缓慢的独特值。
NetConnection->connected = true
NetConnection->connectedProxyType = none
NetConnection->proxyType = none
NetConnection->uri = null
NetConnection->usingTLS = false
VidStream->bufferLength = 0
VidStream->bufferTime = 0.1
VidStream->bytesLoaded = 3204116
VidStream->bytesTotal = 3204116
VidStream->currentFPS = 0
VidStream->time = 63.797
答案 0 :(得分:4)
除了“NetStream.Failed”之外,我不知道发出连接断开的任何事件,只能与Flash Media Server一起使用(我甚至不知道是否或何时被解雇)
你必须找到一个基于“NetStream.Buffer.Empty”的解决方案:每当发生此事件时启动一个计时器,让它等待足够长的时间以确保连接不可能恢复,然后启动一个新的尝试。您可以在每个“NetStream.Buffer.Full”上重置计时器,或者在电影结束或手动暂停时重置计时器,这样除非确实需要,否则不会造成任何伤害。
答案 1 :(得分:2)
使用NetConnection状态而不是:NetConnection.Connect.Closed
我遇到了类似的问题&注意到视频连接失败时会截断NetStream.bytesTotal值。因此,根据NetStream捕获视频长度(以字节为单位)以&在调用NetConnection.Connect.Closed时使用它来检测故障。
因为视频代码无法在上下文中解释,所以我将它放在一起,建立在Flash的示例@ Flash NetConnection Example
上以下是代码,内联评论:
public class NonTruncatedNetConnectionExample extends Sprite {
private var videoURL:String = "http://www.helpexamples.com/flash/video/cuepoints.flv";
private var connection:NetConnection;
private var stream:NetStream;
private var video:Video = new Video();
// ADDITION: special length variable to check for truncation
private var videoBytes:uint;
public function NonTruncatedNetConnectionExample() {
connection = new NetConnection();
connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
connection.connect(null);
}
private function netStatusHandler(event:NetStatusEvent):void {
switch (event.info.code) {
case "NetConnection.Connect.Success" :
connectStream();
break;
case "NetStream.Play.StreamNotFound" :
trace("Stream not found: " + videoURL);
break;
// ADDITION: this will be triggered when the connection is closed
// on completion, or on failure
case "NetConnection.Connect.Closed" :
if (this.videoBytes != this.stream.bytesTotal) {
// failure
// you can throw the error here
// or in the loadingProgress function below
} else {
// success
// the video loaded completely
}
break;
}
}
private function securityErrorHandler(event:SecurityErrorEvent):void {
trace("securityErrorHandler: " + event);
}
private function connectStream():void {
var stream:NetStream = new NetStream(connection);
stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
stream.client = new CustomClient();
video.attachNetStream(stream);
stream.play(videoURL);
addChild(video);
// ADDITION: the loadingProgress function
this.addEventListener(Event.ENTER_FRAME, loadingProgress);
}
/***
** ADDITION : loadingProgress captures the length of the video in bytes for use in comparison when
** NetConnection.Connect.Closed is called
** It also tracks current loading progress so you can use it as a buffer indicator
*/
private function loadingProgress(E:Event):void {
// check that this.stream.client has initialised & you have correct access to this.stream variables
// bytesTotal is also a divisor so must be greater than 0 before continuing, or it will hard-fail
if (this.stream.client && this.stream.bytesTotal > 0) {
// sanity checker ;)
trace("bytesLoaded = " + this.stream.bytesLoaded + " :: bytesTotal = " + this.stream.bytesTotal);
// capture the video's total bytes only if the variable does not yet exist
// before this point this.stream.bytesTotal returns a bogus (really big) number
// watch out for capturing this.stream.totalBytes before this point, or you create a double negative,
// because it won't match the actual bytesTotal & will therefore error [ it got me :( ; but then I got it ;) ]
if (!this.videoBytes) this.videoBytes = this.stream.bytesTotal;
// compare this to stream.totalBytes to detect truncation
if (this.videoBytes != this.stream.bytesTotal) {
// error
// you can throw the error here if you want, or wait for the NetConnection.Connect.Closed switch above
} else {
// or you can detach this event listener here while just holding on to the videoBytes variable
// & wait for the NetConnection.Connect.Closed switch above
// e.g. this.removeEventListener(Event.ENTER_FRAME, loadingProgress);
}
// use this to drive a buffer bar if you want
var radian:Number = (this.stream.bytesLoaded / this.totalBytes);
var percent:Number = radian * 100;
}
}
}
还有:
class CustomClient {
public function onMetaData(info:Object):void {
trace("metadata: duration=" + info.duration + " width=" + info.width + " height=" + info.height + " framerate=" + info.framerate);
}
public function onCuePoint(info:Object):void {
trace("cuepoint: time=" + info.time + " name=" + info.name + " type=" + info.type);
}
}
答案 2 :(得分:1)
在Windows上使用NetLimiter进行密集测试(意外地“终止”TCP连接)后,只会触发NetStream.Buffer.Empty。
解决方案weltraumpirat为您提供了唯一可用的解决方案(启动计时器以查看您是否仍在主动接收数据)。
显然,丢失所有TCP连接后,URLStream :: connected仍然为真,并且停止(没有任何IO_ERROR或其他事件/异常,就像NetStream一样)。
如果您的目标是> 10.1 Flash,您可以使用URLStream将数据加载到NetStream :: appendBytes中(请参阅数据生成模式的文档(通过将null传递给NetStream :: play()来启用)),然后,当接收NetStream.Buffer.Empty时,立即检查URLStream :: connected以查看您是否仍然连接到服务器,而不是启动Timer。