日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android无法解码avcmp4,android - Android中的MediaCodec编码的H.264 avc视频无法播放 - 堆栈内存溢出...

發布時間:2023/12/14 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android无法解码avcmp4,android - Android中的MediaCodec编码的H.264 avc视频无法播放 - 堆栈内存溢出... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景:

我一直在努力實現像錄像機這樣的Vine兩天。 首先,我嘗試了MediaRecorder。 但我需要的視頻可能是由小視頻片段組成的。 此類不能用于錄制短時視頻剪輯。 然后我找到了MediaCodec,FFmpeg和JavaCV。 FFmpeg和JavaCV可以解決這個問題。 但我必須使用許多庫文件編譯我的項目。 它會生成一個非常大的APK文件。 所以我更喜歡通過MediaCodec實現它,盡管這個類只能在Android 4.1之后使用。 90%的用戶會滿意。

結果:

我終于得到了編碼文件,但無法播放。 我通過FFprobe檢查了信息,結果如下:

輸入#0,h264,來自'test.mp4':持續時間:N / A,比特率:N / A流#0:0:視頻:h264(基線),yuv420p,640x480,25 fps,25 tbr,1200k tbn, 50 tbc

我不太了解H.264編碼的機制。

碼:

從此鏈接修改

public class AvcEncoder {

private static String TAG = AvcEncoder.class.getSimpleName();

private MediaCodec mediaCodec;

private BufferedOutputStream outputStream;

private int mWidth, mHeight;

private byte[] mDestData;

public AvcEncoder(int w, int h) {

mWidth = w;

mHeight = h;

Log.d(TAG, "Thread Id: " + Thread.currentThread().getId());

File f = new File("/sdcard/videos/test.mp4");

try {

outputStream = new BufferedOutputStream(new FileOutputStream(f));

Log.i("AvcEncoder", "outputStream initialized");

} catch (Exception e) {

e.printStackTrace();

}

try {

mediaCodec = MediaCodec.createEncoderByType("video/avc");

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", w,

h);

mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);

mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);

// mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,

// MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);

mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,

MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);

mDestData = new byte[w * h

* ImageFormat.getBitsPerPixel(ImageFormat.YV12) / 8];

mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);

mediaCodec.configure(mediaFormat, null, null,

MediaCodec.CONFIGURE_FLAG_ENCODE);

mediaCodec.start();

}

public void close() {

try {

mediaCodec.stop();

mediaCodec.release();

mediaCodec = null;

// outputStream.flush();

outputStream.close();

} catch (IOException e) {

}

}

public void offerEncoder(byte[] input) {

try {

CameraUtils.transYV12toYUV420Planar(input, mDestData, mWidth,

mHeight);

ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();

ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();

int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);

if (inputBufferIndex >= 0) {

ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];

inputBuffer.clear();

inputBuffer.put(mDestData);

mediaCodec.queueInputBuffer(inputBufferIndex, 0,

mDestData.length, 0, 0);

}

MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();

int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo,

0);

while (outputBufferIndex >= 0) {

ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];

byte[] outData = new byte[bufferInfo.size];

outputBuffer.get(outData);

try {

outputStream.write(outData, 0, outData.length);

} catch (Exception e) {

Log.d("AvcEncoder", "Outputstream write failed");

e.printStackTrace();

}

// Log.i("AvcEncoder", outData.length + " bytes written");

mediaCodec.releaseOutputBuffer(outputBufferIndex, false);

outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo,

0);

}

} catch (Throwable t) {

t.printStackTrace();

}

}

}

通過Camera的startPreview調用此類:

private void startPreview() {

if (mCamera == null) {

return;

}

try {

mCamera.setPreviewDisplay(mSurfaceView.getHolder());

Parameters p = mCamera.getParameters();

Size s = p.getPreviewSize();

int len = s.width * s.height

* ImageFormat.getBitsPerPixel(p.getPreviewFormat()) / 8;

mAvcEncoder = new AvcEncoder(s.width, s.height);

mCamera.addCallbackBuffer(new byte[len]);

mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {

@Override

public void onPreviewFrame(byte[] data, Camera camera) {

mAvcEncoder.offerEncoder(data);

mCamera.addCallbackBuffer(data);

}

});

mCamera.startPreview();

} catch (IOException e) {

e.printStackTrace();

}

}

釋放相機時關閉它:

private void releaseCamera() {

if (mCamera != null) {

mCamera.stopPreview();

mCamera.release();

mCamera = null;

}

if (mAvcEncoder != null) {

mAvcEncoder.close();

}

}

總結

以上是生活随笔為你收集整理的android无法解码avcmp4,android - Android中的MediaCodec编码的H.264 avc视频无法播放 - 堆栈内存溢出...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。