Android Camera2画面黑屏,录像只有1秒

Android Camera2 picture is black and video records only 1sec

我正在使用 Camera2 API 并借助您可以在此处找到的两个示例:

我使用与上述链接中相同的源代码,因此我不会在此处复制我的源代码(除非您需要某些部分,否则我将编辑我的问题并post)。

编辑:

运行 一些测试。当我尝试通过我的 phone 播放视频时,它只显示第一帧,我可以听到实际在录音中的音频(声音)。一旦视频播放到结束,视频会以某种方式自动重新开始并按应有的方式显示视频。

但是,当我尝试在我的 PC 上播放视频时(将其从 Phone 复制到桌面),我只看到最后一帧黑屏。显示最后一帧,但视频根本不播放。我可以听到音频(声音)。

我在想可能是某些视频编码/解码有问题?

问题:

In my case the Video recording won't work. I can see both files in the directory that they should be on my Phone, but when I play the video (5 second video) first 4 seconds are black, then last second is like one Frame of what I recorded and that's it, yet file size seems big (160MB).

屏幕:

我不知道哪里出了问题,有人可以帮忙吗?

这不是真正的解决方案,但它仍然可以满足我的要求。

为了播放视频,我必须在我的 MediaRecorder 设置中完全禁用音频

        //mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setOutputFile(getVideoFile(activity).getAbsolutePath());
        mMediaRecorder.setVideoEncodingBitRate(10000000);
        mMediaRecorder.setVideoFrameRate(24);
        mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
        //mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

你可以注意到我在哪里可以注释掉命令。一旦我这样做了,视频就可以正常播放了。

希望这个糟糕 解决方法仍然可以帮助那些不需要在视频录制中使用音频的人。

在某些设备上,特别是 Galaxy 系列、S7 等,媒体记录器为视频轨道提供了错误的时间戳。这会导致先播放音频,然后再播放视频。要解决此问题,您需要重新分析媒体记录器生成的输出并重写视频时间戳,从时间 0 开始。这将解决您在上面发布的音频视频同步问题。

Samsung Galaxy S7(我认为是 S6)有一个错误,会导致编码混乱。 解决方法是使用以下函数重新编码。

请注意,您的 gradle 中需要此依赖项: 编译 'com.googlecode.mp4parser:isoparser:1.1.22'

    public void fixSamsungBug()
{
    DataSource channel = null;
    try
    {
        channel = new FileDataSourceImpl(app.dataMgr.videoFileURL);
    } catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }

    IsoFile isoFile = null;

    try
    {
        isoFile = new IsoFile(channel);
    } catch (IOException e)
    {
        e.printStackTrace();
    }

    List<TrackBox> trackBoxes = isoFile.getMovieBox().getBoxes(TrackBox.class);
    boolean sampleError = false;
    for (TrackBox trackBox : trackBoxes) {
        TimeToSampleBox.Entry firstEntry = trackBox.getMediaBox().getMediaInformationBox().getSampleTableBox().getTimeToSampleBox().getEntries().get(0);

        // Detect if first sample is a problem and fix it in isoFile
        // This is a hack. The audio deltas are 1024 for my files, and video deltas about 3000
        // 10000 seems sufficient since for 30 fps the normal delta is about 3000
        if(firstEntry.getDelta() > 10000) {
            sampleError = true;
            firstEntry.setDelta(3000);
        }
    }

    if(sampleError) {
        Log.d("gpinterviewandroid", "Sample error! correcting...");
        Movie movie = new Movie();
        for (TrackBox trackBox : trackBoxes) {
            movie.addTrack(new Mp4TrackImpl(channel.toString() + "[" + trackBox.getTrackHeaderBox().getTrackId() + "]" , trackBox));
        }
        movie.setMatrix(isoFile.getMovieBox().getMovieHeaderBox().getMatrix());
        Container out = new DefaultMp4Builder().build(movie);

        //delete file first!
        File file = new File(app.dataMgr.videoFileURL);
        boolean deleted = file.delete();


        FileChannel fc = null;
        try
        {
            //fc = new FileOutputStream(new File(app.dataMgr.videoFileURL)).getChannel();
            fc = new RandomAccessFile(app.dataMgr.videoFileURL, "rw").getChannel();
        } catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }

        try
        {
            out.writeContainer(fc);
            fc.close();
        } catch (IOException e)
        {
            e.printStackTrace();
        }

        Log.d("gpinterviewandroid", "Finished correcting raw video");
    }
}

这段代码对我有用:

mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);