简体   繁体   中英

Unable to publish live stream continously without any halt via RTMP to FMS using Xuggler

I am trying to forward live RTMP streaming video from link1 to link2. But when video stops or pause at input end then my java application stops reading packets and get error 'unable to read RTMP-Header Packet'. Code is given below-

import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IContainerFormat;
import com.xuggle.xuggler.IPacket;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;

public class XugglerRecorder
{
    public static void main(String[] args)
    {
        String url = "rtmp://IP:PORT/live2/16_8_2013";

        IContainer readContainer = IContainer.make();
        readContainer.setInputBufferLength(4096);
        IContainer writeContainer=IContainer.make();
        //writeContainer.setInputBufferLength(0);
        IContainerFormat containerFormat_live = IContainerFormat.make();
        containerFormat_live.setOutputFormat("flv","rtmp://IP:PORT/live/abc", null);
       int retVal= writeContainer.open("rtmp://192.168.1.198:1935/live/abc", IContainer.Type.WRITE, containerFormat_live);
        //writeContainer.setInputBufferLength(0);
        if (retVal < 0) {
            System.err.println("Could not open output container for live stream");
            System.exit(1);
        }

        if (readContainer.open(url, IContainer.Type.READ, null, true, false) < 0) {
            throw new RuntimeException("unable to open read container");
        }

        IStream video = writeContainer.addNewStream(0);
        if (video == null) {
            throw new RuntimeException("unable to add video stream");
        }

        IPacket packet = IPacket.make();
        while (readContainer.readNextPacket(packet) >= 0 && !packet.isKeyPacket()) {}

        IStreamCoder inVideoCoder = null;
        int videoStreamId = -1;
        for (int i = 0; i < readContainer.getNumStreams(); ++i) {
            IStream stream = readContainer.getStream(i);
            IStreamCoder coder = stream.getStreamCoder();
            if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
                inVideoCoder = coder;
                videoStreamId = i;

                if (inVideoCoder.open(null, null) < 0) {
                    throw new RuntimeException("Unable to open input video coder");
                }

                //for getting frame params need to decode at least one key frame
                IVideoPicture picture = IVideoPicture.make(inVideoCoder.getPixelType(), 0, 0);

                int bytesDecoded = inVideoCoder.decodeVideo(picture, packet, 0);
                if (bytesDecoded < 0) {
                    throw new RuntimeException("Unable to decode video packet");
                }
             }
        }

        if (videoStreamId == -1) {
            throw new RuntimeException("unable to find video stream");
        }        

        IStreamCoder outVideoCoder = video.getStreamCoder();
        outVideoCoder.setCodec(inVideoCoder.getCodec());
        outVideoCoder.setHeight(inVideoCoder.getHeight());
        outVideoCoder.setWidth(inVideoCoder.getWidth());
        outVideoCoder.setPixelType(inVideoCoder.getPixelType());
        outVideoCoder.setBitRate(inVideoCoder.getBitRate());
        outVideoCoder.setTimeBase(inVideoCoder.getTimeBase());
        if (outVideoCoder.open(null, null) < 0) {
            throw new RuntimeException("unable to open output video coder");
        }

        if (writeContainer.writeHeader() < 0) {
            throw new RuntimeException("unable to write header");
        }

        int i = 0;
      doit(readContainer, packet, writeContainer);
        if (writeContainer.writeTrailer() < 0) {
            throw new RuntimeException("unable to write trailer");
        }

    }

    private static void doit(IContainer readContainer, IPacket packet,
            IContainer writeContainer) {
        int i = 0;
        while (readContainer.readNextPacket(packet) >= 0) {
            if(readContainer.readNextPacket(packet)<0)
            {
                System.out.println("Packet null Hello");
                try{
                    doit(readContainer, packet, writeContainer);            
                }catch(Exception e){e.printStackTrace();}
                continue;
             }

            if(readContainer.readNextPacket(packet)==-1 ){
                System.out.println("Packet is absent"); 
            }

            if (packet.getStreamIndex() != 0) {
                continue;
            }

            if (writeContainer.writePacket(packet) < 0 && readContainer.readNextPacket(packet)>=0) {
                try{
                    System.out.println(" packet sleep");
                }catch(Exception e){e.printStackTrace();}
            }

        }       
    }
}

I am able to publish live video to FMS via RTMP. But unable to store save point of video before stop or pause of video streaming. If there is any time lag of input streaming then my application should keep on checking and waiting for stream instead of stopping. Kindly help me out from this. Thanks in advance.

Any help or tips for how to debug this would be immensely appreciated.

I don't know much about Xuggler.

You might try catching Exception.

Or you might try calling doit() one more time in main method. Suppose in case if no more packets will be there to read then method doit() overs. So, it will not try to read again.

Or you can try adding something like while (container.readPacket==null) {} at the starting of doit() OR I think it will be while (container.readPacket!=null) {}

Try not checking for isKeyPacket and see what will happen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM