2012-06-13 118 views
4

我試圖翻譯一大組bufferedimages(由我的應用程序在飛行上創建的預先保存的圖像)到一個視頻使用java,並希望有一個圖書館,可以幫助進程。使用bufferedimages將視頻編碼成h264?

我已經探索了一些不同的選項,如jcodec(沒有關於如何使用它的文檔)。 Xuggler(由於與jdk5及其相關庫的兼容性問題,無法運行它)。還有一些其他圖書館的文獻資料很差。 (1)通過逐幀編寫bufferedimages創建h264視頻,(2)具有文檔,以便我可以真正弄清楚如何使用該大壩事情。

關於我應該看什麼的任何想法?

如果純java源代碼存在的地方可以實現這一點,我會非常有興趣看到它。因爲我很想看看這個人是如何實現這個功能以及我如何使用它的!

在此先感謝...

+0

你的程序需要多少時間了編碼'BufferedImages'到'video'? – Mavie

回答

1

這裏是你如何可以JCodec做到這一點:

public class SequenceEncoder { 
    private SeekableByteChannel ch; 
    private Picture toEncode; 
    private RgbToYuv420 transform; 
    private H264Encoder encoder; 
    private ArrayList<ByteBuffer> spsList; 
    private ArrayList<ByteBuffer> ppsList; 
    private CompressedTrack outTrack; 
    private ByteBuffer _out; 
    private int frameNo; 
    private MP4Muxer muxer; 

    public SequenceEncoder(File out) throws IOException { 
     this.ch = NIOUtils.writableFileChannel(out); 

     // Transform to convert between RGB and YUV 
     transform = new RgbToYuv420(0, 0); 

     // Muxer that will store the encoded frames 
     muxer = new MP4Muxer(ch, Brand.MP4); 

     // Add video track to muxer 
     outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, 25); 

     // Allocate a buffer big enough to hold output frames 
     _out = ByteBuffer.allocate(1920 * 1080 * 6); 

     // Create an instance of encoder 
     encoder = new H264Encoder(); 

     // Encoder extra data (SPS, PPS) to be stored in a special place of 
     // MP4 
     spsList = new ArrayList<ByteBuffer>(); 
     ppsList = new ArrayList<ByteBuffer>(); 

    } 

    public void encodeImage(BufferedImage bi) throws IOException { 
     if (toEncode == null) { 
      toEncode = Picture.create(bi.getWidth(), bi.getHeight(), ColorSpace.YUV420); 
     } 

     // Perform conversion 
     transform.transform(AWTUtil.fromBufferedImage(bi), toEncode); 

     // Encode image into H.264 frame, the result is stored in '_out' buffer 
     _out.clear(); 
     ByteBuffer result = encoder.encodeFrame(_out, toEncode); 

     // Based on the frame above form correct MP4 packet 
     spsList.clear(); 
     ppsList.clear(); 
     H264Utils.encodeMOVPacket(result, spsList, ppsList); 

     // Add packet to video track 
     outTrack.addFrame(new MP4Packet(result, frameNo, 25, 1, frameNo, true, null, frameNo, 0)); 

     frameNo++; 
    } 

    public void finish() throws IOException { 
     // Push saved SPS/PPS to a special storage in MP4 
     outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList)); 

     // Write MP4 header and finalize recording 
     muxer.writeHeader(); 
     NIOUtils.closeQuietly(ch); 
    } 
} 
+1

其實你從https://github.com/jcodec/jcodec/blob/master/src/main/java/org/jcodec/api/SequenceEncoder.java輸入類。你能否澄清理由?爲什麼OP應該重寫這個類? – CAMOBAP

+0

@CAMOBAP或從http://stackoverflow.com/q/17695475/5353361。 'RgbToYuv420','CompressedTrack'和大多數方法不會從jcodec-0.1.9.jar導入到Eclipse中。 http://jcodec.org/上的教程也大致相同。然而,github僅在3天前更新。爲什麼人們不斷髮布破壞的'SequenceEncoder'? – John

1

jcodec現在(jcodec-0.1.9.jar)包括SequenceEncoder直接允許的BufferedImage寫作到視頻流。

我花了一段時間修復了這個新類的默認導入到Eclipse。除去第一進口,嘗試之後(正如我上面所說的,我無法找到一些類)使用斯坦尼斯的代碼,並重新導入我發現了錯誤創建我自己

import org.jcodec.api.awt.SequenceEncoder; 
//import org.jcodec.api.SequenceEncoder; 

二是完全過時了沒有任何文獻指引我參考後者。

相稱的方法則是:

private void saveClip(Trajectory traj) { 
    //See www.tutorialspoint.com/androi/android_audio_capture.htm 
    //for audio cap ideas. 
    SequenceEncoder enc; 
    try { 
     enc = new SequenceEncoder(new File("C:/Users/WHOAMI/today.mp4")); 
     for (int i = 0; i < BUFF_COUNT; ++i) { 
      BufferedImage image = buffdFramToBuffdImage(frameBuff.get(i)); 
      enc.encodeImage(image); 
     } 
     enc.finish(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 
+1

'jcodec'以'QuickTime'格式創建視頻,並且每幀需要很多時間(或者BufferedImage)。 – Mavie