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);
        }
  • 相关阅读:
    HDU 5528 Count a * b 欧拉函数
    HDU 5534 Partial Tree 完全背包
    HDU 5536 Chip Factory Trie
    HDU 5510 Bazinga KMP
    HDU 4821 String 字符串哈希
    HDU 4814 Golden Radio Base 模拟
    LA 6538 Dinner Coming Soon DP
    HDU 4781 Assignment For Princess 构造
    LA 7056 Colorful Toy Polya定理
    LA 6540 Fibonacci Tree
  • 原文地址:https://www.cnblogs.com/renhui/p/9584966.html
Copyright © 2011-2022 走看看