我正在尝试将实时RTMP流视频从link1转发到link2。但是,当视频在输入端停止或暂停时,我的Java应用程序将停止读取数据包,并出现错误“无法读取RTMP-Header数据包”。代码如下-

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();}
            }

        }
    }
}


我可以通过RTMP将实时视频发布到FMS。但是无法在停止或暂停视频流之前存储视频的保存点。如果输入流有任何时间滞后,则我的应用程序应继续检查并等待流,而不是停止。
请帮助我。提前致谢。

任何有关调试的帮助或技巧将不胜感激。

最佳答案

我对Xuggler不太了解。

您可以尝试捕获异常。

或者您可以尝试在main方法中再调用一次doit()。假设万一没有更多的数据包可以读取,则方法doit()会溢出。因此,它不会尝试再次读取。

或者您可以尝试添加类似
同时(container.readPacket == null){}在doit()开头,否则我认为
while(container.readPacket!= null){}

尝试不检查isKeyPacket,看看会发生什么。

08-04 05:00
查看更多