​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播放网络视频的更多相关文章

  1. FFmpeg开发笔记(十):ffmpeg在ubuntu上的交叉编译移植到海思HI35xx平台

    FFmpeg和SDL开发专栏(点击传送门) 上一篇:<FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放>下一篇:敬请期待   前言   将ffmpeg移植到海思H ...

  2. .net开发笔记(十六) 对前部分文章的一些补充和总结

    补充有两个: 一个是系列(五)中讲到的事件编程(网址链接),该文提及到了事件编程的几种方式以及容易引起的一些异常,本文补充“多线程事件编程”这一块. 第二个是前三篇博客中提及到的“泵”结构在编程中的应 ...

  3. 论文阅读笔记五十六:(ExtremeNet)Bottom-up Object Detection by Grouping Extreme and Center Points(CVPR2019)

    论文原址:https://arxiv.org/abs/1901.08043 github: https://github.com/xingyizhou/ExtremeNet 摘要 本文利用一个关键点检 ...

  4. 安卓开发笔记(十六):'Request(okhttp3.Request.Builder)' has private access in 'okhttp3.Request

    当出现了'Request(okhttp3.Request.Builder)' has private access in 'okhttp3.Request的错误的时候,实际上是我们在写代码的时候少打了 ...

  5. Java开发笔记(十六)非此即彼的条件分支

    前面花了大量篇幅介绍布尔类型及相应的关系运算和逻辑运算,那可不仅仅是为了求真值或假值,更是为了通过布尔值控制流程的走向.在现实生活中,常常需要在岔路口抉择走去何方,往南还是往北,向东还是向西?在Jav ...

  6. Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件

    前言   上一篇已经将himpp套入qt的基础上进行开发.那么qt中拿到frame则是很关键的交互,这是qt与海思可能编解码交叉开发的关键步骤.   受限制   因为直接配置sample的vi比较麻烦 ...

  7. FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  8. 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...

  9. FFmpeg开发笔记(四):ffmpeg解码的基本流程详解

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  10. FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放

    前言   ffmpeg播放rtsp网络流和摄像头流.   Demo   使用ffmpeg播放局域网rtsp1080p海康摄像头:延迟0.2s,存在马赛克     使用ffmpeg播放网络rtsp文件流 ...

随机推荐

  1. 使用 C# 和 ONNX 來玩转Phi-3 SLM

    LLM 席卷世界刷新 AI 的认知之后,由于 LLM 需要的硬件要求实在太高,很难在普通设备上运行,因此 SLM 逐漸受到重視,Phi-3 SLM 是由 Microsoft 所开发的模型,可以在你的电 ...

  2. 论文《policy-gradient-methods-for-reinforcement-learning-with-function-approximation 》的阅读——强化学习中的策略梯度算法基本形式与部分证明

    最近组会汇报,由于前一阵听了中科院的教授讲解过这篇论文,于是想到以这篇论文为题做了学习汇报.论文<policy-gradient-methods-for-reinforcement-learni ...

  3. @Valid和@Validated的service层的应用

    1.背景 实际开发中,很多时候要对参数校验,比如为空等, 除了要在接口的入口处使用,很多普通方法也需要检查,比如service方法, 那么如何在service上使用这个参数校验呢? 2.使用方式 步骤 ...

  4. 卷积神经网络CNN实战:MINST手写数字识别——网络定义

    本文基于python-pytorch框架,编写CNN网络,并采用CNN手写数字数据集训练.测试网络. 网络的构建 以LeNet-5 网络为例 类定义 首先先了解一下网络的最基本框架 一般而言,首先创建 ...

  5. C# 全局异常捕获(转载)

    C# 全局异常捕获 原文地址:https://www.cnblogs.com/tomahawk/articles/5993874.html 开发界有那么一个笑话,说是"「我爱你」三个字,讲出 ...

  6. 阿里云 CLI 使用

    安装 macOS: brew install aliyun-cli Linux: wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-a ...

  7. C 语言多文件编译

    C 语言中的多文件编程通常涉及将代码分散在几个不同的源文件(.c 文件)和头文件(.h 文件)中.这么做可以帮助你组织大型项目,提高代码的重用性,便于团队合作,分离接口和实现,以及加快编译时间.下面是 ...

  8. 一文剖析TCP三次握手、四次挥手

    TCP三次握手四次挥手 问题 TCP建立连接为什么是三次握手,而不是两次或四次? TCP,名为传输控制协议,是一种可靠的传输层协议,IP协议号为6. 顺便说一句,原则上任何数据传输都无法确保绝对可靠, ...

  9. python pyqt6 QMenu 设定圆角边框

    本来这个没有必要写,但是因为写的过程中,按照网上的写法运行,不知道为什么QMenu的右下角有圆角边框与直角背景颜色会覆盖显示 所以还是有必要写一下 menu = QMenu(self.tool_but ...

  10. 一文了解JSON

    目录 JSON 在JavaScript 中的使用. json 的定义 json 的访问 json 的两个常用方法 JSON 在 在 java 中的使用 javaBean 和 和 json 的互转 Li ...