Submitted by Jochus on 13 Oct 2010 - 00:10 (last updated on: 13 Oct 2010 - 09:12)
Posted in
Last week, I had to investigate a case where we want to resize a video to a whole set of resized video's. So you have a source video with resolution: 1280x800 and I want a video for 640x400, 320x200, 160x100, ... etc, etc, ...
Of course, we need Java for this ;-) ! I came across this library http://www.xuggle.com/xuggler/. Xuggler is the easy way to uncompress, modify, and re-compress any media file (or stream) from Java.
Well, they say it is "easy", but for me it wasn't. This is my (finally!) working example.
Prerequisites
- install Xuggler
- set the following ENV vars
export XUGGLE_HOME="/usr/local/xuggler" export PATH=$PATH:$XUGGLE_HOME/bin export LD_LIBRARY_PATH="/usr/local/xuggler/lib"
Resizing a video
MediaConvertor
public class MediaConvertor { private static final Integer WIDTH = 640; private static final Integer HEIGHT = 360; private static final String INPUT_FILE = "/tmp/input.mp4"; private static final String OUTPUT_FILE = "/tmp/output.mpg"; public static void main(String[] args) { // create custom listeners MyVideoListener myVideoListener = new MyVideoListener(WIDTH, HEIGHT); Resizer resizer = new Resizer(WIDTH, HEIGHT); // reader IMediaReader reader = ToolFactory.makeReader(INPUT_FILE); reader.addListener(resizer); // writer IMediaWriter writer = ToolFactory.makeWriter(OUTPUT_FILE, reader); resizer.addListener(writer); writer.addListener(myVideoListener); // show video when encoding reader.addListener(ToolFactory.makeViewer(true)); while (reader.readPacket() == null) { // continue coding } } }
Resizer
import com.xuggle.mediatool.MediaToolAdapter; import com.xuggle.mediatool.event.IVideoPictureEvent; import com.xuggle.mediatool.event.VideoPictureEvent; import com.xuggle.xuggler.IVideoPicture; import com.xuggle.xuggler.IVideoResampler; public class Resizer extends MediaToolAdapter { private Integer width; private Integer height; private IVideoResampler videoResampler = null; public Resizer(Integer aWidth, Integer aHeight) { this.width = aWidth; this.height = aHeight; } @Override public void onVideoPicture(IVideoPictureEvent event) { IVideoPicture pic = event.getPicture(); if (videoResampler == null) { videoResampler = IVideoResampler.make(width, height, pic.getPixelType(), pic.getWidth(), pic .getHeight(), pic.getPixelType()); } IVideoPicture out = IVideoPicture.make(pic.getPixelType(), width, height); videoResampler.resample(out, pic); IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex()); super.onVideoPicture(asc); out.delete(); } }
MyVideoListener
import com.xuggle.mediatool.MediaToolAdapter; import com.xuggle.mediatool.event.IAddStreamEvent; import com.xuggle.xuggler.ICodec; import com.xuggle.xuggler.IStreamCoder; public class MyVideoListener extends MediaToolAdapter { private Integer width; private Integer height; public MyVideoListener(Integer aWidth, Integer aHeight) { this.width = aWidth; this.height = aHeight; } @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) { } else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) { streamCoder.setWidth(width); streamCoder.setHeight(height); } super.onAddStream(event); } }
Hello,
This is really a very good article. Thanks a lot..
Could u pls provide me the help for compressing vdo or changing bitrates of vdo. What i want to do is to reduce the vdo file size.
Bcoz with dis code i can convert vdo but it size increases after conversion.
Thanks.
hi,
I want to convert .flv to .mpg but the above code did not work for that and result,
Exception in thread "main" java.lang.IllegalArgumentException: could not find input codec id
so I thought it was the width and height and I changed it into 1208*800 but it did not solved the problem.
is anybody have a clue?
thank you.
Hi,
If I resize a video to another of the same properties, the size is increased (double or even more size).
What may be the problem?
Thanks,
Luis
hey
i was working on a deadline and had no idea what xuggler was. After three days of trial and error , and googling i cud only get the audio to work n just as i was about to give up , i came upon ur post. man u wudnt believe how happy i am, after 10 mins of small project specific tweaks to ur code, my project started working and i am sooooo happy :) . thanx alot man.
hey
i was working on a deadline and had no idea what xuggler was. After three days of trial and error , and googling i cud only get the audio to work n just as i was about to give up , i came upon ur post. man u wudnt believe how happy i am, after 10 mins of small project specific tweaks to ur code, my project started working and i am sooooo happy :) . thanx alot man.
I ran your code and got the following errors....
Exception in thread "main" 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 com.Pixel.Resizer.onVideoPicture(Resizer.java:32)
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.Pixel.PixelMain.main(PixelMain.java:34)
the problem is at this point : super.onAddStream(event);
Pls help....!!!
Post new comment