Use Java to convert any media type to FLV with Xuggler

I had the following issue: I wanted to convert any media files the users might upload to my web app to FLV, in order to play them inside my flash player.

JMF (Java Media Framework) doesn’t support conversion to FLV. After some minutes, i found Xuggler.

After following the documentation, i wrote a conversor, that didn’t work.

My first error message was:

ERROR org.ffmpeg – [libmp3lame @ 0x4334a70] flv does not support that sample rate, choose from (44100, 22050, 11025).

I don’t understand why they don’t do this automatically in their framework, but fact was I had to make an audio-resampler.

I started by writing a conversor that extends MediaToolAdapter

// VideoConverter.java
private IAudioResampler audioResampler = null;
@Override
public void onAudioSamples(IAudioSamplesEvent event) {
  IAudioSamples samples = event.getAudioSamples();
  if (audioResampler == null) {
    audioResampler = IAudioResampler.make(2, samples.getChannels(), 44100, samples.getSampleRate());
  }
  if (event.getAudioSamples().getNumSamples() > 0) {
    IAudioSamples out = IAudioSamples.make(samples.getNumSamples(), samples.getChannels());
    audioResampler.resample(out, samples, samples.getNumSamples());

    AudioSamplesEvent asc = new AudioSamplesEvent(event.getSource(), out, event.getStreamIndex());
    super.onAudioSamples(asc);
    out.delete();
  }
}
@Override
public void onAddStream(IAddStreamEvent event) {
  int streamIndex = event.getStreamIndex();
  IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
  if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
    streamCoder.setSampleRate(44100);
  }
  super.onAddStream(event);
}

(I got this from here)

But still it didn’t work, as i kept getting the following error:

Exception in thread “main” java.lang.RuntimeException: failed to encode audio
at com.xuggle.mediatool.MediaWriter.encodeAudio(MediaWriter.java:862)
at com.xuggle.mediatool.MediaWriter.onAudioSamples(MediaWriter.java:1448)

My last clue was to convert the video was well, resulting in the following conversor:

private IVideoResampler videoResampler = null;
private IAudioResampler audioResampler = null;

@Override
public void onAddStream(IAddStreamEvent event) {
  int streamIndex = event.getStreamIndex();
  IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
  if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
    streamCoder.setSampleRate(44100);
  } else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
    streamCoder.setWidth(VIDEO_WIDTH);
    streamCoder.setHeight(VIDEO_HEIGHT);
  }
  super.onAddStream(event);
}

@Override
public void onVideoPicture(IVideoPictureEvent event) {
  IVideoPicture pic = event.getPicture();
  if (videoResampler == null) {
    videoResampler = IVideoResampler.make(VIDEO_WIDTH, VIDEO_HEIGHT, pic.getPixelType(), pic.getWidth(), pic.getHeight(), pic.getPixelType());
  }
  IVideoPicture out = IVideoPicture.make(pic.getPixelType(), VIDEO_WIDTH, VIDEO_HEIGHT);
  videoResampler.resample(out, pic);

  IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
  super.onVideoPicture(asc);
  out.delete();
}

@Override
public void onAudioSamples(IAudioSamplesEvent event) {
  IAudioSamples samples = event.getAudioSamples();
  if (audioResampler == null) {
    audioResampler = IAudioResampler.make(2, samples.getChannels(), 44100, samples.getSampleRate());
  }
  if (event.getAudioSamples().getNumSamples() > 0) {
  IAudioSamples out = IAudioSamples.make(samples.getNumSamples(), samples.getChannels());
  audioResampler.resample(out, samples, samples.getNumSamples());

  AudioSamplesEvent asc = new AudioSamplesEvent(event.getSource(), out, event.getStreamIndex());
  super.onAudioSamples(asc);
  out.delete();
  }
}

After writing this conversor, the only thing left to do was to configure the listeners:

IMediaReader reader = ToolFactory.makeReader(inputFile.getAbsolutePath());
reader.addListener(conversor);

IMediaWriter writer = ToolFactory.makeWriter(outputFile.getAbsolutePath(), reader);
writer.addAudioStream(1, 0, 2, 44100);
writer.addVideoStream(0, 0, VIDEO_WIDTH, VIDEO_HEIGHT);
conversor.addListener(writer);
while (running && reader.readPacket() == null) {

//do nothing


}
<pre>

I tested this code using as input flv, mp4, avi, mov and wmv, and they all worked fine. I hope this code will help you as it helped me. If you have any questions or suggestions, please, don’t hesitate in getting in touch with me.

30 thoughts on “Use Java to convert any media type to FLV with Xuggler

  1. hi,
    thank you for the code.
    But when I used it to convert .avi to .flv that giving me a runtime exception like the bellow,

    java.lang.RuntimeException: failed to encode video
    at com.xuggle.mediatool.MediaWriter.encodeVideo(MediaWriter.java:771)
    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.MediaToolAdapter.onVideoPicture(MediaToolAdapter.java:169)
    at video.Resizer.onVideoPicture(Resizer.java:37)
    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 video.videoconvert.convertAVI(videoconvert.java:178)
    at video.videoconvert.main(videoconvert.java:18)

    anybody have any clue?

      • Hello gmussi i m facing the same issue… it keeps giving me the error “cannot encode video”

        I hv tried to convert .avi, .mpg as input files and ..flv as output file…

        Pls help 🙂

      • hai sir
        will you know anything about how to divide the whole video into some 10 second pulses?
        if you know can you send me the source code to my email:sravanthi422@gmail.com

    • hi.
      I have the same problem. Is there any solution?
      P.S. Thanks to author for this article.

  2. hey , thankyou for the great tutorial, just one question.. this code is for converting files to flv, what changes wud have to be made to convert files to 3gp format?? or will this code work??

    • Hi Khizar, in one word: no.
      In theory Xuggler should convert any format without any effort from the programmer’s side. Unfortunately sometimes adjustments are needed so that it can convert properly.
      The code above handles specific situations regarding the FLV format, where the framewprk is not always able to guess the correct parameters.

  3. thanx alot for the reply. i am working on a deadline, so i tinkered a bit with your code and got it to work, well sort of work. it now encodes the new 3gp file but there is no video. the sound is fine. there is no exception. no error. just that the new file does not have any video. I am putting in the convertor’s overridden methods, please if u have some time , take a look and see if there is something that i am doing wrong.

    @Override
    public void onAddStream(IAddStreamEvent event)
    {
    if (writer == null)
    {
    writer = ToolFactory.makeWriter(outputFile.getAbsolutePath(), reader);

    }

    int streamIndex = event.getStreamIndex();
    IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();

    if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO)
    {
    streamCoder.setFlag(IStreamCoder.Flags.FLAG_QSCALE, false);

    streamCoder.setCodec(ICodec.findEncodingCodecByName(“aac”));
    writer.addAudioStream(streamIndex, streamIndex, 1, 8000);

    }
    else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO)
    {
    streamCoder.setFlag(IStreamCoder.Flags.FLAG_QSCALE, false);

    streamCoder.setCodec(ICodec.findEncodingCodecByName(“h264”));
    writer.addVideoStream(streamIndex, streamIndex, VIDEO_WIDTH, VIDEO_HEIGHT);

    }
    super.onAddStream(event);
    }

    // //
    @Override
    public void onVideoPicture(IVideoPictureEvent event)
    {
    IVideoPicture pic = event.getPicture();
    if (videoResampler == null)
    {
    videoResampler = IVideoResampler.make(VIDEO_WIDTH, VIDEO_HEIGHT, pic.getPixelType(), pic.getWidth(), pic.getHeight(), pic.getPixelType());
    }
    IVideoPicture out = IVideoPicture.make(pic.getPixelType(), VIDEO_WIDTH, VIDEO_HEIGHT);
    videoResampler.resample(out, pic);

    IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
    super.onVideoPicture(asc);
    out.delete();
    }

    @Override
    public void onAudioSamples(IAudioSamplesEvent event)
    {
    IAudioSamples samples = event.getAudioSamples();
    if (audioResampler == null)
    {
    audioResampler = IAudioResampler.make(1, samples.getChannels(), 8000, samples.getSampleRate());
    }
    if (event.getAudioSamples().getNumSamples() > 0)
    {
    IAudioSamples out = IAudioSamples.make(samples.getNumSamples(), samples.getChannels());
    audioResampler.resample(out, samples, samples.getNumSamples());

    AudioSamplesEvent asc = new AudioSamplesEvent(event.getSource(), out, event.getStreamIndex());
    super.onAudioSamples(asc);
    out.delete();
    }
    }

  4. ive found out that i only need the onAddStream method for my program to work, i.e i commented out the other two methods and it still encodes the audio but not the video. no success with the video, the problem is i donot have any errors to play with , the program runs and completes successfully but the target file does not have any video 😦 ive been hitting my head to a wall all day ;(

    • Please check that the video channel is correct on the new file. The best way to find problems is to get a video in the format you want working, and then start comparing what is different in the 2 files (the one working, and the one generated by xuggler). Players like MediaPlayerClassic can help you debug the videos. Check every single thing that is different and try adjusting this code to fit your needs. I wish you good luck on this journey.

  5. i checked the new video , and it seems that there is something wrong with the video encoding, the dimension is shown as 0 x 0. now my code looks the same as yours except that in the onAddStream method i was getting a null pointer exception on the writer so i put a null check there.

    if (writer == null)
    {
    writer = ToolFactory.makeWriter(outputFile.getAbsolutePath(), reader);

    }

    did that happen to u or am i doing something wrong.

  6. Hi Gmussi,

    I am trying to encode the .mxf format to avi but it is not working.
    I get this error –

    2011-09-28 14:17:39,411 [main] ERROR org.ffmpeg – [mxf @ 0x2cc840] material track 2: no corresponding source track found
    2011-09-28 14:17:39,437 [main] ERROR org.ffmpeg – [mxf @ 0x2cc840] material track 3: no corresponding source package found
    2011-09-28 14:17:39,437 [main] ERROR org.ffmpeg – [mxf @ 0x2cc840] material track 4: no corresponding source package found
    2011-09-28 14:17:39,438 [main] ERROR org.ffmpeg – [mxf @ 0x2cc840] material track 5: no corresponding source package found
    2011-09-28 14:17:39,850 [main] WARN com.xuggle.xuggler – Got error: picture is not of the same PixelType as this Coder expected (../../../../../../../csrc/com/xuggle/xuggler/StreamCoder.cpp:1204)

    If you could guide me the right direction then that will be very helpful.

    • Hello.

      I would get from the video the correct PixelType first. You can use xuggler or some video analizers for that. After you know which one you have and which one you need, you can set it manually in your conversor. Regards.

  7. Thanks for replying.

    I have just started with Xuggler and Java as well hence excuse me for asking stupid questions.

    I am able to do the transcoding using ffmpeg with this command –
    ffmpeg -f dv -i “C:\temp001NY.MXF” -ar 44100 -vcodec libx264 -maxrate 2000k -bufsize 2000k -vf scale=”iw/2:ih/2″ -strict experimental -vstats_file “C:\temp\progress.txt” “C:\temp001NYoutput-short1.mov”

    How can I replicate the same with Xuggler?

    Thanks

  8. How to convert .avi file into .flv.? Because iam getting some error.

    2011-10-03 11:42:41,889 [main] ERROR org.ffmpeg – swScaler: pal8 is not supporte
    d as output pixel format
    2011-10-03 11:42:41,904 [main] DEBUG com.xuggle.xuggler – error: could not alloc
    ate a image rescaler (../../../../../../../csrc/com/xuggle/xuggler/VideoResample
    r.cpp:236)
    Exception in thread “main” java.lang.UnsupportedOperationException: Converter cl
    ass com.xuggle.xuggler.video.BgrConverter constructor failed with: java.lang.Run
    timeException: 2 Could not create could resampler to translate from BGR24 to PAL
    8
    at com.xuggle.xuggler.video.ConverterFactory.createConverter(ConverterFa
    ctory.java:347)
    at com.xuggle.xuggler.video.ConverterFactory.createConverter(ConverterFa
    ctory.java:275)
    at com.xuggle.mediatool.MediaViewer.onAddStream(MediaViewer.java:410)
    at com.xuggle.mediatool.AMediaToolMixin.onAddStream(AMediaToolMixin.java
    :78)
    at com.xuggle.mediatool.MediaReader.getStreamCoder(MediaReader.java:375)

    at com.xuggle.mediatool.MediaReader.readPacket(MediaReader.java:461)
    at VideoConverter.main(VideoConverter.java:55)
    Done.

  9. please give me immediate reply for bcoz of i have to submit my project. so plz understand my problem and give reply soon

  10. Sometimes it鈥檚 the old, clapped-out, rusty tractors that are the most reliable for grunt work on the farm.They often need less oil, less servicing and get a toot from passers-by.Dowerin farmer Andrew Todd shared some photos with the WA Country Hour team of his particularly ancient looking front end loader, which has encouraged a stream [url=http://problemenmetspelling.nl/Scripts/ugg-sneakers-for-cheap-502.php]Ugg Sneakers For Cheap[/url] of photos from farmers all over the state.”The clapped-out field bin trailer is a wheatbelt institution”, said one contributor Josiah O鈥橦are.Mr Todd agrees, he says old tractors are [url=http://problemenmetspelling.nl/Scripts/ugg-womens-jacket-444.php]Ugg Womens Jacket[/url] great for dragging grain field bins during harvest.”There鈥檚 probably one or two on every farm.”It鈥檚 a big time of year, they only get rolled out four to six weeks a year and they鈥檙e all out and about now.””There are a few that turn heads as you drive past paddocks and probably a lot [url=http://problemenmetspelling.nl/Scripts/ugg-shoes-wiki-243.php]Ugg Shoes Wiki[/url] of them have been around for longer than I鈥檝e been on the planet.”They鈥檝e all earned their keep on the farm and they鈥檙e in retirement now, sitting on field bins.”The WA Country Hour is hosting a competition, asking listeners to send in photos of their old field bin tractors.You can view the collection of tractor photos on the WA Country Hour facebook page.The photo with the most ‘likes’ will win an ABC prize pack, to be [url=http://problemenmetspelling.nl/Scripts/ugg-womens-georgette-518.php]Ugg Womens Georgette[/url] announced on Monday 2nd November 2013. grain, crop-harvesting, agricultural-machinery, dowerin-6461 November 25, 2013 17:04:03 Contact Olivia Garnett Walk over weighing [url=http://problemenmetspelling.nl/Scripts/ugg-women-greenfield-530.php]Ugg Women Greenfield[/url] A project using remote technology is trying to tackle labour costs in northern Australia. Inglewood Farms sold Cassie Hough Australia’s largest organic poultry farm has been sold to a Qld agribusiness group. Mine viability questioned A plan to develop one of the world’s biggest coalmines is ‘uncommercial’, Greenpeace says. [url=http://problemenmetspelling.nl/Scripts/ugg-sale-knightsbridge-992.php]Ugg Sale Knightsbridge[/url] Merino breeding star The way Tasmanian superfine wool grower Nan Bray runs her Saxon merinos seems radical.

    [url=http://wilson.e4.163ns.cn/forum.php?mod=viewthread&tid=157040&fromuid=19725]Ugg Damen Bel Cloud[/url]
    [url=http://bbs.autowj.com/bbs/home.php?mod=space&uid=83281]Ugg Boots Billig Deutschland[/url]

  11. Hi Gmussi,
    Plz help, i wants to convert any video file (mp4,3gp,wmv,avi,flv) to other formats (mp4,3gp,wmv,avi,flv) vice-versa, how should i implement this code. I tried below code,
    public class videoconverter {

    public boolean convert(String input, String output){
    IMediaReader reader = ToolFactory.makeReader(input);
    reader.addListener(ToolFactory.makeWriter(output, reader));
    while (reader.readPacket() == null){}

    return true;
    }
    }

Leave a comment