This must be a very stupid question, but how does one recode with Xuggler? Simplified I have:
IMediaReader reader = ToolFactory.makeReader(sourceUrl);
IMediaWriter writer = ToolFactory.makeWriter(url, reader);
MediaSegmenterWriter writerListener = new MediaSegmenterWriter();
writer.open();
while (reader.readPacket() == null)
do {
}
while(false);
Now, I want to recode the file in the reader to another bitrate and resolution. How do I do that? On creating the writer I have tried to add IMediaStreams with a copy of the original coder with the necessary changes, but that does not work:
int numStreams = reader.getContainer().getNumStreams();
for(int i = 0; i < numStreams; i++)
{
final IStream stream = reader.getContainer().getStream(i);
final IStreamCoder coder = stream.getStreamCoder();
IStreamCoder newCoder = IStreamCoder.make(IStreamCoder.Direction.ENCODING, coder);
if(newCoder == null ){
continue;
}
writer.getContainer().addNewStream(i);
int streams = writer.getContainer().getNumStreams();
System.out.println("Current amount of streams in writer: " + streams);
System.out.println("Coder: " + coder.toString());
if (coderSetting != null && newCoder != null){
if (newCoder.getCodecType().equals(ICodec.Type.CODEC_TYPE_VIDEO)) {
newCoder.setWidth(320);
newCoder.setHeight(240);
}
IStream outputStream = writer.getContainer().getStream(i);
outputStream.setStreamCoder(newCoder);
newCoder.open();
}
}
But this just gives the same result as leaving the code out (e.g. 1920x1080 from original)
Also tried to add a listener to the writer and replace the coder, but either got an error (coder already opened_ or no effect. (on onOpen, onAddStream, onOpenCoder))
I looked for tutorials, but non seem to do this simple operation.
Any help would be REALLY appreciated!!!
In order to resize the content as well as recode you need to create a MediaToolAdapter like:
private static class MediaResizer extends MediaToolAdapter {
private IVideoResampler videoResampler = null;
private int mediaHeight;
private int mediaWidth;
public MediaResizer (int aHight, int aWidth) {
mediaWidth = aWidth;
mediaHeight = aHeight;
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
// In case of audio only, do not re-size as it is not needed
if(job.role == MediaRole.MediaRoleEnum.LS_AUDIO) super.onVideoPicture(event);
IVideoPicture pic = event.getPicture();
if (videoResampler == null) {
videoResampler = IVideoResampler.make(job.getCoderSettings().width, job.getCoderSettings().height, pic.getPixelType(), pic.getWidth(), pic.getHeight(), pic.getPixelType());
}
IVideoPicture out = IVideoPicture.make(pic.getPixelType(), mediaWidth, mediaHeight);
videoResampler.resample(out, pic);
IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
super.onVideoPicture(asc);
out.delete();
}
}
You add this as a listener to your reader, and then your writer to you resized. It should be something like:
IMediaReader reader = ToolFactory.makeReader(sourceUrl);
MediaResizer resizer = new MediaResizer(job);
IMediaWriter currentWriter = ToolFactory.makeWriter(destinationDir, reader);
reader.addListener(resizer);
resizer.addListener(currentWriter);