Added frame grabber

This commit is contained in:
Ziver Koc 2012-10-31 19:34:46 +00:00
parent b6adc5c402
commit 06861e1658
2 changed files with 171 additions and 104 deletions

View file

@ -1,12 +1,14 @@
package zall;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
@ -25,6 +27,8 @@ import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.IVideoResampler;
import com.xuggle.xuggler.video.ConverterFactory;
import com.xuggle.xuggler.video.IConverter;
import zall.bean.Media.Size;
import zall.bean.Video;
@ -127,7 +131,7 @@ public class ZalleryTranscoder extends HttpServlet{
///////////// Start Transcoding
// create a media reader
IMediaReader reader = ToolFactory.makeReader( originalFile.getPath() );
reader.addListener(new FrameGrabListener(reader, 0.2));
reader.addListener(new FrameGrabListener(reader, smallFile, 0.2));
reader.addListener(new ProgressListener(reader));
VideoTranscoderListener converter = new VideoTranscoderListener(640, 360);
@ -221,28 +225,22 @@ class VideoTranscoderListener extends MediaToolAdapter{
private IVideoResampler videoResampler = null;
private IAudioResampler audioResampler = null;
IMediaWriter writer;
@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) {
//writer.addAudioStream(streamIndex, streamIndex, ICodec.ID.CODEC_ID_AAC, 2, 44100);
streamCoder.setSampleRate( 44100 );
/*
streamCoder.setCodec( ICodec.ID.CODEC_ID_AAC );
streamCoder.setBitRate( 128 );
*/
//streamCoder.setCodec( ICodec.ID.CODEC_ID_AAC );
//streamCoder.setBitRate( 128 );
}
else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
//writer.addVideoStream(streamIndex, streamIndex, ICodec.ID.CODEC_ID_H264, VIDEO_WIDTH, VIDEO_HEIGHT);
streamCoder.setWidth( width );
streamCoder.setHeight( height );
/*
streamCoder.setCodec(ICodec.findEncodingCodec( ICodec.ID.CODEC_ID_H264 ));
streamCoder.setBitRate( 500000 );
//streamCoder.setCodec(ICodec.findEncodingCodec( ICodec.ID.CODEC_ID_H264 ));
//streamCoder.setBitRate( 800000 );
/*
int retval = Configuration.configure("/usr/local/xuggler/share/ffmpeg/libx264-superfast.ffpreset", streamCoder);
if (retval<0)
throw new RuntimeException("cound not cofigure coder from preset file");
@ -323,21 +321,38 @@ class ProgressListener extends MediaToolAdapter {
class FrameGrabListener extends MediaToolAdapter {
private long totalLength;
private long grabAt;
private File outputFile;
public FrameGrabListener(IMediaReader reader, double at) {
public FrameGrabListener(IMediaReader reader, File outputFile, double at) {
if( !reader.isOpen() )
reader.open(); // read container
this.totalLength = reader.getContainer().getDuration();
this.outputFile = outputFile;
setAtProgress(at);
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
long currentLength = event.getTimeStamp();
if( grabAt > 0 && currentLength > grabAt ){
System.out.println("\nScreanshoot!!!");
grabAt = -1;
try{
long currentLength = event.getTimeStamp();
if( grabAt > 0 && currentLength > grabAt ){
System.out.println("\nScreanshoot!!!");
ConverterFactory.Type mConverterType = ConverterFactory.findRegisteredConverter(
ConverterFactory.XUGGLER_BGR_24);
IConverter mVideoConverter = ConverterFactory.createConverter(
mConverterType.getDescriptor(),
event.getPicture());
ImageIO.write(
mVideoConverter.toImage(event.getPicture()),
"png",
outputFile);
grabAt = -1;
}
}catch(IOException e){
e.printStackTrace();
}
}
@ -346,3 +361,4 @@ class FrameGrabListener extends MediaToolAdapter {
}
}

View file

@ -1,47 +1,62 @@
/*
javac -cp xuggle-xuggler-5.4.jar Transcoder.java
java -cp xuggle-xuggler-5.4.jar:./:slf4j-api-1.6.4.jar Transcoder
http://whaticode.com/2010/04/30/use-java-to-convert-any-media-type-to-flv-with-xuggler-part-2/
*/
package zall.util.test;
import java.io.File;
import javax.imageio.ImageIO;
import java.io.IOException;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IAddStreamEvent;
import com.xuggle.mediatool.event.AudioSamplesEvent;
import com.xuggle.mediatool.event.IAudioSamplesEvent;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.mediatool.event.VideoPictureEvent;
import com.xuggle.xuggler.Configuration;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.IVideoResampler;
import com.xuggle.xuggler.IAudioSamples;
import com.xuggle.xuggler.IAudioResampler;
import com.xuggle.xuggler.video.IConverter;
import com.xuggle.xuggler.video.ConverterFactory;
public class Transcoder {
public static void main(String[] args){
File originalFile = new File( "C:\\Users\\Ziver\\Desktop\\Downloads\\test2.mp4" );
File mediumFile = new File( "C:\\Users\\Ziver\\Desktop\\Downloads\\temp\\test2_medium.mp4" );
File smallFile = new File( "C:\\Users\\Ziver\\Desktop\\Downloads\\temp\\test2_small.png" );
File originalFile = new File( "test2.mp4" );
File mediumFile = new File( "test2_medium.mp4" );
File smallFile = new File( "test2_small.png" );
//ConvertVideo tmp = new ConvertVideo(originalFile, mediumFile);
//tmp.run();
//return;
///////////// Start Transcoding
// create a media reader
IMediaReader reader = ToolFactory.makeReader( originalFile.getPath() );
reader.open();
reader.addListener(new FrameGrabListener(reader, smallFile, 0.2));
reader.addListener(new ProgressListener(reader));
VideoTranscoderListener converter = new VideoTranscoderListener(480, 270);
reader.addListener(converter);
// create a media writer
IMediaWriter mediaWriter = ToolFactory.makeWriter(mediumFile.getPath(), reader);
// add a writer to the reader, to create the output file
reader.addListener(mediaWriter);
mediaWriter.addListener(new Resizer(450, 295));
mediaWriter.addListener(new CodecChanger());
mediaWriter.addListener(new ProgressListener(reader.getContainer()));
IMediaWriter writer = ToolFactory.makeWriter(mediumFile.getPath(), reader);
converter.addListener(writer);
// create a media viewer with stats enabled for debugging
//IMediaViewer mediaViewer = ToolFactory.makeViewer(true);
// add a viewer to the reader, to see the decoded media
//IMediaViewer mediaViewer = ToolFactory.makeViewer(true);
//reader.addListener(mediaViewer);
//writer.addListener(mediaViewer);
// read and decode packets from the source file and
// and dispatch decoded audio and video to the writer
@ -54,29 +69,53 @@ public class Transcoder {
mediumFile.delete();
smallFile.delete();
}
System.out.println("Done!");
System.out.println("\n\nDone!");
}
}
class VideoTranscoderListener extends MediaToolAdapter{
private int width;
private int height;
class Resizer extends MediaToolAdapter {
private Integer width;
private Integer height;
public VideoTranscoderListener(int width, int height) {
this.width = width;
this.height = height;
}
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 );
//streamCoder.setCodec( ICodec.ID.CODEC_ID_AAC );
//streamCoder.setBitRate( 128 );
}
else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
streamCoder.setWidth( width );
streamCoder.setHeight( height );
public Resizer(Integer aWidth, Integer aHeight) {
this.width = aWidth;
this.height = aHeight;
//streamCoder.setCodec(ICodec.findEncodingCodec( ICodec.ID.CODEC_ID_H264 ));
//streamCoder.setBitRate( 800000 );
/*
int retval = Configuration.configure("/usr/local/xuggler/share/ffmpeg/libx264-superfast.ffpreset", streamCoder);
if (retval<0)
throw new RuntimeException("cound not cofigure coder from preset file");
*/
}
super.onAddStream(event);
}
@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());
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);
@ -85,20 +124,45 @@ class Resizer extends MediaToolAdapter {
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();
}
}
}
class ProgressListener extends MediaToolAdapter {
private long currentLength;
private long totalLength;
private int progress = -1;
public ProgressListener(IContainer c) {
this.totalLength = c.getDuration();
public ProgressListener(IMediaReader reader) {
if( !reader.isOpen() )
reader.open(); // read container
this.totalLength = reader.getContainer().getDuration();
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
currentLength = event.getTimeStamp();
System.out.println(currentLength+" / "+totalLength+" - "+getProgress());
if( (int)(100*getProgress()) != progress ){
progress = (int)(100*getProgress());
System.out.print("\n"+(int)(100*getProgress())+"% ");
}
else System.out.print(".");
}
public long getProcessedLength(){
@ -109,66 +173,53 @@ class ProgressListener extends MediaToolAdapter {
return totalLength;
}
public int getProgress(){
return (int)(((double)currentLength/totalLength)*100);
public double getProgress(){
if(totalLength > 0)
return ((double)currentLength/totalLength);
return 0;
}
}
class CodecChanger extends MediaListenerAdapter {
/*
* HTML5
* video codec - avc1.42E01E i.e. H.264/MPEG-4 AVC
* audio codec - mp4a.40.2 i.e. MPEG-4 AAC LC
*/
public void onAddStream(IAddStreamEvent event) {
// put your stream specific configuration code here
// you can get the container from the writer and
// get the specific stream from the container using
// the stream index in the event
int streamIndex = event.getStreamIndex();
IStream stream = event.getSource().getContainer().getStream(streamIndex);
ICodec.Type codecType = stream.getStreamCoder().getCodecType();
if(codecType == ICodec.Type.CODEC_TYPE_AUDIO){
applyAudioSettings(stream);
} else {
applyVideoSettings(stream);
}
class FrameGrabListener extends MediaToolAdapter {
private long totalLength;
private long grabAt;
private File outputFile;
public FrameGrabListener(IMediaReader reader, File outputFile, double at) {
if( !reader.isOpen() )
reader.open(); // read container
this.totalLength = reader.getContainer().getDuration();
this.outputFile = outputFile;
setAtProgress(at);
}
private void applyVideoSettings(IStream stream) {
IStreamCoder coder = stream.getStreamCoder();
coder.setCodec(ICodec.ID.CODEC_ID_H264);
coder.setBitRate( 500000 );
//IVideoResampler.make(outWidth, outHeight, outContainer.getPixelType(), inContainer.getWidth(), inContainer.getHeight(), inContainer.getPixelType());
@Override
public void onVideoPicture(IVideoPictureEvent event) {
try{
long currentLength = event.getTimeStamp();
if( grabAt > 0 && currentLength > grabAt ){
System.out.println("\nScreanshoot!!!");
ConverterFactory.Type mConverterType = ConverterFactory.findRegisteredConverter(
ConverterFactory.XUGGLER_BGR_24);
IConverter mVideoConverter = ConverterFactory.createConverter(
mConverterType.getDescriptor(),
event.getPicture());
ImageIO.write(
mVideoConverter.toImage(event.getPicture()),
"png",
outputFile);
grabAt = -1;
}
}catch(IOException e){
e.printStackTrace();
}
}
private void applyAudioSettings(IStream stream) {
IStreamCoder coder = stream.getStreamCoder();
// ICodec.ID.CODEC_ID_MP3
coder.setCodec( ICodec.ID.CODEC_ID_AAC );
//coder.setSampleRate( 44000 );
coder.setBitRate( 128 );
//IAudioResampler.make(out.getChannels(), in.getChannels(), out.getSampleRate(), in.getSampleRate());
}
}
public void setAtProgress(double procent){
grabAt = (long)(totalLength * procent);
}
}
class SetVideoTranscodeListener extends MediaToolAdapter {
@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_VIDEO) {
streamCoder.setCodec(ICodec.findEncodingCodec(ICodec.ID.CODEC_ID_H264));
int retval = Configuration.configure("/usr/local/xuggler/share/ffmpeg/libx264-superfast.ffpreset", streamCoder);
if (retval<0)
throw new RuntimeException("cound not cofigure coder from preset file");
}
super.onAddStream(event);
}
}