Skip to main content
February 27, 2010
Answered

Recorded stream corrupted when stopped and appended

  • February 27, 2010
  • 1 reply
  • 949 views

I'm combining streams from a number of cameras together into a recorded stream, let's called it 'serverstream.flv'.  The source streams are all from webcams, and each user is assigned a stream name based on their name and a user id, like '1_bob' and '2_julie'.

Sometimes the presenters stop broadcasting temporarily and we just switch to a blank window.  The stream on the server side stops recording at that point by calling

serverStream.record(false);

and then when the presenter comes back I start recording again with

serverStream.record("append");

The viewers are subscribing to serverStream and this works fine for them.  But the recorded flv gets corrupted every time I do this.  It plays only until the first time recording stopped and then after that the data is seriously mangled. Some tools from Moyea can extract the audio and video, but the video has errors with frozen frames or incorrect playback speed.

But here's the strange part.  I tried just recording the presenter streams individually, so there's a file called '1_bob.flv' and '2_julie.flv', etc.  In the same way I'm stopping and appending as necessary.  But these recordings are just fine, without the corruption at the stopping points.  After a great deal of experimentation I find that the recorded FLVs are ONLY okay when they are named to match the camera stream.  If I create any new stream on the server, called something like 'bob_stream' and play the stream '1_bob' on it, I get errors in the recording. 

What could be going on?  Where could this be coming from?

I should point out that this is running FMIS 3.5 and worked flawlessly until recently.  Then the server was updated with the latest build of FMIS and we're getting this problem.  The application code both client-side and server-side didn't change, so it's got to be something in the FMIS configuration that changed, but I can't think what it could be.

Any help would be very greatly appreciated.

    This topic has been closed for replies.
    Correct answer SE_0208

    I doubt whether it can be configuration issue but i will still check out. I did not your logic and use case very clearly but before i spent more time on this can you change your code little bit and see if that work:-

    1. Change the order of play and record i.e.

        serverstream.record();

        serverstream.play(streamName,-1)

    2. Can you put Application.xml in your application folder ( i mean at same level where you have your main.asc) and add <EraseOnPublish>false</EraseOnPublish>

    under <Application>/<StreamManager>/<Live>

    Try this and let me know what results you get , meanwhile i will try to look in more detail about your code workflow

    1 reply

    Participating Frequently
    March 1, 2010

    Its difficult to tell what problems you are running into. Is it possible for you to post the server-side and client-side code, you can mail me(post private message) the same if you don't want to post it here.

    March 8, 2010

    There's a lot of code that isn't particularly important for this problem at hand, but here's the important stuff.

    The client app is a Flex application.  All presenters are streaming at all times to the server, but only one is being rebroadcast.  The moderator selects the presenter that gets broadcast.  That triggers newClient.connectStream on the server side. The problems come in particularly if ever the video broadcast is stopped (which we refer to as reverting to logo because the video window shows a company logo in it).  That's done with the newClient.revertToLogo function.

    ...


    var serverStream;

    var currentClientStream;


    ...


    application.onAppStart = function() {


    ...

        

         recordingFileName = dirs[1] + "_" + dirs[2] + "_" + appStartTime + "_stream";            // Create a new stream for recording the session on the server that's includes the room number and timestamp in the filename      serverStream = Stream.get(recordingFileName );


    ...


    }


    newClient.connectStream = function(streamName) {

         // Set the sharedObject to point to the selected presenter's stream   

         application.currentStreamSO.setProperty("currentStream", streamName);

         trace("Stream changed: " + streamName);

         // Start the recording clock running and log the presenter change           setRecording(true);                 // ******* This should work but doesn't seem to properly      // serverStream and visibleStream play the right streams but serverStream's recording gets data corruption and lost time      // Subscribe to the new stream      serverStream.play(streamName, -1);      serverStream.record("append")    

                    trace("Beginning recording of streams");                           /* This _does_ work, but appending is only okay if it's a client stream that's being recorded

          * not a stream created on the server that's playing the client stream */

         currentClientStream = Stream.get(streamName);                currentClientStream.play(streamName, -1);      currentClientStream.record("append");

    }

    newClient.revertToLogo = function() {            ...

         application.currentStreamSO.setProperty("currentStream", null);      serverStream.record(false);           currentClientStream.record(false); ...

    }

    The code that's cut out is just for clarity.  It's mostly to do with some logging and slide changing, but nothing to do with the video streams.

    You can see that there are two streams being recorded, the serverStream which plays whatever client stream is selected and should record that as one long file, and the currentClientStream, which changes each time a different presenter is selected and records a stream that matches their stream name (so like 1201_Mike_Jones.flv for instance).  This has no problem recording and appending.  It's ONLY the stream created on the server side that has this issue.

    If I record for, say 20 seconds, then revert to logo, then record that same presenter for another 20 seconds, there are two files, the serverStream recording and the 1201_Mike_Jones recording.  They are _almost_ identical in size, but not exactly.  The serverStream will vary by a few hundred bytes.  Opening them both, the 1201_Mike_Jones will have a file length of 40 seconds but the serverStream recording will only show a length of 20 seconds.  The video can be extracted with some video tools, but it gets garbled after the append.

    I experimented a bit to see if it's a problem with the the way serverStream was created, even though I couldn't see how.  So I tried changing the line currentClientStream = Stream.get(streamName); to currentClientStream = Stream.get(streamName + "_test"); and then leaving the rest the same.  Of course the result is that now I get a file called 1201_Mike_Jones_test.flv.  And now it has the file error.  So it's any stream that's created server side appears to be unable to append properly.

    This problem started after rebuilding the server with 3.5.3, a totally fresh install.  Since then it's been downgraded back to 3.5.2 and continues to do this.  The code worked prior to that, so I have to wonder if it's a configuration issue, but what could cause this?

    SE_0208Correct answer
    Participating Frequently
    March 8, 2010

    I doubt whether it can be configuration issue but i will still check out. I did not your logic and use case very clearly but before i spent more time on this can you change your code little bit and see if that work:-

    1. Change the order of play and record i.e.

        serverstream.record();

        serverstream.play(streamName,-1)

    2. Can you put Application.xml in your application folder ( i mean at same level where you have your main.asc) and add <EraseOnPublish>false</EraseOnPublish>

    under <Application>/<StreamManager>/<Live>

    Try this and let me know what results you get , meanwhile i will try to look in more detail about your code workflow