zoukankan      html  css  js  c++  java
  • Android MediaPlayer SeekTo 在 8.0 版本上优化说明

    android使用 mediaPlayer 播放video视频过程中, 当用户退出当前播放,再从后台恢复播放时,需要跳转到之前退出的时间点继续播放。使用的方法基本都是 SeekTo 之前的时间点,但是经常遇到恢复播放时位置不准的问题,而且甚至有重头开始播放的现象。这个是因为SeekTo是回到上一时间点附近的关键帧导致的。

    针对这个问题,在最新的android 8.0平台上,已经有了新的解决方案:

    SeekTo() 方法在android O 平台新增了一个多参数的方法:

    void seekTo(long msec, @SeekMode int mode)

    这里的Mode 传入

    int SEEK_CLOSEST = 0x03 

    就不会出现播放视频位置不准确的现象了。

    /**
         * Seek modes used in method seekTo(long, int) to move media position
         * to a specified location.
         *
         * Do not change these mode values without updating their counterparts
         * in include/media/IMediaSource.h!
         */
        /**
         * This mode is used with {@link #seekTo(long, int)} to move media position to
         * a sync (or key) frame associated with a data source that is located
         * right before or at the given time.
         *
         * @see #seekTo(long, int)
         */
        public static final int SEEK_PREVIOUS_SYNC    = 0x00;
        /**
         * This mode is used with {@link #seekTo(long, int)} to move media position to
         * a sync (or key) frame associated with a data source that is located
         * right after or at the given time.
         *
         * @see #seekTo(long, int)
         */
        public static final int SEEK_NEXT_SYNC        = 0x01;
        /**
         * This mode is used with {@link #seekTo(long, int)} to move media position to
         * a sync (or key) frame associated with a data source that is located
         * closest to (in time) or at the given time.
         *
         * @see #seekTo(long, int)
         */
        public static final int SEEK_CLOSEST_SYNC     = 0x02;
        /**
         * This mode is used with {@link #seekTo(long, int)} to move media position to
         * a frame (not necessarily a key frame) associated with a data source that
         * is located closest to or at the given time.
         *
         * @see #seekTo(long, int)
         */
        public static final int SEEK_CLOSEST          = 0x03;
    
        /** @hide */
        @IntDef(
            value = {
                SEEK_PREVIOUS_SYNC,
                SEEK_NEXT_SYNC,
                SEEK_CLOSEST_SYNC,
                SEEK_CLOSEST,
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface SeekMode {}
    
        private native final void _seekTo(long msec, int mode);
    
        /**
         * Moves the media to specified time position by considering the given mode.
         * <p>
         * When seekTo is finished, the user will be notified via OnSeekComplete supplied by the user.
         * There is at most one active seekTo processed at any time. If there is a to-be-completed
         * seekTo, new seekTo requests will be queued in such a way that only the last request
         * is kept. When current seekTo is completed, the queued request will be processed if
         * that request is different from just-finished seekTo operation, i.e., the requested
         * position or mode is different.
         *
         * @param msec the offset in milliseconds from the start to seek to.
         * When seeking to the given time position, there is no guarantee that the data source
         * has a frame located at the position. When this happens, a frame nearby will be rendered.
         * If msec is negative, time position zero will be used.
         * If msec is larger than duration, duration will be used.
         * @param mode the mode indicating where exactly to seek to.
         * Use {@link #SEEK_PREVIOUS_SYNC} if one wants to seek to a sync frame
         * that has a timestamp earlier than or the same as msec. Use
         * {@link #SEEK_NEXT_SYNC} if one wants to seek to a sync frame
         * that has a timestamp later than or the same as msec. Use
         * {@link #SEEK_CLOSEST_SYNC} if one wants to seek to a sync frame
         * that has a timestamp closest to or the same as msec. Use
         * {@link #SEEK_CLOSEST} if one wants to seek to a frame that may
         * or may not be a sync frame but is closest to or the same as msec.
         * {@link #SEEK_CLOSEST} often has larger performance overhead compared
         * to the other options if there is no sync frame located at msec.
         * @throws IllegalStateException if the internal player engine has not been
         * initialized
         * @throws IllegalArgumentException if the mode is invalid.
         */
        public void seekTo(long msec, @SeekMode int mode) {
            if (mode < SEEK_PREVIOUS_SYNC || mode > SEEK_CLOSEST) {
                final String msg = "Illegal seek mode: " + mode;
                throw new IllegalArgumentException(msg);
            }
            // TODO: pass long to native, instead of truncating here.
            if (msec > Integer.MAX_VALUE) {
                Log.w(TAG, "seekTo offset " + msec + " is too large, cap to " + Integer.MAX_VALUE);
                msec = Integer.MAX_VALUE;
            } else if (msec < Integer.MIN_VALUE) {
                Log.w(TAG, "seekTo offset " + msec + " is too small, cap to " + Integer.MIN_VALUE);
                msec = Integer.MIN_VALUE;
            }
            _seekTo(msec, mode);
        }
  • 相关阅读:
    在WPF中应用弱事件模式
    MSTest DeploymentItemAttribute
    delegate, event
    zookeeper 开机启动197
    centos 7 安装solr7.3.0 配置mysql197
    solr7.4 centos7安装197
    centos 查看mysql数据库命令197
    bootstrapValidator验证197
    idea快捷键197
    sun.misc.Unsafe.park(Native Method)197
  • 原文地址:https://www.cnblogs.com/renhui/p/9584966.html
Copyright © 2011-2022 走看看