
MediaPlayer 撑不住了用 ExoPlayer 从零拼一台模块化播放器【免费下载链接】ExoPlayerAn extensible media player for Android项目地址: https://gitcode.com/gh_mirrors/exop/ExoPlayer你有没有这种经历需求文档上写着支持多码率、字幕、倍速、水印你下意识打开MediaPlayer然后发现自己卡在换音轨要重启播放没有滤镜接口缓冲策略改不了的泥潭里。其实 Google 早就给了答案——ExoPlayer一个为 Android 打造的可拼装应用级媒体播放器。它不替你做所有事而是把播放这件事拆成一个个可替换的零件让你像拼车一样自定义每一环。接下来这篇 ExoPlayer 实战教程就带你从零开始组装它。✅ 学会用 4 行代码跑起第一个播放器 ✅ 看懂 ExoPlayer 模块化架构与核心组件 ✅ 掌握添加字幕、倍速、画中画等增强玩法 ✅ 拿到滤镜、直播、离线下载的进阶路线图 ✅ 避开新手最容易踩的 6 个坑先看成品一个播放器能玩到什么程度动手前先看看 ExoPlayer 的下限和上限。下限是原始视频帧一个再普通不过的室内画面色彩、构图原封不动。上限则是同一帧画面可以被灰度化、旋转 90 度、叠加文字水印甚至叠加 Logo——全程不需要额外解码只是 GPU 层面的一次次加工。这些处理能力不是魔改出来的而是模块化设计的自然结果。想理解它为什么这么能打得先看它的内部构造。一辆车而不是一台录音机传统MediaPlayer是一台一体化录音机按下播放键从解封装到解码到出声全在里面你改不了任何环节。ExoPlayer 则是一辆可以拆换零件的车组件大白话解释干什么用MediaSource油路和进气管定义媒体从哪来负责加载和读取Renderer发动机汽缸把音/视频数据解码成能听能看的内容TrackSelector变速箱从多个轨道里挑合适的分辨率、语言LoadControl油门踏板决定缓冲多少、什么时候继续拉数据这些零件在创建播放器时通过构造器注入进去想换哪块换哪块。默认配件足够好用但当你想要自定义视频滤镜这种标准播放器永远给不了的功能时只要换一个实现了Renderer接口的零件即可。整个设计哲学就一句话把能力开放出来而不是替你锁死。搭骨架用 4 行代码跑起最小播放器先别急着自定义零件我们从最小可用版本开始。在build.gradle里引入依赖implementation com.google.android.exoplayer:exoplayer:2.19.1exoplayer是一个全家桶坐标内部会自动带入 core、ui、datasource 等全部模块。想精确控制体积也可以按需拆开引入implementation com.google.android.exoplayer:exoplayer-core:2.19.1 implementation com.google.android.exoplayer:exoplayer-hls:2.19.1 implementation com.google.android.exoplayer:exoplayer-ui:2.19.1然后在 Activity 里写核心逻辑ExoPlayer player new ExoPlayer.Builder(context).build(); player.setMediaItem(MediaItem.fromUri(https://example.com/video.mp4)); player.prepare(); player.play();这段代码在做三件事Builder用默认组件拼装出一台标准车setMediaItem指定要播的媒体prepare()进入准备状态后play()开始播放。跑起来你就能听到声音但还看不到画面——因为画面需要一块显示屏。盖主体把画面接到屏幕上ExoPlayer 本身不碰任何 View它只往一个Surface或TextureView上输出画面。最简单的做法是用现成的StyledPlayerView它还自带播放/暂停按钮和进度条com.google.android.exoplayer2.ui.StyledPlayerView android:idid/player_view android:layout_widthmatch_parent android:layout_heightmatch_parent/StyledPlayerView playerView findViewById(R.id.player_view); playerView.setPlayer(player); // 把播放器和视图绑定绑定之后画面、控制条、横竖屏切换全都自动接管。如果你嫌自带皮肤丑ExoPlayer 允许通过setControllerLayoutRes或覆写布局来换皮参考library/ui/src/main/res/layout/下的模板即可。 至此你已经拥有一个能播、能暂停、能拖进度、能调音量的一体化播放器代码不到 20 行。这是所有高级玩法的地基。精装修清单播放、倍速、字幕与画面变换地基打好了我们来逐级加料。播放清单把多个视频串成列表一行搞定MediaItem first MediaItem.fromUri(firstUri); MediaItem second MediaItem.fromUri(secondUri); player.setMediaItems(List.of(first, second), /* startIndex */ 0, /* startPositionMs */ 0);清单支持自动续播、循环、随机播放源码逻辑在library/core/src/main/java/com/google/android/exoplayer2/PlaylistTimeline.java有空可以读读它的时间线拼接思路。倍速与音轨播放中随时调速、切换语言轨道player.setPlaybackSpeed(1.5f); // 1.5 倍速 Tracks tracks player.getCurrentTracks(); player.setTrackSelectionParameters( player.getTrackSelectionParameters() .buildUpon() .setPreferredAudioLanguage(zh) .build());画面变换想给画面加灰度或反色滤镜官方提供了RgbFilter这类现成效果类其内部是一个 4x4 颜色矩阵灰度滤镜用的是 BT.709 亮度系数0.2126 / 0.7152 / 0.0722见library/effect/src/main/java/com/google/android/exoplayer2/effect/RgbFilter.java。把它喂给DefaultVideoFrameProcessor.Factory().setGlEffects(...)就能在渲染流水线里插入着色器处理实时改变每一帧的颜色。直播流ExoPlayer 对 DASH、HLS、RTSP、SmoothStreaming 全覆盖。直播场景下它把时间线建模成直播窗口只有窗口内的内容是可播可追的配合Player.getCurrentLiveOffset()可以拿到延迟量。示意图见 docs 目录下的docs/images/live-window.png进阶技巧与避坑指南现象原因对策minSdkVersion ≤ 20构建报错方法数超限开启 multidex播放 https 内容闪黑依赖 Java 8 特性未开在compileOptions里打开 Java 8明文 http 地址被拒Android 默认禁明文配置networkSecurityConfig或加 usesCleartextTraffic切后台后继续发声未释放/未暂停在onPause暂停、onStop释放播一会就卡轨道自适应策略保守调DefaultTrackSelector参数或带宽估计换了播放器没反应旧实例没release()重建前先释放旧实例并解绑 view排错核心看日志给播放器挂一个AnalyticsListener把事件、异常、格式信息都打出来比瞎猜快得多相关写法参考demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java。收尾清单与下一步现在回头看看你其实已经掌握了一条完整的播放器组装链路理解 ExoPlayer 的零件可替换设计哲学用ExoPlayer.Builder跑通最小播放器用StyledPlayerView完成画面与控制器绑定掌握清单、倍速、音轨切换、滤镜增强熟悉 6 个高频坑的对应解法想继续深入有三条路线一是通读library/effect/里的 OpenGL 效果实现自己写滤镜算法二是研究docs/transforming-media.md学习用 Transformer 做视频转码、去音轨三是看extensions/下的 ima、cast、workmanager 扩展给播放器加上广告、投屏和后台下载能力。如果你在实战中踩过某个奇葩的播放器 bug欢迎在评论区把它曝光出来人多力量大说不定你的坑就是别人的坎。下一期我们聊聊如何给这个播放器接入可跳过的贴片广告感兴趣的话点个关注不迷路。【免费下载链接】ExoPlayerAn extensible media player for Android项目地址: https://gitcode.com/gh_mirrors/exop/ExoPlayer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考