/** @param args the command line arguments */ public static void main(String[] args) throws IOException { final ArrayList<BufferedImage> frames = new ArrayList<BufferedImage>(); final File f = new File( "/Users/Shared/Developer/Java/MonteMedia/current/trunk/MonteMedia/avidemo-tscc8.avi"); MovieReader in = Registry.getInstance().getReader(f); try { Format format = new Format(VideoFormatKeys.EncodingKey, VideoFormatKeys.ENCODING_BUFFERED_IMAGE); int track = in.findTrack(0, new Format(FormatKeys.MediaTypeKey, MediaType.VIDEO)); if (track == -1) { throw new IOException("Movie has no video track."); } Codec codec = Registry.getInstance().getCodec(in.getFormat(track), format); if (codec == null) { throw new IOException("Can not decode video track."); } Buffer inBuf = new Buffer(); Buffer codecBuf = new Buffer(); do { in.read(track, inBuf); if (codec.process(inBuf, codecBuf) == Codec.CODEC_FAILED) { System.out.println("Can not decode buffer " + inBuf); } if (!codecBuf.isFlag(BufferFlag.DISCARD)) { frames.add(Images.cloneImage((BufferedImage) codecBuf.data)); } } while (!inBuf.isFlag(BufferFlag.END_OF_MEDIA)); } finally { in.close(); } SwingUtilities.invokeLater( new Runnable() { @Override public void run() { JFrame fr = new JFrame(f.getName()); fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JLabel label = new JLabel(new ImageIcon(frames.get(0))); final JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, frames.size() - 1, 0); slider.addChangeListener( new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { label.setIcon(new ImageIcon(frames.get(slider.getValue()))); } }); fr.add(BorderLayout.CENTER, label); fr.add(BorderLayout.SOUTH, slider); fr.pack(); fr.setVisible(true); } }); }
@Override public void read(Buffer buf) { if (position < demux.getFrameCount()) { buf.setFlagsTo(KEYFRAME); if (!(buf.data instanceof BitmapImage)) { buf.data = demux.createCompatibleBitmap(); } demux.readFrame((int) position, (BitmapImage) buf.data); buf.sampleDuration = new Rational(demux.getDuration((int) position), demux.getJiffies()); position++; } else { buf.setFlagsTo(DISCARD); } }
@Override public void write(int track, Buffer buf) throws IOException { VideoTrack t = tracks.get(track); if (buf.isFlag(DISCARD)) { return; } File file = new File(t.dir, String.format(t.nameFormat, t.count + 1)); if (buf.data instanceof byte[]) { FileOutputStream out = new FileOutputStream(file); try { out.write((byte[]) buf.data, buf.offset, buf.length); } finally { out.close(); } } else if (buf.data instanceof File) { FileInputStream in = new FileInputStream((File) buf.data); try { FileOutputStream out = new FileOutputStream(file); try { byte[] b = new byte[2048]; int len; while ((len = in.read(b)) != -1) { out.write(b, 0, len); } } finally { out.close(); } } finally { in.close(); } } else { throw new IllegalArgumentException("Can't process buffer data:" + buf.data); } t.count++; }
public int process(Buffer in, Buffer out) { out.setMetaTo(in); if (in.isFlag(DISCARD)) { return CODEC_OK; } out.format = outputFormat; SeekableByteArrayOutputStream tmp; if (out.data instanceof byte[]) { tmp = new SeekableByteArrayOutputStream((byte[]) out.data); } else { tmp = new SeekableByteArrayOutputStream(); } Format vf = outputFormat; // Handle sub-image Rectangle r; int scanlineStride; if (in.data instanceof BufferedImage) { BufferedImage image = (BufferedImage) in.data; WritableRaster raster = image.getRaster(); scanlineStride = raster.getSampleModel().getWidth(); r = raster.getBounds(); r.x -= raster.getSampleModelTranslateX(); r.y -= raster.getSampleModelTranslateY(); } else { r = new Rectangle(0, 0, vf.get(WidthKey), vf.get(HeightKey)); scanlineStride = vf.get(WidthKey); } try { switch (vf.get(DepthKey)) { case 8: { writeKey8( tmp, getIndexed8(in), r.width, r.height, r.x + r.y * scanlineStride, scanlineStride); break; } case 16: { writeKey16( tmp, getRGB15(in), r.width, r.height, r.x + r.y * scanlineStride, scanlineStride); break; } case 24: { writeKey24( tmp, getRGB24(in), r.width, r.height, r.x + r.y * scanlineStride, scanlineStride); break; } case 32: { writeKey24( tmp, getARGB32(in), r.width, r.height, r.x + r.y * scanlineStride, scanlineStride); break; } default: { out.setFlag(DISCARD); return CODEC_FAILED; } } out.format = outputFormat; out.sampleCount = 1; out.setFlag(KEYFRAME); out.data = tmp.getBuffer(); out.offset = 0; out.length = (int) tmp.getStreamPosition(); return CODEC_OK; } catch (IOException ex) { ex.printStackTrace(); out.setFlag(DISCARD); return CODEC_FAILED; } }