Tuesday, February 1, 2011

Xuggler: Using MediaTool API

I see the tutorial. And going to test MediaTool API for transcoding. I follow the section "How To Transcode Media From One Format To Another".

IMediaReader reader = ToolFactory.makeReader(baseURL+this.streamName);
IMediaWriter writer = ToolFactory.makeWriter(baseURL+this.transcodedStreamName, reader);
reader.addListener(writer);
while (reader.readPacket() == null){
    do {} while(false);
}

Greate very simple. Let's run....

11:41:29.983 [Thread-70] ERROR com.xuggle.xuggler - Could not find output format (../../../../../../../csrc/com/xuggle/xuggler/Container.cpp:338)
Exception in thread "Thread-70" java.lang.IllegalArgumentException: could not open: rtmp://127.0.0.1/live/myStream
        at com.xuggle.mediatool.MediaWriter.open(MediaWriter.java:1289)
        at com.xuggle.mediatool.MediaWriter.getStream(MediaWriter.java:998)
        at com.xuggle.mediatool.MediaWriter.encodeVideo(MediaWriter.java:749)
        at com.xuggle.mediatool.MediaWriter.encodeVideo(MediaWriter.java:790)
        at com.xuggle.mediatool.MediaWriter.onVideoPicture(MediaWriter.java:1441)
        at com.xuggle.mediatool.AMediaToolMixin.onVideoPicture(AMediaToolMixin.java:166)
        at com.xuggle.mediatool.MediaReader.dispatchVideoPicture(MediaReader.java:610)
        at com.xuggle.mediatool.MediaReader.decodeVideo(MediaReader.java:519)
        at com.xuggle.mediatool.MediaReader.readPacket(MediaReader.java:475)
        at com.mycompany.xuggler.H264TranscoderThread.testRTMPPublishH264(H264TranscoderThread.java:68)
        at com.mycompany.xuggler.H264TranscoderThread.run(H264TranscoderThread.java:77)

Hm... It fails.... O.K. look into the source code.
public void open()
{
    // open the container

    if (getContainer().open(getUrl(), IContainer.Type.WRITE, mContainerFormat,
          true, false) < 0)
        throw new IllegalArgumentException("could not open: " + getUrl());

    // inform listeners

    super.onOpen(new OpenEvent(this));
    
    // note that we should close the container opened here

    setShouldCloseContainer(true);
}
Guess from the messages, look into the mContainerFormat more deeper..
MediaWriter(String url, IContainer inputContainer)
{
    super(url, IContainer.make());

    // verify that the input container is a readable type

    if (inputContainer.getType() != IContainer.Type.READ)
        throw new IllegalArgumentException(
        "inputContainer is improperly must be of type readable.");

    // verify that no streams will be added dynamically

    if (inputContainer.canStreamsBeAddedDynamically())
        throw new IllegalArgumentException(
            "inputContainer is improperly configured to allow " + 
            "dynamic adding of streams.");

    // record the input container and url

    mInputContainer = inputContainer;

    // create format 

    mContainerFormat = IContainerFormat.make();
    mContainerFormat.setOutputFormat(mInputContainer.getContainerFormat().
        getInputFormatShortName(), getUrl(), null);
}
Hm, it getting from the reader..... Then maybe....., change the code.
IMediaReader reader = ToolFactory.makeReader(baseURL+this.streamName);
reader.open();
IMediaWriter writer = ToolFactory.makeWriter(baseURL+this.transcodedStreamName, reader);
reader.addListener(writer);
while (reader.readPacket() == null){
    do {} while(false);
}
Yes it works.

3 comments:

  1. Hello,

    Thanks for sharing this. I see that in this example you were encoding stream to H264.

    com.mycompany.xuggler.H264TranscoderThread.testRTMPPublishH264

    my question is where do you put the arguments? I mean the --acodec, --vcodec, --vpreset, etc

    Did you have success with the transcoding?

    Thanks!

    ReplyDelete
  2. Above code just decode and encode with the same codec. See the following post. I think it will give you some idea on that. http://tikiroomtiki.blogspot.com/2011/08/transcoding-video-to-h264-using-xuggler.html

    ReplyDelete
  3. Hi! Thanks for sharing this.
    I have exactly the same problem but still cannot fix it. You just add reader.open();, right? I tried it but it does not work. Could you please provide more comments on this.

    ReplyDelete