Could not open output container for live stream

不打扰是莪最后的温柔 提交于 2019-12-11 19:34:04

问题


I am working on YouTube broadcasting Java program. So far, I can create live event using this program:

https://github.com/youtube/api-samples/tree/master/java

For more detail what I am getting so far, please see my another question:

https://stackoverflow.com/questions/30449366/how-to-send-video-stream-for-live-event-using-youtube-broadcast-in-java

Now, the next thing is I want to create a video stream which will be passed to live streaming YouTube APIs so that my video will be broadcasting as Live Event on YouTube.

For this, I am using Xuggler library 5.2. However, when I try to run sample program for Xuggler so I get following message and neither works anything nor my webcam starts.

Source code:

import java.awt.Dimension;
import java.awt.image.BufferedImage;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamResolution;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IContainerFormat;
import com.xuggle.xuggler.IPacket;
import com.xuggle.xuggler.IPixelFormat;
import com.xuggle.xuggler.IRational;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.video.ConverterFactory;
import com.xuggle.xuggler.video.IConverter;



public class HelloWorld {

    public static void main(String[] args) {
        IContainer container = IContainer.make();
        IContainerFormat containerFormat_live = IContainerFormat.make();
        containerFormat_live.setOutputFormat("flv", "rtmp://a.rtmp.youtube.com" + "/"+ "live2", null);
        container.setInputBufferLength(0);
        int retVal = container.open("rtmp://a.rtmp.youtube.com" + "/"+ "live2", IContainer.Type.WRITE, containerFormat_live);
        if (retVal < 0) {
            System.err.println("Could not open output container for live stream");
            System.exit(1);
        }

        Dimension size = WebcamResolution.QVGA.getSize();

        IStream stream = container.addNewStream(0);
        IStreamCoder coder = stream.getStreamCoder();
        ICodec codec = ICodec.findEncodingCodec(ICodec.ID.CODEC_ID_H264);
        coder.setNumPicturesInGroupOfPictures(4);
        coder.setCodec(codec);
        coder.setBitRate(500000);
        coder.setPixelType(IPixelFormat.Type.YUV420P);
        coder.setHeight(size.height);
        coder.setWidth(size.width);

        System.out.println("[ENCODER] video size is " + size.width + "x" + size.height);
        coder.setFlag(IStreamCoder.Flags.FLAG_QSCALE, true);
        coder.setGlobalQuality(0);
        IRational frameRate = IRational.make(24, 1);
        coder.setFrameRate(frameRate);
        coder.setTimeBase(IRational.make(frameRate.getDenominator(), frameRate.getNumerator()));

        coder.open();
        container.writeHeader();
        long firstTimeStamp = System.currentTimeMillis();
        long lastTimeStamp = -1;
        int i = 0;
        try {
         //   Robot robot = new Robot();
            Webcam webcam = Webcam.getDefault();
            webcam.setViewSize(size);
            webcam.open();

            while (i < 100000000) {
                //long iterationStartTime = System.currentTimeMillis();
                long now = System.currentTimeMillis();
                //grab the screenshot
                BufferedImage image = webcam.getImage();
                //convert it for Xuggler
                BufferedImage currentScreenshot = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
                currentScreenshot.getGraphics().drawImage(image, 0, 0, null);
                //start the encoding process
                IPacket packet = IPacket.make();
                IConverter converter = ConverterFactory.createConverter(currentScreenshot, IPixelFormat.Type.YUV420P);
                long timeStamp = (now - firstTimeStamp) * 1000; 
                IVideoPicture outFrame = converter.toPicture(currentScreenshot, timeStamp);
                if (i == 0) {
                    //make first frame keyframe
                    outFrame.setKeyFrame(true);
                }
                outFrame.setQuality(0);
                coder.encodeVideo(packet, outFrame, 0);
                outFrame.delete();
                if (packet.isComplete()) {
                    container.writePacket(packet);
                    System.out.println("[ENCODER] writing packet of size " + packet.getSize() + " for elapsed time " + ((timeStamp - lastTimeStamp) / 1000));
                    lastTimeStamp = timeStamp;
                }
                System.out.println("[ENCODER] encoded image " + i + " in " + (System.currentTimeMillis() - now));
                i++;
                try {
                    Thread.sleep(Math.max((long) (1000 / frameRate.getDouble()) - (System.currentTimeMillis() - now), 0));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

On running, getting this message:

23:13:38,807 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
23:13:38,808 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
23:13:38,811 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Setting up default configuration.
23:13:38,878 |-WARN in ch.qos.logback.core.ConsoleAppender[console] - This appender no longer admits a layout as a sub-component, set an encoder instead.
23:13:38,878 |-WARN in ch.qos.logback.core.ConsoleAppender[console] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
23:13:38,878 |-WARN in ch.qos.logback.core.ConsoleAppender[console] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details

23:13:46.644 [main] ERROR org.ffmpeg - RTMP_ReadPacket, failed to read RTMP packet header
Could not open output container for live stream
23:13:46.650 [main] ERROR com.xuggle.xuggler - URL: rtmp://a.rtmp.youtube.com/live2; Error: could not open file (../../../../../../../csrc/com/xuggle/xuggler/Container.cpp:516)

I don't understand what's going wrong. Why my webcam won't start?


回答1:


Read manifest file (MANIFEST.MF) of xuggler library 5.2 jar for correct version of dependency jars, collect correct version jars and add them in the class path to resolve the dependency and version issues.



来源:https://stackoverflow.com/questions/30489734/could-not-open-output-container-for-live-stream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!