2012-01-24 28 views
4

私はこのビデオを編集できるように、h.264ビデオをエンコードしてデコードできるプログラムを作成しようとしています。 私はこのプログラムをJavaで作成したいと思ったら誰でも私にこれをどうやって言うことができますか?Java - h.264ビデオエンコーディング

+0

最終的に 'FFMpeg'はこれを行うことができましたが、私はあまりよく分かりません。もしそうなら、Java Wrapperがあれば分かります。 – evotopid

+0

[Xuggler](http://www.xuggle.com/xuggler/)API – JuanZe

+0

を試してみました。これは、(JMFを使用しようとするよりも)はるかに良いアイデアのようです。 +1 –

答えて

1

目的の形式をエンコードおよびデコードできるクラスを取得または書き出します。サービスプロバイダインターフェイスであることを確認してください。それをアプリケーションのランタイムクラスパスに追加します。 JMFのデフォルトプレーヤーを使用して再生します。それを編集することについてあまり確かではありません。

0

ffmpegライブラリとx264を確認してください。これらのライブラリをコンパイルして作成します。それは、ビデオのエンコード/デコードのための非常に良いAPIを持っています。 ffmpegだけをコンパイルすると、h.264をエンコードすることはできません。デコードするだけです。 h264をエンコードするには、x264ライブラリをコンパイルする必要があります。 http://ubuntuforums.org/showthread.php?t=786095。かなり良いチュートリアル。 これはC APIですが、ネイティブメソッドを使用して呼び出すことができます。

よろしくお願いします。英語に申し訳ありません。

7

JCodec(http://jcodec.org)を使用できます。

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(Picture bi) throws IOException { 
     if (toEncode == null) { 
      toEncode = Picture.create(bi.getWidth(), bi.getHeight(), ColorSpace.YUV420); 
     } 

     // Perform conversion (RGB -> YUV) 
     transform.transform(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); 
    } 
} 

そして最後に Androidの画像使用からとTO を変換する:

public static Picture fromBitmap(Bitmap src) { 
    Picture dst = Picture.create((int)src.getWidth(), (int)src.getHeight(), RGB); 
    fromBitmap(src, dst); 
    return dst; 
} 

public static void fromBitmap(Bitmap src, Picture dst) { 
    int[] dstData = dst.getPlaneData(0); 
    int[] packed = new int[src.getWidth() * src.getHeight()]; 

    src.getPixels(packed, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight()); 

    for (int i = 0, srcOff = 0, dstOff = 0; i < src.getHeight(); i++) { 
     for (int j = 0; j < src.getWidth(); j++, srcOff++, dstOff += 3) { 
      int rgb = packed[srcOff]; 
      dstData[dstOff]  = (rgb >> 16) & 0xff; 
      dstData[dstOff + 1] = (rgb >> 8) & 0xff; 
      dstData[dstOff + 2] = rgb & 0xff; 
     } 
    } 
} 

public static Bitmap toBitmap(Picture src) { 
    Bitmap dst = Bitmap.create(pic.getWidth(), pic.getHeight(), ARGB_8888); 
    toBitmap(src, dst); 
    return dst; 
} 

public static void toBitmap(Picture src, Bitmap dst) { 
    int[] srcData = src.getPlaneData(0); 
    int[] packed = new int[src.getWidth() * src.getHeight()]; 

    for (int i = 0, dstOff = 0, srcOff = 0; i < src.getHeight(); i++) { 
     for (int j = 0; j < src.getWidth(); j++, dstOff++, srcOff += 3) { 
      packed[dstOff] = (srcData[srcOff] << 16) | (srcData[srcOff + 1] << 8) | srcData[srcOff + 2]; 
     } 
    } 
    dst.setPixels(packed, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight()); 
} 
配列をコードするために

int frameNumber = 10000; 
FileChannelWrapper ch = null; 
try { 
    ch = NIOUtils.readableFileChannel(new File(path to mp4)); 
    FrameGrab frameGrab = new FrameGrab(ch); 

    frameGrab.seek(frameNumber); 
    Picture frame; 
    for (int i = 0; (frame = frameGrab.getNativeFrame()) != null && i < 200; i++) { 
     // Do something 
    } 
} finally { 
    NIOUtils.closeQuietly(ch); 
} 

:ビデオシーケンス行くをデコードする

FINALLY RGBフレーム行くためにそれを変換するために、あなたはYUVがフレームアウト買ってあげるデコードに:

Transform transform = ColorUtil.getTransform(pic.getColor(), ColorSpace.RGB); 
Picture rgb = Picture.create(pic.getWidth(), pic.getHeight(), ColorSpace.RGB); 
transform.transform(pic, rgb); 

そして、すべてDEPSを使用して、ダウンロードJARを確認してください:http://jcodec.org/downloads/jcodec-0.1.3-uberjar.jar

+0

ありがとうございました。エンコーディング操作の計算量はどのくらいですか? – biggvsdiccvs

関連する問題