Could not open output container for live stream
Asked Answered
I

1

0

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?

Iceboat answered 27/5, 2015 at 17:52 Comment(1)
Where are you using your YouTube key?Perch
F
0

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.

Flounder answered 29/5, 2015 at 12:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.