3

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

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

编辑:

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

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

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

问题:

在我的情况下,视频录制将不起作用。我可以在他们应该在我的手机上的目录中看到这两个文件,但是当我播放视频(5 秒视频)时,前 4 秒是黑色的,然后最后一秒就像我录制的一帧,仅此而已,但文件大小似乎很大(160MB)。

屏幕:

  • 上传后会发布视频

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

4

4 回答 4

5

这不是一个真正的解决方案,但它仍然完成了我想做的事情。

为了播放视频,我必须在 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);

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

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

于 2016-03-04T13:28:15.310 回答
1

三星 Galaxy S7(和我认为是 S6)有一个错误,它弄乱了编码。解决方法是使用下面的函数重新编码。

请注意,您的 gradle 中需要此依赖项: compile '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");
    }
}
于 2017-07-31T15:54:12.657 回答
1

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

于 2016-12-29T19:56:52.433 回答
0

这段代码对我有用:

mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
于 2017-11-11T07:23:08.180 回答