FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
Android早期的MediaPlayer控件对于网络视频的兼容性很差,所以后来单独推出了Exoplayer库增强支持网络视频,在《Android Studio开发实战:从零基础到App上线(第3版)》一书第14章的“14.3.3 新型播放器ExoPlayer”就详细介绍了Exoplayer库的详细用法。
现在Android官方再次升级Exoplayer,并将其纳入了Jetpack的Media3第三代媒体库,作为音视频相关操作的统一处理引擎。升级后的Exoplayer就成为Media3的统一媒体播放引擎,提供了音频和视频播放的应用级组件,意欲在音视频渲染方向上一统江湖。
根据Android官网的介绍,ExoPlayer还摆脱设备和操作系统碎片化问题,让App代码以一致的方式运行于整个Android生态系统中。因为Media3是个很新很新的Jetpack库,所以它对开发环境要求比较高,需满足下列条件才能正常引入Media3。
1、开发工具要选用Android Studio Jellyfish(小水母版本)或更高版本。
2、Gradle版本不低于8.6。
3、App模块的build.gradle里面compileSdk和targetSdk要升级到34或者更高版本。
根据上述条件准备好了开发环境,再按照以下描述引入Media3的ExoPlayer库,详细步骤说明如下。
一、修改模块的build.gradle
在build.gradle的dependencies节点内部补充下面的导包语句,把ExoPlayer用到的相关库都加进来。
implementation "androidx.media3:media3-exoplayer:1.4.0"
implementation "androidx.media3:media3-exoplayer-hls:1.4.0"
implementation "androidx.media3:media3-exoplayer-rtsp:1.4.0"
implementation "androidx.media3:media3-ui:1.4.0"
implementation "androidx.media3:media3-common:1.4.0"
implementation "androidx.media3:media3-session:1.4.0"
implementation "androidx.media3:media3-datasource:1.4.0"
implementation "androidx.media3:media3-datasource-rtmp:1.4.0"
二、编辑播放界面的布局文件
打开播放界面的XML布局文件,给根布局添加如下的属性配置:
xmlns:app="http://schemas.android.com/apk/res-auto"
接着在布局内部添加来自ExoPlayer库的PlayerView控件节点,举例如下:
<!-- use_controller是否显示控制栏,show_timeout控制栏的消失间隔,show_buffering是否显示缓冲区,resize_mode大小调整模式 -->
<androidx.media3.ui.PlayerView
android:id="@+id/pv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:show_buffering="always"
app:show_timeout="5000"
app:use_controller="true"
app:resize_mode="fit"/>
三、活动页面代码增加ExoPlayer的处理代码
首先补充下面一行代码声明PlayerView对象:
private ExoPlayer mPlayer; // 声明一个新型播放器对象
接着在onCreate方法里面补充以下代码,获取PlayerView对象,并对其设置ExoPlayer的播放器对象:
PlayerView pv_content = findViewById(R.id.pv_content);
mPlayer = new ExoPlayer.Builder(this).build();
pv_content.setPlayer(mPlayer); // 设置播放器视图的播放器对象
然后添加下面的播放方法,开始播放指定链接的网络视频。
// 播放视频
private void playVideo(Uri uri) {
DataSource.Factory factory = new DefaultDataSource.Factory(this);
// 创建指定地址的媒体对象
MediaItem videoItem = new MediaItem.Builder().setUri(uri).build();
// 基于工厂对象和媒体对象创建媒体来源
MediaSource videoSource;
if (uri.getPath().endsWith("m3u8")) { // hls链接
videoSource = new HlsMediaSource.Factory(factory)
.createMediaSource(videoItem);
} else if (uri.getPath().startsWith("rtsp")) { // rtsp链接
videoSource = new RtspMediaSource.Factory()
.createMediaSource(videoItem);
} else if (uri.getPath().startsWith("rtmp")) { // rtmp链接
videoSource = new ProgressiveMediaSource.Factory(new RtmpDataSource.Factory())
.createMediaSource(videoItem);
} else { // 其他链接(http开头或https开头的普通视频链接)
videoSource = new ProgressiveMediaSource.Factory(factory)
.createMediaSource(videoItem);
}
mPlayer.setMediaSource(videoSource); // 设置播放器的媒体来源
mPlayer.prepare(); // 播放器准备就绪
mPlayer.play(); // 播放器开始播放
}
从上述的播放代码可知,这里用到了ExoPlayer的四种播放形式,分别为:播放HLS链接、播放RTMP链接、播放RTSP链接、播放普通网络视频。
四、给AndroidManifest.xml补充互联网访问权限
打开AndroidManifest.xml,添加下面的互联网权限配置:
<uses-permission android:name="android.permission.INTERNET" />
最后编译运行App,在真机上看到的播放器效果如下图所示。

可见成功把Media3的ExoPlayer库跑了起来,并且正常播放网络视频。
更多详细的FFmpeg开发知识参见《FFmpeg开发实战:从零基础到短视频上线》一书。
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频的更多相关文章
- FFmpeg开发笔记(十):ffmpeg在ubuntu上的交叉编译移植到海思HI35xx平台
FFmpeg和SDL开发专栏(点击传送门) 上一篇:<FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放>下一篇:敬请期待 前言 将ffmpeg移植到海思H ...
- .net开发笔记(十六) 对前部分文章的一些补充和总结
补充有两个: 一个是系列(五)中讲到的事件编程(网址链接),该文提及到了事件编程的几种方式以及容易引起的一些异常,本文补充“多线程事件编程”这一块. 第二个是前三篇博客中提及到的“泵”结构在编程中的应 ...
- 论文阅读笔记五十六:(ExtremeNet)Bottom-up Object Detection by Grouping Extreme and Center Points(CVPR2019)
论文原址:https://arxiv.org/abs/1901.08043 github: https://github.com/xingyizhou/ExtremeNet 摘要 本文利用一个关键点检 ...
- 安卓开发笔记(十六):'Request(okhttp3.Request.Builder)' has private access in 'okhttp3.Request
当出现了'Request(okhttp3.Request.Builder)' has private access in 'okhttp3.Request的错误的时候,实际上是我们在写代码的时候少打了 ...
- Java开发笔记(十六)非此即彼的条件分支
前面花了大量篇幅介绍布尔类型及相应的关系运算和逻辑运算,那可不仅仅是为了求真值或假值,更是为了通过布尔值控制流程的走向.在现实生活中,常常需要在岔路口抉择走去何方,往南还是往北,向东还是向西?在Jav ...
- Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件
前言 上一篇已经将himpp套入qt的基础上进行开发.那么qt中拿到frame则是很关键的交互,这是qt与海思可能编解码交叉开发的关键步骤. 受限制 因为直接配置sample的vi比较麻烦 ...
- FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...
- FFmpeg开发笔记(四):ffmpeg解码的基本流程详解
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放
前言 ffmpeg播放rtsp网络流和摄像头流. Demo 使用ffmpeg播放局域网rtsp1080p海康摄像头:延迟0.2s,存在马赛克 使用ffmpeg播放网络rtsp文件流 ...
随机推荐
- 如何实现nvidia显卡的cuda的多kernel并发执行???
相关: CPU端多进程/多线程调用CUDA是否可以加速??? 参考: <CUDA C 编程指南>导读 https://developer.nvidia.com/blog/gpu-pro-t ...
- Java静态相关问题
问题1: public class Demo01_StaticTest { private static Demo01_StaticTest st = new Demo01_StaticTest(); ...
- Java核心技术之Date相关
import java.time.DayOfWeek; import java.time.LocalDate; import java.util.Scanner; /** * @author Suns ...
- JNA使用入门
JNA即Java Native Access. 官方主页 代码仓库 官方样例 maven中心仓库主页 官方文档 Getting Started Functional Description. Mapp ...
- 使用一次sql请求,返回分页数据和总条数
日常搬砖,总少不了需要获取分页数据和总行数. 一直以来的实践是编码两次sql请求,分别拉分页数据和totolCount. 最近我在思考: 常规实践为什么不是 在一次sql请求中中执行多次sql查询或多 ...
- PowerShell快速修改多个文件的名称
本文介绍基于PowerShell语言,对文件夹中全部文件的名称加以批量替换.修改的方法. 在之前的文章中,我们介绍了基于Python语言,批量修改大量文件的名称的方法.当时我们修改文件名的需求 ...
- VSCode 插件离线安装方法
一.引言 最近想要使用 VSCode 来进行项目的开发工作,无奈工作机上无法上网.这就涉及到了相关插件的离线安装的问题. 在参考了 https://blog.csdn.net/wangwei703/a ...
- LeetCode300.最长递增子序列
LeetCode300.最长递增子序列 力扣题目链接(opens new window) 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删除 ...
- wiz 为知笔记服务器 docker 迁移爬坑指北
本文主要是介绍 wiz 为知笔记服务器 docker 从旧服务器迁移到新服务器的步骤以及问题排查. 旧服务器升级 wiz docker 目的:保持和新服务器拉取的镜像版本一致. 官方只留了 wiz d ...
- cubeide汉化包地址
http://mirrors.ustc.edu.cn/eclipse/technology/babel/update-site 具体步骤看洋桃物联网入门30步的视频