AMS doesn't receive unpublish command SOMETIMES over rtmpt
Asked Answered
G

2

7

This one has had me going for a week at least. I am trying to record a video file to AMS. It works great almost all of the time, except about 1 in 10 or 15 recording sessions, I never receive 'NetStream.Unpublish.Success' on my netstream from AMS when I close the stream. I am connecting to AMS using rtmpt when this happens, it seems to work fine over rtmp. Also, it seems like this only happens in safari on mac, but since its so intermittent I don't really trust that. Here is my basic flow:

// 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

}

Update I am now using a new NetConnection per connection attempt and also not forcing port 80 (see my 'answer' below). This has not solved my connection woes, only made the instances more infrequent. Now like every week or so I still have some random failure of ams or flash. Most recently someone made a recording and then flash player was unable to load the video for playback. The ams logs show a connection attempt and then nothing. There should at least be a play event logged for when i load the metadata. This is quite frustrating and impossible to debug.

Gonsalve answered 24/11, 2014 at 23:36 Comment(3)
Have you tried using wireshark and actually check?Brutal
Could this be a "too quick to check" issue? Can you do a try/catch where if it fails the unpublish command you wait a moment before re-attempting to unpublish..? I think the nature of RTMPT (being an HTTP wrapper for RTMP et al) sometimes causes hiccups so perhaps a timed retry might help..Lavoisier
I'm having exactly the same issue, did you ever find a solution? How about calling close() again after a period of time if NetStream.Unpublish.Success is not received?Zuckerman
L
0

I would try 2 distinct NetConnection objects, one for record and one for replay. This will remove your complexities around listeners adding/removing and connect/reconnect/disconnect logic and would IMO be cleaner. NetConnections are cheap, and I've always used one per task at hand. The other advantage is that you can connect both at startup so the replay connection is ready instantly.

I've not seen a Promise used here before, but I'm not qualified to comment if that may cause a problem or not.

Laflamme answered 2/12, 2014 at 22:30 Comment(0)
G
0

I think my issue was connecting over port 80. I originally thought I had to use port 80 with rtmpt, so I set my Settings.recordServer variable to rtmpt://myamsserver.net:80/app. I'm now using a shotgun approach where I try a bunch of port/protocol combos at once and pick the first one to connect. It is almost always picking port 443 over rtmpt, which seems much faster and more stable all around than 80, and I haven't had this issue since. It could also be due to not reusing the same NetConnection object like Stefan suggested, its hard to say.

Gonsalve answered 2/12, 2014 at 22:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.