Обнаружение закрытия TCP-соединения при воспроизведении Flash-видео - PullRequest
2 голосов
/ 16 февраля 2011

На стороне клиента 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

Ответы [ 3 ]

4 голосов
/ 16 февраля 2011

Я не знаю ни одного события, сигнализирующего о сброшенном соединении, кроме «NetStream.Failed», которое работает только с Flash Media Server (и я даже не знаю, запускается ли когда-либо или когда-либо).

Необходимо найти базу решений на NetStream.Buffer.Empty: запускать таймер при каждом возникновении этого события, подождать достаточно долго, чтобы убедиться, что соединение вряд ли восстановится,затем начните новую попытку.Вы можете сбросить таймер на каждом «NetStream.Buffer.Full», или когда фильм заканчивается или останавливается вручную, чтобы он не принес никакого вреда, если он действительно не нужен.

2 голосов
/ 20 сентября 2012

Скорее используйте статусы NetConnection: NetConnection.Connect.Closed

Я столкнулся с подобной проблемой и заметил, что значение NetStream.bytesTotal усекается при сбое видеосоединения.Таким образом, сначала запишите длину видео в байтах в соответствии с NetStream и используйте его для обнаружения сбоя при вызове NetConnection.Connect.Closed.

Поскольку код видео невозможно объяснить вне контекста, я поставилэто вместе, опираясь на пример Flash @ Пример Flash NetConnection

Вот код, встроенные комментарии:

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);
    }
}
1 голос
/ 11 июля 2011

После интенсивного тестирования с использованием NetLimiter в Windows (чтобы неожиданно прервать соединение TCP) запускается только NetStream.Buffer.Empty.

Единственное доступное вам решение, которое вам дал weltraumpirat (запуск Timer)чтобы убедиться, что вы все еще активно получаете данные).

Очевидно, что URLStream :: connected остается верным после потери всех соединений TCP и останавливается (без какого-либо IO_ERROR или других событий / исключений, как NetStream). Если вы нацеливаетесь на> 10.1 Flash, вы можете использовать URLStream для загрузки данных в NetStream :: appendBytes (см. Документацию для режима генерации данных (включите, передав NULL в NetStream :: play ())), а затем, когдаПолучая NetStream.Buffer.Empty, немедленно проверьте URLStream :: connected, чтобы увидеть, если вы все еще подключены к серверу, вместо запуска Timer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...