我是 Android 开发新手。我的原始文件夹中有一个视频,我想以不同的部分播放它,例如 20-40 秒或 1:20-2.30 秒。问题在于视频时间同步。假设我的视频从 1:34(即 94 int)秒开始。在小于 23 的 api 上,它工作正常,并在我想要的时间播放视频,但在高于 23 的 api 上,它从 1:32 秒(int 中的 92)开始播放。如何解决这个问题呢 ?任何帮助和建议将不胜感激。谢谢
case "Exer2":
{
mPlayBtn.setVisibility(View.INVISIBLE);
mVideo.postDelayed(onExer2ForEverySecond,1000);
Log.i(TAG,"Exer2 Case");
mStartTime=94*1000;
mVideo.seekTo(mStartTime);
mVideo.start();
break;
}
Runnable onExer2ForEverySecond=new Runnable() {
@Override
public void run() {
mVideo.postDelayed(onExer2ForEverySecond,1000);
if(mVideo.isPlaying())
{
if(mVideo.getCurrentPosition()==153*1000){
mVideo.pause();
}
}
}
};
最佳答案
关键帧
视频由帧(图片)组成,通常每秒 30 帧。框架可以有两种类型:
- 关键帧、同步帧或帧内
- 不是关键帧
关键帧包含完整图片,而非关键帧包含前一个关键帧的更改。因此,如果您查看任何非关键帧,您将不会看到完整的图像,而只会看到某些部分。 非关键帧没有关键帧就没有意义。
关键帧占用更多空间,非关键帧占用匹配更少的空间。该算法提供了减小视频文件大小的能力。
要点是:
- 如果某个关键帧每秒出现一次,则意味着该秒内有 29 个其他帧不是关键帧。
- 不同视频中关键帧的频率可能不同,例如一个视频每秒有 1 个关键帧,而另一个视频每 3 秒有 1 个关键帧。
这里是the Wiki link了解更多详情。
寻找视频
VideoView ,你似乎正在使用什么,在引擎盖下使用 MediaPlayer .seekTo()方法。此方法将以您设置的毫秒为单位搜索您的视频。但如果在该毫秒的视频中包含非关键帧,seekTo() 方法将搜索 a previous key-frame (因为非关键帧对于观看您视频的用户来说没有任何意义)。
返回到上一个关键帧将减少您在seekTo() 方法中设置的毫秒数。这就是为什么您的视频从 1:32 秒开始播放,而不是 1:34(即 94 int)秒。而且它完全不依赖于 Android API 级别。
解决方案
实际上,您可以在代码中实现没有简单的解决方案,一切都取决于您将使用的视频。
视频的关键帧频率应为每秒 1 个或更高。在这种情况下,您可以毫无问题地找到所需的视频。
如果关键帧频率低于每秒 1 个(例如每 2 秒 1 个),您将需要重新转换视频以达到关键帧频率 1/秒。以编程方式执行此操作并非易事,因此最好在 Adobe Premier 或任何其他视频工具中准备视频。
关于java - 视频所需开始时间同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51856161/