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); } }
Comments
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....!!!
your code is working fine, but when convert iPhone video then orientation is changed automatically, how can i get same orientation of video?
please help me.
Hi Rahul,
I'm sorry, but I don't have experience with rotating iPhone movies.
Kind regards,
Jochen
The article which you provided is very helpful for me. Is is possible to grasp the voice(audio) from a video lecture file and write the voice(professor's lecture) as text words in word document by using xuggler.
Hi mujafar,
I think it's possible to extract the audio from the video with Xuggler, but the translation of audio to text words will be difficult :-). I don't think Xuggler has a feature like that. You will need other software to do that.
Kind regards,
Jochen
Hello Sir Your Article is good and converting well also...
I need to add video codec in video
I tried to add in MyVideoListener
streamCoder.setCodecID(ICodec.ID.CODEC_ID_MPEG4);
But it doesn't work....would you please provide the solution....
Hi Suren,
Thank you for your message. Unfortunately, I don't know how to implement your feature request. Maybe try getting support by this link: http://www.xuggle.com/xuggler/support
Kind regards,
Jochen
How can merge multiple video in single video file.???? Using java only.
Hi Nandkishor,
I'm sorry to inform you I do not have experience with the question you are asking.
Kind regards,
Jochen
Hi,
When I run this code I got those errors, and all videos last 3 sc.
23:36:53.160 [Thread-4] ERROR org.ffmpeg - [h264 @ 0x7ff558a4ca00] AVC: nal size 406
23:36:53.166 [Thread-4] ERROR org.ffmpeg - [h264 @ 0x7ff558a4ca00] AVC: nal size 406
23:36:53.166 [Thread-4] ERROR org.ffmpeg - [h264 @ 0x7ff558a4ca00] no frame!
23:36:53.162 [Thread-2] ERROR org.ffmpeg - [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7ff55a014000] stream 0, offset 0x80c1: partial file
What may be the problem?
I have no idea ... sorry :-(
That was because a video with the same name existing.
Instead of replacing video, renaming with a new name solved the problem.
Many thanks...
How to implement above code without using video preview windows(java swing windows which were opening)?
Add new comment