Android camera2 api galaxy s7

我正在编写一个应用程序,用于记录手机中的video并将其上传到服务器。 适用于除Galaxy S7之外的任何设备。 在Galaxy S7上,录制的video文件只包含音频,没有video或一个video帧。 这在手机上创建的临时文件中是正确的,而不仅仅是上传到服务器的临时文件。 我正在使用Camera2 API,我尝试使用前后摄像头。

我尝试过我的代码和这两个示例应用程序: https : //developer.android.com/samples/Camera2Video/project.html https://github.com/googlesamples/android-Camera2Video/blob/master/Application/的src /主/ JAVA / COM /示例/机器人/ camera2video / Camera2VideoFragment.java

生成的video文件似乎没问题,这里是编解码器信息:Stream 0类型:video编解码器:H264 – MPEG-4 AVC(第10部分)(avc1)语言:英语分辨率:960×720显示分辨率:960×720帧率:29.055091

流1类型:音频编解码器:MPEG AAC音频(mp4a)语言:英语频道:立体声采样率:16000 Hz

经过几天的工作,我找到了答案。

三星Galaxy S7(和我认为的S6)有一个混淆编码的错误。 修复是使用以下function重新编码。

请注意,您需要在gradle中使用此依赖项:compile’c​​om.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 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"); } }