Search code examples
javavideostreamred5

Red5 video stream recording is breaking up


Finally I created a stream video recorder flash application and its simple Red5 backend but of course Red5 jokes me again. Most of the times the recorded videos are corrupted, cannot play them back without randomly stopping-resuming, hanging out the player .. and me as well. Why is it doing this?

I researched the internet and found this issue but no solution! I tried not to record the video instead switch it to live and attach an ffmpeg to do the dirty job but naturally the ffmpeg couldn't connect with the following error message on the red5's output:

Error executing call: Service: null Method: play Num Params: 1 0: my_little_stream ... blabla bla

Before I try out integrating the Xuggler stuff what I truly don't want to I ask you, what to do, can I attach the ffmpeg somehow or is there a configuration in the red5 server I should change.. or anything! Thanks!

Edit: I'm using Red5 1.0 RC2

Edit#2: I compiled the oflaDemo app from trunk sources with red5 1.0.0rc2 server files then created a live stream with a simple flex app just to try out if ffmpeg recorder worked. Now it could connect to red5 but the result is the same! The videos seems to be corrupt...


Solution

  • *But what should I put into the packetReceived() function? *

    I add this in a separated answer to highlight correctly:

    To write the packets to disk, you need: 1) the packet, 2) convert the packet to an ITag 3) Obtain an instance of a ITagWriter

    1) the packet data http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/flvrecord/listener/StreamVideoListener.java?view=markup around Line 50

    public void packetReceived(IBroadcastStream broadcastStream,
      IStreamPacket streampacket) {
    
    }
    

    streampacket => the packet you want to write to disk.

    2) write the packet by converting it to a ITag

    http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java?view=markup around Line 90ff

            IoBuffer data = streampacket.getData().asReadOnlyBuffer();
    
            if (data.limit() == 0) {
                return;
            }
    
            if (startTimeStamp == -1) {
                // That will be not bigger then long value
                startTimeStamp = streampacket.getTimestamp();
            }
    
            timeStamp -= startTimeStamp;
    
            ITag tag = new Tag();
            tag.setDataType(streampacket.getDataType());
    
            // log.debug("data.limit() :: "+data.limit());
            tag.setBodySize(data.limit());
            tag.setTimestamp(timeStamp);
            tag.setBody(data);
    
            writer.writeTag(tag);
    

    3) Obtaining an instance of a Writer

    http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java?view=markup around Line 90ff

    protected ITagWriter writer = null;
    
    private void init() throws IOException {
        file = new File(OmFileHelper.getStreamsSubDir(this.scope.getName()), this.streamName + ".flv");
    
        IStreamableFileFactory factory = (IStreamableFileFactory) ScopeUtils
                .getScopeService(this.scope, IStreamableFileFactory.class,
                        StreamableFileFactory.class);
    
        if (!this.file.isFile()) {
            // Maybe the (previously existing) file has been deleted
            this.file.createNewFile();
    
        } else if (!file.canWrite()) {
            throw new IOException("The file is read-only");
        }
    
        IStreamableFileService service = factory.getService(this.file);
        IStreamableFile flv = service.getStreamableFile(this.file);
        this.writer = flv.getWriter();
    
    }
    

    So this is a rough walk through. In that sense you can then go ahead.

    The http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java?view=markup

    class also contains a Queue to collect the packets.

    IStreamPacket.getType == 9 is video and I think 8 is audio (but you need to verify that).

    Sebastian