whycxzp
2024-07-29 8769a20594326a1b60487d550aa616aa4277ba72
更新
2个文件已修改
74 ■■■■■ 已修改文件
app/src/main/java/com/whyc/Camera2TextureViewActivity.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/whyc/widget/Camera2TextureView4.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/whyc/Camera2TextureViewActivity.java
@@ -10,12 +10,12 @@
import android.widget.LinearLayout;
import android.widget.TextView;
import com.whyc.widget.Camera2TextureView2;
import com.whyc.widget.Camera2TextureView4;
public class Camera2TextureViewActivity extends Activity {
    private static final String TAG = Camera2TextureViewActivity.class.getSimpleName();
    private Button camera2Recording;
    private Camera2TextureView2 camera2TextureView;
    private Camera2TextureView4 camera2TextureView;
    private boolean isRecording = false;
app/src/main/java/com/whyc/widget/Camera2TextureView4.java
@@ -42,7 +42,6 @@
/**
 * 这个采用ImageReader视频帧来获取视频和处理图片
 * TODO 关闭录像出现mMediaMuxer 异常
 * */
public class Camera2TextureView4 extends TextureView {
@@ -194,6 +193,9 @@
    private void startPreview() {
        //启动预览
        try {
            if(previewThreadHandler == null){
                initPreviewThreadHandler();
            }
            mCaptureSession.setRepeatingRequest(previewCaptureBuilder.build(), null, previewThreadHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
@@ -284,14 +286,14 @@
        byte[] nv12 = new byte[I420size];
        byte[] nv21 = new byte[I420size];
        YUVUtil.YUVToNV21_NV12(image,nv12,videoWidth,videoHeight,"NV12");
        YUVUtil.YUVToNV21_NV12(image, nv12, videoWidth, videoHeight, "NV12");
        long now = image.getTimestamp();
        image.close();
        //图片截图
        SharedPreferences camera2Time = mContext.getSharedPreferences("camera2Time", Context.MODE_PRIVATE);
        long lastTime = camera2Time.getLong("time", 0);
        long secondsGap = (now - lastTime) / 1000000000;
        if (lastTime == 0  || secondsGap > 2) {
        if (lastTime == 0 || secondsGap > 2) {
            camera2Time.edit().putLong("time", now).apply();
            //需要将nv12转化为nv21后进行图片存储
            nv21 = convertNV12toNV21(nv12);
@@ -300,34 +302,41 @@
        }
        // 提交数据给MediaCodec
        int inputBufferIndex = mMediaCodec.dequeueInputBuffer(0);
        if (inputBufferIndex >= 0) {
            ByteBuffer inputBuffer = mMediaCodec.getInputBuffer(inputBufferIndex);
            inputBuffer.clear();
            inputBuffer.put(nv12);
            long nanoTime = System.nanoTime();
            long presentationTimeUs = nanoTime / 1000; // 将纳秒转换为微秒
            mMediaCodec.queueInputBuffer(inputBufferIndex, 0, nv12.length, presentationTimeUs, 0);
        }
        // 获取编码后的数据汇入H264 封装成mp4
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            mVideoTrackIndex = mMediaMuxer.addTrack(mMediaCodec.getOutputFormat());
            if(mVideoTrackIndex != -1){
                mMediaMuxer.start();
        try {
            int inputBufferIndex = mMediaCodec.dequeueInputBuffer(0);
            if (inputBufferIndex >= 0) {
                ByteBuffer inputBuffer = mMediaCodec.getInputBuffer(inputBufferIndex);
                inputBuffer.clear();
                inputBuffer.put(nv12);
                long nanoTime = System.nanoTime();
                long presentationTimeUs = nanoTime / 1000; // 将纳秒转换为微秒
                mMediaCodec.queueInputBuffer(inputBufferIndex, 0, nv12.length, presentationTimeUs, 0);
            }
        }
        while (outputBufferIndex >=0){
            ByteBuffer outputBuffer = mMediaCodec.getOutputBuffer(outputBufferIndex);
            if (mVideoTrackIndex != -1) {
                mMediaMuxer.writeSampleData(mVideoTrackIndex, outputBuffer, bufferInfo);
            // 获取编码后的数据汇入H264 封装成mp4
            MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
            int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0);
            if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                mVideoTrackIndex = mMediaMuxer.addTrack(mMediaCodec.getOutputFormat());
                if (mVideoTrackIndex != -1) {
                    mMediaMuxer.start();
                }
            }
            mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
            outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0);
            if((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) !=0){
                break;
            while (outputBufferIndex >= 0) {
                ByteBuffer outputBuffer = mMediaCodec.getOutputBuffer(outputBufferIndex);
                if (mVideoTrackIndex != -1) {
                    mMediaMuxer.writeSampleData(mVideoTrackIndex, outputBuffer, bufferInfo);
                    mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
                    outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0);
                    if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                        break;
                    }
                }
            }
        } catch (Exception e) {
            //中断错误,忽略
        }
    };
@@ -434,10 +443,11 @@
        try {
            previewThread.quitSafely();
            previewThread.join();
            previewThread = null;
            previewThreadHandler = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            previewThread = null;
            previewThreadHandler = null;
        }
    }