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).
屏幕:
- 将post视频上传一次
我不知道哪里出了问题,有人可以帮忙吗?
这不是真正的解决方案,但它仍然可以满足我的要求。
为了播放视频,我必须在我的 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);
我正在使用 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).
屏幕:
- 将post视频上传一次
我不知道哪里出了问题,有人可以帮忙吗?
这不是真正的解决方案,但它仍然可以满足我的要求。
为了播放视频,我必须在我的 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);