【问题标题】:Android: Seek video frame by frame onSeekbar changedAndroid:在 Seekbar 更改上逐帧搜索视频
【发布时间】:2017-02-20 05:12:10
【问题描述】:

我在我的项目中使用了视频视图和搜索栏,这是搜索栏更改时的当前代码

seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {

            if (fromUser) {
                // this is when actually seekbar has been seeked to a new
                // position
                videoView.seekTo(progress);
            }
        }
    });

问题是:draw seekbar 时视频 seek 不流畅,是跳帧。

例如:

点 1 到点 2:

持续时间:1 秒

帧数:3

如果通过 videoView.start() 播放视频没问题,但如果从点 1 到点 2 绘制搜索栏,则会跳过第 2 帧。

【问题讨论】:

    标签: android android-videoview seekbar


    【解决方案1】:

    在对视频流进行编码时,通常会有一个叫做 I 帧(I-Picture)或关键帧的东西,这意味着这个帧有很多信息,可以用来完整地解码一帧。为了减少空间量,所有帧都没有编码为关键帧,而是编码为 P(预测)帧或预测帧,这意味着您可以在关键帧的帮助下解码 P 帧。

    所以在查找操作期间,在这种情况下,查找是在给定的持续时间内对最近的关键帧进行的。例如,如果用户搜索到 40 秒,而最近的关键帧在第 35 秒,则搜索将在第 35 秒而不是第 40 秒完成。

    您仍然可以尝试以下方法,看看它是否有效。 I图片之间的距离通常为0.5秒。因此,不要以毫秒为单位,而是尝试使用 secs 直接跳转到 I 图片。

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
    
            if (fromUser) {
                // this is when actually seekbar has been seeked to a new
                // position
                videoView.seekTo(progressx1000);
            }
        }
    enter code here
    

    尝试像这样在 onStopTrackingTouch() 中调用它:

    public void onStopTrackingTouch(SeekBar seekBar) {
         videoView.seekTo(seekBar.getProgress());
    }
    

    这就是我在项目中的做法。

    【讨论】:

    • @Nicky 你面临什么问题,使用这个解决方案?应该可以!
    • 请看这个视频link(案例 seekTo onProgressChanged)。如您所见,当我拖动 seekBar 时它会滞后。如果我将 seekTo 放在StopTrackingTouch 上,那么只有在我停止拖动时才会出现 seekTo。谢谢
    • 还是不行,我的问题是 video.seekTo() 跳帧,所以滑动搜索栏时视频预览不流畅。
    • 这不行,它会一直寻找关键帧。 Mediacodec 是实现这一目标的唯一原生方式。
    【解决方案2】:

    VideoViewer seekTo() 函数有点受限,它假定您想要快速回到关键帧。但是,MediaPlayer 允许您覆盖该选择:

    mediaPlayer.seekTo(time, MediaPlayer.SEEK_CLOSEST);
    

    其他值包括:SEEK_PREVIOUS_SYNC、SEEK_NEXT_SYNC、SEEK_CLOSEST_SYNC。

    如果您还没有 MediaPlayer 的实例,例如,您可以在 VideoViewer 的 onPreparedListener 中访问它。

    有关 MediaPlayer 的 seekTo 的详细信息,请参阅here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多