Media3 的使用

一、Media3 基础概述

1. 是什么

Media3 是 Google Jetpack 全新一代官方音视频全套库完全替代旧版 ExoPlayer ,是 Google 未来唯一官方音视频标准库,整合了播放、解码、缓存、后台播放、媒体会话、UI 控制器、DRM 加密、字幕、音轨切换 所有能力。底层依旧基于 ExoPlayer 内核,API 全面重构、更简洁、架构更优、完全兼容 Jetpack 全家桶、生命周期安全、完美适配 Compose

2. 历史与定位(必懂)

  • 旧:ExoPlayer(独立第三方库,谷歌开源)
  • 新:Media3 = Jetpack 官方化 ExoPlayer Google 已停止更新 ExoPlayer ,所有迭代全部迁移到 Media3 ,新项目必须用 Media3,不再用 ExoPlayer

3. 核心优势(对比 ExoPlayer 全部升级点)

  1. 官方 Jetpack 库,纳入 AndroidX 官方维护,版本统一、无版本碎片化
  2. API 大幅精简,链式调用更简洁,冗余 API 全部删除
  3. 架构分层清晰:播放器内核、UI、媒体会话、后台、缓存完全解耦
  4. 原生生命周期安全,绑定 Lifecycle,页面销毁自动暂停释放
  5. 完美原生支持 Compose,自带 Compose 专属播放组件
  6. 内置完整媒体会话(MediaSession) ,一键实现后台播放、锁屏控制、通知栏控制、耳机线控
  7. 内置完善缓存、自适应码率、HLS/DASH/MP4 全格式支持
  8. 自带官方完整 UI 控制器,无需自定义
  9. 包体积更小、性能更优、内存泄漏风险极低

4. 最新稳定版本(2026)

Media3 最新稳定版:1.7.0

最低兼容:Android 5.0(API 21) ,全机型覆盖

二、依赖引入(Module 级 build.gradle.kts,全套按需引入,直接复制)

Media3 模块化设计,按需引入依赖,不要全量引入,我按日常开发常用优先级拆分。

kotlin

kotlin 复制代码
// 统一版本
val media3Version = "1.7.0"

// 1. 核心播放器内核(必引,所有播放基础)
implementation("androidx.media3:media3-exoplayer:$media3Version")

// 2. 官方UI播放控制器(播放/暂停/进度条/全屏/快进,自带View控件)
implementation("androidx.media3:media3-ui:$media3Version")

// 3. 媒体会话(后台播放、锁屏、通知栏、耳机控制,音乐APP必引)
implementation("androidx.media3:media3-session:$media3Version")

// 4. 缓存模块(视频/音频本地缓存,网络播放必引)
implementation("androidx.media3:media3-datasource-cache:$media3Version")

// 5. Compose 专属扩展(Compose 页面播放必用,你重点需要)
implementation("androidx.media3:media3-compose:$media3Version")

// 6. 附加扩展(按需)
implementation("androidx.media3:media3-exoplayer-hls:$media3Version") // HLS流媒体增强
implementation("androidx.media3:media3-exoplayer-dash:$media3Version") // DASH流媒体
implementation("androidx.media3:media3-common:$media3Version") // 通用工具类

三、核心概念(先懂概念,代码不懵)

1. 核心类全解析

  1. ExoPlayer 播放器内核主体,Media3 核心,创建实例、播放控制、资源管理,依旧保留 ExoPlayer 类名,但全部是 Media3 新 API。
  2. MediaItem 媒体数据模型,封装单个音视频资源 (网络 url、本地文件、标题、封面、时长、字幕),所有播放源统一用 MediaItem
  3. PlayerViewView 体系官方 UI 播放视图(旧 ExoPlayer 的 PlayerView),自带完整控制器、画面渲染、手势拖动、进度条。
  4. MediaSession 媒体会话管理器,后台播放灵魂,实现:后台进程播放、通知栏控件、锁屏界面控制、耳机按键、系统媒体中心联动。
  5. CacheDataSource网络资源本地缓存,重复播放不重复下载。
  6. Media3 Compose 组件 PlayerSurfaceMediaPlayerControl、原生 Compose 播放渲染,无 AndroidView 嵌套。

2. 支持媒体格式

  • 本地:MP4、MP3、M4A、WAV
  • 网络:HTTP 普通视频、HLS(m3u8)、DASH 自适应流媒体
  • 额外:字幕 (SRT/ASS)、多音轨、DRM 数字版权加密

3. 固定开发流程(所有项目通用公式)

plaintext

markdown 复制代码
1. 权限声明(网络/存储)
2. 构建 ExoPlayer 播放器实例
3. 构建 MediaItem 播放源
4. 绑定播放视图 + 设置播放参数
5. 播放控制(播放/暂停/进度/切换)
6. 页面生命周期管理(onStart初始化、onStop释放)
7. 扩展:缓存、后台媒体会话、Compose适配

四、权限配置(AndroidManifest.xml,必须)

xml

xml 复制代码
<!-- 网络权限(网络音视频必加) -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 后台播放权限(安卓12+后台进程) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<!-- 本地存储读取(本地视频/缓存) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

五、View 体系完整基础播放(Kotlin Activity,最基础完整版,可直接复制)

包含:播放器创建、网络视频播放、播放 / 暂停、进度监听、生命周期安全释放、完整标准写法

1. XML 布局

xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- Media3 官方播放UI控件(自带全部控制器) -->
    <androidx.media3.ui.PlayerView
        android:id="@+id/playerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

2. Activity 完整代码(标准最佳实践)

kotlin

kotlin 复制代码
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.media3.common.MediaItem
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView

class Media3BasicActivity : AppCompatActivity() {
    // 播放器实例
    private var exoPlayer: ExoPlayer? = null
    private lateinit var playerView: PlayerView

    // 网络测试视频地址(m3u8流媒体/普通mp4通用)
    private val videoUrl = "https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_1MB.mp4"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_media3_basic)
        playerView = findViewById(R.id.playerView)
    }

    // ========== 页面可见,初始化播放器 ==========
    override fun onStart() {
        super.onStart()
        initPlayer()
    }

    // 初始化播放器核心方法
    private fun initPlayer() {
        // 1. 构建播放器实例(Media3 全新简洁构建器)
        exoPlayer = ExoPlayer.Builder(this)
            .build()

        // 2. 绑定播放器到UI视图
        playerView.player = exoPlayer

        // 3. 构建媒体播放源 MediaItem
        val mediaItem = MediaItem.fromUri(videoUrl)

        // 4. 设置播放源 + 准备播放
        exoPlayer?.setMediaItem(mediaItem)
        exoPlayer?.prepare() // 预加载
        exoPlayer?.playWhenReady = true // 自动播放
    }

    // ========== 页面不可见,暂停播放 ==========
    override fun onStop() {
        super.onStop()
        // 页面退到后台暂停,不销毁
        exoPlayer?.playWhenReady = false
    }

    // ========== 页面销毁,完全释放资源(防内存泄漏) ==========
    override fun onDestroy() {
        super.onDestroy()
        exoPlayer?.release()
        exoPlayer = null
        playerView.player = null
    }
}

基础 API 说明(常用播放控制)

kotlin

scss 复制代码
exoPlayer?.play() // 播放
exoPlayer?.pause() // 暂停
exoPlayer?.seekTo(10000) // 拖动进度(毫秒)
exoPlayer?.previous() // 上一个
exoPlayer?.next() // 下一个
exoPlayer?.duration // 总时长(ms)
exoPlayer?.currentPosition // 当前播放位置
exoPlayer?.playbackState // 播放状态(空闲/准备/播放/暂停/结束)

六、进阶常用功能(项目高频,全部完整代码)

1. 播放列表(多个视频 / 音频连续轮播)

kotlin

less 复制代码
// 多个播放源
val mediaItems = listOf(
    MediaItem.fromUri("url1"),
    MediaItem.fromUri("url2"),
    MediaItem.fromUri("url3")
)
// 设置播放列表
exoPlayer?.setMediaItems(mediaItems)
exoPlayer?.prepare()
exoPlayer?.playWhenReady = true

2. 全局网络缓存(所有视频本地缓存,重复播放不走网络)

Media3 内置完整缓存,一行配置全局缓存,无需额外管理

kotlin

kotlin 复制代码
import androidx.media3.datasource.cache.Cache
import androidx.media3.datasource.cache.CacheDataSource
import androidx.media3.datasource.cache.SimpleCache
import androidx.media3.datasource.FileDataSource
import java.io.File

// 全局单例缓存(建议写在Application,全局统一)
private lateinit var mediaCache: Cache

// 初始化缓存(Application onCreate)
private fun initMedia3Cache() {
    // 缓存目录
    val cacheDir = File(this.cacheDir, "media3_cache")
    // 缓存大小 500M
    mediaCache = SimpleCache(cacheDir, SimpleCache.NoEvictor())

    // 缓存数据源工厂
    val cacheDataSourceFactory = CacheDataSource.Factory()
        .setCache(mediaCache)
        .setUpstreamDataSourceFactory(FileDataSource.Factory())
        .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS)

    // 构建播放器时传入缓存工厂
    exoPlayer = ExoPlayer.Builder(this)
        .setMediaSourceFactory(cacheDataSourceFactory) // 绑定全局缓存
        .build()
}

3. 后台播放 + 通知栏 + 锁屏控制(音乐 APP 核心,MediaSession)

这是 Media3 对比旧 ExoPlayer 最大升级,官方内置媒体会话,极简实现后台全能力,无需自己写 Service、通知、广播。

kotlin

kotlin 复制代码
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import androidx.media3.session.SessionToken

// 1. 清单注册媒体服务(自动后台生命周期)
<service
    android:name="androidx.media3.session.MediaSessionService"
    android:exported="false">
    <intent-filter>
        <action android:name="android.media.browse.MediaBrowserService" />
    </intent-filter>
</service>

// 2. 代码绑定 MediaSession
private lateinit var mediaSession: MediaSession

private fun initMediaSession() {
    mediaSession = MediaSession.Builder(this, exoPlayer)
        .build()

    // 获取会话令牌,系统自动关联通知、锁屏、耳机线控
    val sessionToken = mediaSession.sessionToken
    playerView.setSessionToken(sessionToken)
}

效果

  • App 退到后台、锁屏、应用切后台进程,音频持续播放不中断
  • 通知栏自带播放 / 暂停 / 切歌控件
  • 锁屏界面显示封面、标题、播放控制
  • 耳机线控(单击暂停 / 播放、双击下一曲)全部自动生效

4. 播放状态监听(加载、缓冲、播放完成、错误)

kotlin

kotlin 复制代码
exoPlayer?.addListener(object : Player.Listener {
    // 播放状态变化
    override fun onPlaybackStateChanged(playbackState: Int) {
        super.onPlaybackStateChanged(playbackState)
        when(playbackState) {
            Player.STATE_IDLE -> {} // 空闲
            Player.STATE_BUFFERING -> {} // 缓冲加载中
            Player.STATE_READY -> {} // 准备完成可播放
            Player.STATE_ENDED -> {} // 播放结束
        }
    }

    // 播放结束回调
    override fun onPlaybackComplete() {
        super.onPlaybackComplete()
    }

七、Compose 中 Media3 完整使用(你重点学习部分,官方原生 Compose 组件)

Media3 官方原生提供 Compose 专属库 media3-compose无需 AndroidView 嵌套、无需兼容层、纯 Compose 状态驱动、生命周期安全,搭配你之前学的全部 Compose 体系完美适配。

完整纯 Compose 播放代码

kotlin

kotlin 复制代码
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.media3.common.MediaItem
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.compose.PlayerSurface
import androidx.media3.ui.compose.PlayerControls

@Composable
fun Media3ComposePlayer() {
    val context = LocalContext.current
    // 记住播放器实例(Compose 状态持有,页面重建不重复创建)
    val exoPlayer = remember {
        ExoPlayer.Builder(context)
            .build()
            .apply {
                val mediaItem = MediaItem.fromUri("https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_1MB.mp4")
                setMediaItem(mediaItem)
                prepare()
                playWhenReady = true
            }
    }

    // Compose 页面销毁自动释放播放器(无需手动onDestroy)
    DisposableEffect(Unit) {
        onDispose {
            exoPlayer.release()
        }
    }

    // 纯Compose视频渲染画布(官方PlayerSurface)
    PlayerSurface(
        player = exoPlayer,
        modifier = Modifier.fillMaxSize()
    ) {
        // 内置Compose播放控制器(播放/暂停/进度条)
        PlayerControls(player = exoPlayer)
    }
}

Compose 优势

  1. 完全原生 Compose,无 AndroidViewBinding 嵌套
  2. remember + DisposableEffect 自动生命周期管理,自动释放无内存泄漏
  3. 状态和 Compose 数据流统一,可自定义 Compose 风格控制器
  4. 完美适配你之前学的 Accompanist、Hilt、Navigation 全套 Jetpack

八、Media3 与 旧 ExoPlayer 全方位对比(面试必背)

表格

对比项 ExoPlayer(旧) Media3(新)
库归属 谷歌独立开源库 Jetpack AndroidX 官方库
维护状态 已停止更新、废弃 官方主力持续迭代
API 设计 旧版繁琐、类臃肿 全新精简 API、链式构建、架构分层
Compose 支持 无原生支持,需嵌套 AndroidView 官方原生 media3-compose 专属组件
媒体后台播放 需手动写 Service、MediaSession 复杂配置 内置 MediaSession,一行绑定,自带通知 / 锁屏
缓存 配置繁琐 极简全局缓存配置
生命周期 需手动管理释放,易内存泄漏 完善生命周期绑定,Compose 自动释放
包体积 较大 精简内核,体积更小
项目选型 新项目禁止使用 新项目唯一官方标准音视频库
底层内核 原始内核 完全继承 ExoPlayer 内核,所有能力 100% 兼容

九、高频踩坑大全(开发必避)

  1. 播放器内存泄漏 严格遵循:onStart 初始化、onStop 暂停、onDestroy 调用 release();Compose 用 DisposableEffect 自动释放。
  2. 后台播放被杀、安卓 12 + 后台权限 必须添加 FOREGROUND_SERVICE_MEDIA_PLAYBACK 权限 + 注册 MediaSessionService
  3. 网络视频无法播放 清单加 INTERNET 权限;http 明文请求需在 Application 配置 android:usesCleartextTraffic="true"
  4. 缓存不生效 必须全局构建 SimpleCache + CacheDataSource.Factory,构建播放器时传入 setMediaSourceFactory
  5. 播放 m3u8 流媒体黑屏 / 无法播放 引入 media3-exoplayer-hls 依赖,官方自动适配 HLS。
  6. 页面切换播放器重复创建 Activity 把 ExoPlayer 作为成员变量;Compose 用 remember 单例持有。
  7. PlayerView 画面拉伸控件默认自适应缩放,无需额外配置,官方自动适配宽高比。

十、面试满分极简背诵版

  1. Media3 是什么 Google Jetpack 新一代官方音视频库,完全替代 ExoPlayer,底层基于 ExoPlayer 内核,API 重构升级,官方永久维护。
  2. 核心模块 内核ExoPlayer、媒体模型MediaItem、UI 视图PlayerView、媒体会话MediaSession、缓存、Compose 扩展。
  3. 核心优势官方 Jetpack、API 极简、原生 Compose 支持、一键后台播放(通知 / 锁屏 / 线控)、内置全局缓存、生命周期安全、全格式流媒体兼容。
  4. 核心流程创建 ExoPlayer 实例 → 构建 MediaItem 播放源 → 绑定 UI 视图 → prepare 预加载 → 播放控制 → 生命周期释放。
  5. 与 ExoPlayer 关系Media3 是 ExoPlayer 的官方升级官方版,ExoPlayer 已废弃,新项目全部使用 Media3。

十一、项目最终最佳实践总结

  1. 所有新项目音视频开发,全部统一用 Media3,彻底放弃 ExoPlayer。
  2. 依赖只按需引入:核心 + UI + 会话 + 缓存 + Compose 扩展即可。
  3. View 开发用 PlayerView,Compose 开发用原生 PlayerSurface
  4. 音频类 APP 必须接入 MediaSession 实现完整后台播放能力。
  5. 网络播放统一配置全局缓存,节省流量。
  6. 严格遵守生命周期释放规范,杜绝内存泄漏。

十二、是否需要三方控件

1 、这些功能 → 完全不需要三方控件

网络视频 / 本地视频 播放

HLS、DASH 流媒体(m3u8)

自动缓存、无缝切换、循环播放

播放、暂停、快进、快退、进度条、全屏

音量调节、亮度调节、手势

多码率自适应、音轨切换、字幕

后台播放、通知栏控制、锁屏控制、耳机线控

播放列表、连续播放、自动播放下一个

Compose 原生播放组件(不用嵌套 AndroidView)

生命周期安全、自动释放、无内存泄漏

👉 以上所有,Media3 原生自带,一行三方都不用!

2、 需要 短视频滑动(抖音 / 快手 效果)

Media3 不带上下滑切换视频的布局→ 需要自己写,或用轻量三方:

  • TikTokLayout
  • VerticalViewPager
  • Compose Pager

注意:播放器还是 Media3,只是外层滑动布局用三方!

3、 需要 超级复杂的自定义 UI

比如:

  • 多层弹幕
  • 连播动画
  • 广告弹窗
  • 贴纸、水印
  • 特效滤镜

→ 这些播放器本身不负责 ,需要自己写或三方 UI 组件。播放器内核依然是 Media3。

4、需要 视频剪辑、拼接、变速、美颜

Media3 只负责播放,不负责编辑→ 必须用第三方编辑库:

  • FFmpeg
  • Mp4Composer
  • 各种音视频编辑 SDK
5、需要 直播(RTSP、RTMP、UDP 等)

Media3 支持部分,但不强→ 常用:

  • ijkPlayer
  • Tencent LiteAV
  • 阿里云直播 SDK
相关推荐
李斯维6 小时前
从历史的角度看 Android 软件架构
android·架构·android jetpack
alexhilton1 天前
Android车载OS中的Remote Compose
android·kotlin·android jetpack
alexhilton7 天前
使用Android Archive进行打包
android·kotlin·android jetpack
Junerver10 天前
我写了一个 Compose Multiplatform 组件库,你可能会用到
kotlin·android jetpack
我命由我1234512 天前
Jetpack Room - Room 查询返回列表无需判空、LIKE 关键字
android·java·开发语言·java-ee·android jetpack·android-studio·android runtime
QING61813 天前
Kotlin 日常开发常用语法糖整理 —— 速记
android·kotlin·android jetpack
我命由我1234513 天前
Android 开发问题:EditText 控件的 android:imeOptions=“actionDone“ 属性不生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
我命由我1234513 天前
Android 开发问题:获取到的 Android ID 发生了变化
android·java·开发语言·java-ee·android studio·android jetpack·android runtime
我命由我1234513 天前
Android 开发问题:Unable to find explicit activity class
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
我命由我1234513 天前
Android 开发问题:全局的主题颜色设置,导致 CheckBox 控件在勾选状态下不显示样式
android·java·开发语言·java-ee·intellij-idea·intellij idea·android jetpack