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
相关推荐
阿巴斯甜2 小时前
CameraX的使用:
android jetpack
阿巴斯甜3 小时前
Accompanist的使用:
android jetpack
阿巴斯甜3 小时前
Activity Result API 的使用:
android jetpack
阿巴斯甜3 小时前
DataStore的使用:
android jetpack
我命由我123451 天前
Android 开发问题:无法从存储库 “D:\keys\MyNotifications.jks“ 中读取密钥 MyNotifications.
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
BoomHe1 天前
Android (AAOS) 13 编译中间产物(Wifi Jar)
android·android studio·android jetpack
撩得Android一次心动2 天前
Android DataBinding 全面解析【源码篇2】
android·源码·android jetpack·databinding
我命由我123452 天前
Android 开发,getSystemService 警告信息:Must be one of: Context. POWER_SERVICE ...
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
alexhilton5 天前
Compose中初始加载逻辑究竟应该放在哪里?
android·kotlin·android jetpack