我正在借助您可以在此处找到的两个示例来使用Camera2 API:
- GitHub - 相机2视频
- GitHub - Camera2Basic
使用的是与上述链接相同的源代码,所以我不会在这里复制我的源代码(除非您需要某些部分,否则我会编辑我的问题并发布它)。
编辑:
运行了一些测试。当我尝试通过手机播放视频时,它只显示第一帧,我可以听到实际在录音中的音频(声音)。视频直到结束,视频会以某种方式自动重新启动并按原样显示视频。
但是,当我尝试在PC上播放视频(将其从手机复制到桌面)时,我只会在最后一帧之前出现黑屏。显示最后一帧,但视频根本不播放。我可以听到音频(声音)。
我在想也许某些视频编码/解码有问题?
问题:
就我而言,视频录制将无法正常工作。我 可以在目录中看到它们应该在我的手机上的两个文件, 但是当我播放视频时 (5秒视频)前 4 秒是黑色的,然后最后一秒是这样的 我录制的一帧,仅此而已,但文件大小似乎很大(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 开始。 这将解决音频视频同步问题, 你在上面发了。
三星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);