Android16进阶之获取播放位置MediaPlayer.getCurrentPosition调用流程与实战(二百二十八)

简介: CSDN博客专家、《Android系统多媒体进阶实战》作者

博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址:Audio工程师进阶系列原创干货持续更新中...... 】🚀
Android多媒体专栏地址:多媒体系统工程师系列原创干货持续更新中...... 】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课 🚀
专题四:Android15快速自定义与集成音效实战课 🚀
专题五:Android15音频策略实战课 🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例) 🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
更多原创,欢迎关注:Android系统攻城狮

🍉🍉🍉文章目录🍉🍉🍉

      • [🌻1. 前言](#🌻1. 前言)
      • [🌻2. 用法与应用场景](#🌻2. 用法与应用场景)
      • [🌻3. 调用流程剖析](#🌻3. 调用流程剖析)
        • [3.1 核心步骤](#3.1 核心步骤)
        • [3.2 涉及核心时序图](#3.2 涉及核心时序图)
      • [🌻4. 实战应用案例](#🌻4. 实战应用案例)
      • [🌻5. 用法总结](#🌻5. 用法总结)

🌻1. 前言

本篇目的:Android16音频深度解析之MediaPlayer.getCurrentPosition调用流程与实战。

在 Android 多媒体开发中,实时获取音频或视频的播放进度是实现进度条同步、断点续播以及音画同步逻辑的基础。MediaPlayer.getCurrentPosition 是应用层访问频率最高的接口之一,它直接反映了播放引擎当前的渲染时间戳。


🌻2. 用法与应用场景

MediaPlayer.getCurrentPosition 方法用于获取当前媒体文件的播放位置,返回值为毫秒(ms)。

  • 用法说明 :该方法可以在播放器处于 StartedPausedPreparedPlaybackCompleted 状态时调用。
  • 运行结果 :返回一个 int 类型的数值,表示从文件起始点到当前播放点的时长。
  • 应用场景
  1. 进度条更新 :配合 HandlerTimer 定时调用,驱动 UI 层的 SeekBar 移动。
  2. 播放进度持久化:在应用进入后台或 Activity 销毁时记录当前位置,以便下次精准续播。
  3. 打点标注:在特定时间点触发特定的业务逻辑(如歌词同步展示或视频广告弹出)。

🌻3. 调用流程剖析

3.1 核心步骤
  1. Java 层入口 :应用调用 MediaPlayer.getCurrentPosition()。Java 框架层首先检查 Native 层的 MediaPlayer 对象是否已初始化,随后进入 JNI。
  2. JNI 与 Native 转发 :通过 android_media_MediaPlayer_getCurrentPosition 将请求转发至 mediaplayer.cpp
  3. MediaServer 通讯 :MediaPlayer 的 Client 端通过 Binder 机制向 MediaServer 进程发送查询请求。
  4. NuPlayer 获取时钟NuPlayer 引擎并不会实时计算时间,而是向其内部的 MediaClock 组件查询。MediaClock 维护了一个基于系统时钟(System Clock)和音频渲染时间(Audio Sink Time)的参考轴。
  5. 音频戳同步 :在音频播放场景下,引擎会根据 AudioTrack 实际写出的采样数以及底层的硬件延迟(Latency)来计算最真实的播放位置,以确保获取到的数值与用户听到的声音完全匹配。
3.2 涉及核心时序图

AudioTrack / HAL MediaClock NuPlayer Engine MediaPlayer Native MediaPlayer Java 应用代码层 AudioTrack / HAL MediaClock NuPlayer Engine MediaPlayer Native MediaPlayer Java 应用代码层 调用 getCurrentPosition() 调用 native_getCurrentPosition 通过 Binder 请求当前位置 查询当前媒体时钟戳 获取已播放音频帧数与延迟 返回物理渲染进度 返回同步后的时间戳 转换并返回毫秒数 返回执行结果 获取当前播放进度 (ms)


🌻4. 实战应用案例

本案例展示了如何通过一个定时任务轮询 getCurrentPosition,并结合健壮的状态处理更新进度。

java 复制代码
public class PlaybackProgressMonitor {
    private MediaPlayer mediaPlayer;
    private Handler progressHandler = new Handler(Looper.getMainLooper());
    private static final int UPDATE_INTERVAL = 1000; // 每秒更新一次

    public void startMonitoring(MediaPlayer mp) {
        this.mediaPlayer = mp;
        progressHandler.post(progressRunnable);
    }

    private Runnable progressRunnable = new Runnable() {
        @Override
        public void run() {
            if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                try {
                    // 1. 获取当前毫秒进度
                    int currentPos = mediaPlayer.getCurrentPosition();
                    
                    // 2. 获取总时长
                    int duration = mediaPlayer.getDuration();
                    
                    // 3. 计算进度并打印(或更新 UI)
                    float progress = (float) currentPos / duration * 100;
                    System.out.println(String.format("播放进度: %.2f%% [位置: %d ms]", progress, currentPos));
                    
                } catch (IllegalStateException e) {
                    // 处理在错误状态下调用 getCurrentPosition 的情况
                    System.err.println("播放器状态异常,停止进度轮询");
                    return;
                }
            }
            // 循环调用
            progressHandler.postDelayed(this, UPDATE_INTERVAL);
        }
    };

    public void stopMonitoring() {
        progressHandler.removeCallbacks(progressRunnable);
        mediaPlayer = null;
    }
}

🌻5. 用法总结

调用层级 核心职责 关键报错/结果
应用框架层 维护播放器状态机并分发 JNI 调用 若对象已释放抛出 IllegalStateException
系统服务层 通过 Binder 进行跨进程通信 指令下发至 MediaServer 进程
引擎处理层 MediaClock 组件检索基准时间戳 确保返回的时间轴具有连续性
音频渲染层 结合 AudioTrack 采样数与硬件 Latency 修正 提供物理意义上的真实播放位置
硬件抽象层 提供底层的缓存延迟数据(Buffer Delay) 延迟数据决定了进度查询的精度
相关推荐
REDcker4 天前
WebCodecs VideoDecoder 的 hardwareAcceleration 使用
前端·音视频·实时音视频·直播·webcodecs·videodecoder
gihigo19984 天前
基于TCP协议实现视频采集与通信
网络协议·tcp/ip·音视频
山河君4 天前
四麦克风声源定位实战:基于 GCC-PHAT + 最小二乘法实现 DOA
算法·音视频·语音识别·信号处理·最小二乘法·tdoa
音视频牛哥4 天前
Android平台RTMP/RTSP超低延迟直播播放器开发详解——基于SmartMediaKit深度实践
android·人工智能·计算机视觉·音视频·rtmp播放器·安卓rtmp播放器·rtmp直播播放器
qq_416276424 天前
通用音频表征的对比学习
学习·音视频
美狐美颜sdk4 天前
Android全局美颜sdk实现方案详解
人工智能·音视频·美颜sdk·视频美颜sdk·美狐美颜sdk
EasyDSS4 天前
私有化部署EasyDSS视频点播能力:全链路视频技术赋能,打造企业级视听新体验
音视频·hls·m3u8·点播技术·智能转码
qq_416276424 天前
DeLoRes——一种通用的音频表征学习新方法(DeLoRes(基于 Barlow Twins 的冗余最小化方法)
学习·音视频
Android系统攻城狮4 天前
Android16进阶之MediaPlayer.isLooping调用流程与实战(二百三十二)
android16·音频进阶·android hal·audio hal·多媒体进阶
Android系统攻城狮4 天前
Android16进阶之MediaPlayer.setLooping调用流程与实战(二百三十一)
android16·音频进阶·android hal·audio hal·多媒体进阶