MediaPlayer 概览

news/2024/4/25 3:46:49/文章来源:https://blog.csdn.net/qq_42015021/article/details/130265774

概览

Android 多媒体框架支持播放各种常见媒体类型,以便您轻松地将音频、视频和图片集成到应用中。您可以使用 MediaPlayer API,播放存储在应用资源(原始资源)内的媒体文件、文件系统中的独立文件或者通过网络连接获得的数据流中的音频或视频。
本文档向您介绍了如何编写与用户和系统互动的媒体播放应用,以实现良好的性能和用户体验。

基础知识

以下类用于在 Android 框架中播放声音和视频:

MediaPlayer

此类是用于播放声音和视频的主要 API。

AudioManager

此类用于管理设备上的音频源和音频输出。

清单声明

在开始使用 MediaPlayer 开发应用之前,请确保您的清单具有适当的声明,这样才能使用相关功能。

  • 互联网权限 - 如果您使用 MediaPlayer 流式播放基于网络的内容,则您的应用必须申请网络访问权限。
    <uses-permission android:name="android.permission.INTERNET" />
  • 唤醒锁定权限 - 如果播放器应用需要防止屏幕变暗或处理器进入休眠状态,或者要使用 MediaPlayer.setScreenOnWhilePlaying() 或 MediaPlayer.setWakeMode() 方法,则您必须申请此权限。
    <uses-permission android:name="android.permission.WAKE_LOCK" />

使用 MediaPlayer

MediaPlayer 类是媒体框架最重要的组成部分之一。此类的对象能够获取、解码以及播放音频和视频,而且只需极少量设置。它支持多种不同的媒体源,例如:

本地资源
内部 URI,例如您可能从内容解析器那获取的 URI
外部网址(流式传输)

本地资源

以下示例展示了如何播放作为本地原始资源(保存在应用的 res/raw/ 目录中)提供的音频:

    MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);mediaPlayer.start(); // no need to call prepare(); create() does that for you 

在本例中,“原始”资源是指系统不会尝试以任何特定方式解析的文件。不过,该资源的内容不应为原始音频。它应该是采用某种支持的格式且经过适当编码和格式化的媒体文件。

本地可用的URI

播放系统中本地可用的 URI(例如,您可以通过内容解析器获取)中的内容方法如下:

    Uri myUri = ....; // initialize Uri hereMediaPlayer mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDataSource(getApplicationContext(), myUri);mediaPlayer.prepare();mediaPlayer.start();

外部网址

通过 HTTP 流式传输并播放远程网址上的内容如下所示:

    String url = "http://........"; // your URL hereMediaPlayer mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDataSource(url);mediaPlayer.prepare(); // might take long! (for buffering, etc)mediaPlayer.start();

异步准备

原则上,使用 MediaPlayer 会非常简单。不过,请务必注意,要正确地将其与典型的 Android 应用集成,还需执行一些额外操作。例如,对 prepare() 的调用可能需要很长时间来执行,因为它可能涉及获取和解码媒体数据。因此,与任何可能需要很长时间来执行的方法一样,切勿从应用的界面线程中调用它。这样做会导致界面挂起,直到系统返回该方法,这是一种非常糟糕的用户体验,并且可能会导致 ANR(应用无响应)错误。即使您预计资源会快速加载,但也请记得,界面中任何响应时间超过十分之一秒的操作都会导致明显的暂停,并让用户觉得您的应用运行缓慢。

为避免界面线程挂起,请生成其他线程来准备 MediaPlayer,并在准备工作完成后通知主线程。不过,尽管您可以自行编写线程逻辑,但此模式在使用 MediaPlayer 时非常普遍,因此框架通过 prepareAsync() 方法提供了一种完成此任务的便捷方式。此方法会在后台开始准备媒体,并立即返回。当媒体准备就绪后,系统会调用通过 setOnPreparedListener() 配置的 MediaPlayer.OnPreparedListeneronPrepared() 方法。

管理状态

您还应该记住,MediaPlayer 以状态为基础。也就是说,MediaPlayer 具有内部状态,您在编写代码时必须始终注意,某些操作仅在播放器处于特定状态时才有效。如果您在错误的状态下执行某项操作,则系统可能会抛出异常或导致其他不良行为。
MediaPlayer 类的参考文档显示了一个完整的状态图,该图说明了哪些方法可将 从一种状态变为另一种状态。例如,当您创建新的 MediaPlayer 时,它处于“Idle”状态。此时,您应该通过调用 setDataSource() 初始化该类,使其处于“Initialized”状态。然后,您必须使用 prepare() 或 prepareAsync() 方法完成准备工作。当 MediaPlayer 准备就绪后,它便会进入“Prepared”状态,这也意味着您可以通过调用 start() 使其播放媒体内容。此时,如图所示,您可以通过调用 start()、pause() 和 seekTo() 等方法在“Started”、“Paused”和“PlaybackCompleted”状态之间切换。不过请注意,当您调用 stop() 时,除非您再次准备 MediaPlayer,否则将无法再次调用 start()
在编写与 MediaPlayer 对象互动的代码时,请始终牢记该状态图,因为从错误的状态调用其方法是导致错误的常见原因。

释放 MediaPlayer

MediaPlayer 会占用宝贵的系统资源。因此,您应该始终采取额外的预防措施,确保 MediaPlayer 实例保留的时间不会过长。完成该操作后,您应始终调用 release() 以确保分配给它的所有系统资源均已正确释放。例如,如果您使用 MediaPlayer,并且您的 Activity 接收到对 onStop() 的调用,则您必须释放该 MediaPlayer,因为当 Activity 未与用户互动时,保留该 MediaPlayer 并没有什么意义(除非您在后台播放媒体内容,这将在下一部分中介绍)。当然,当 Activity 恢复或重启时,您需要先创建一个新的 MediaPlayer 并再次完成准备工作,然后才能恢复播放。
以下代码段介绍了如何释放并取消 MediaPlayer

    mediaPlayer.release();mediaPlayer = null;

例如,思考一下:如果您忘记在 Activity 停止时释放 MediaPlayer,但是在 Activity 重新启动时新建一个 MediaPlayer,则可能会出现哪些问题。如您所知,当用户更改屏幕方向(或以其他方式更改设备配置)时,系统会重启 Activity(默认情况下),因此当用户在纵向和横向之间来回旋转设备时,您可能会很快消耗掉所有的系统资源,因为每当方向更改时,您都会创建一个永远不会释放的新 MediaPlayer。(如需详细了解运行时重启,请参阅处理运行时更改。)

您可能想知道:当用户离开您的 Activity 后仍继续播放“后台媒体”(这与内置音乐应用的行为十分相似)会发生什么。在这种情况下,您需要的是由 Service 控制的 MediaPlayer,如下一部分中所述

示例

在surfaceView中播放自媒体。

    private Callback mSurfaceCallback = new Callback(){@Overridepublic void surfaceCreated(@NonNull SurfaceHolder holder) {Log.i(TAG, "surfaceCreated...");mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);Uri uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName() + "/" + R.raw.video);try {mediaPlayer.setDataSource(MainActivity.this, uri);} catch (IOException e) {ToastUtil.showToast(MainActivity.this, "播放失败");e.printStackTrace();}mediaPlayer.setDisplay(holder);mediaPlayer.prepareAsync();mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {mediaPlayer.start();}});}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder holder) {Log.i(TAG, "surfaceDestroyed...");if (mediaPlayer.isPlaying()) {mediaPlayer.stop();}}};

在 Service 中使用 MediaPlayer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_102330.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据技术之集群数据迁移

在大数据集群数据迁移的项目中涉及到很多技术细节&#xff0c;本博客记录了迁移的大致的操作步骤。 迁移借用Hadoop自带的插件&#xff1a;distcp。 一、Hadoop集群数据迁移 **DistCp&#xff08;分布式拷贝&#xff09;**是用于大规模集群内部和集群之间拷贝的工具。它使用M…

DHCP笔记

目录 DHCP动态主机配置协议——UDP67/68端口 DHCP获取IP地址 客户端首次获取IP地址 客户端再次获取IP地址 租期/续租 DHCP的工作报文 DHCP的配置 案例 DHCP动态主机配置协议——UDP67/68端口 DHCP是应用层协议&#xff0c;采用C/S服务模式&#xff0c;只能在一个广播域…

数据科学与机器学习在软件开发中的应用

数据科学和机器学习是现代软件开发的重要组成部分&#xff0c;可以帮助开发人员更好地理解和分析数据&#xff0c;从而提高软件的质量和性能。在本篇博客中&#xff0c;我将深入探讨数据科学和机器学习在软件开发中的应用&#xff0c;并讨论它们如何帮助我们创建更好的软件。 …

Xshell中的基本命令

whoami 当我们刚登录上Xshell的时候&#xff0c;我们应该做什么呢&#xff1f;&#xff1f; 我们上次说了如何增加使用者&#xff0c;和删除使用者&#xff0c;今天我们说一下其他的基本命令。 我们刚开始登录的时候可以用root登录 那么我们怎么看自己事谁呢&#xff1f; …

Android 一个获取网址时间的Demo

Android 一个获取网址时间的Demo 文章目录 Android 一个获取网址时间的Demo通过一个网址获取时间的代码关于Android NTP 时间Android 同步时间代码 前段时间有个客户想用局域网同步Android 设备的时间&#xff0c;开发后把这个demo分享一下。 效果&#xff1a; 这里也获取了阿…

VUE3子组件-业务代码优化

Vue3子组件 1.简介 Vue 3组件的主要优势之一就是它们可以帮助你将你的应用程序分解成可维护和可重用的部分。当你在应用程序中多次使用相同的代码时&#xff0c;你可以将它们抽象成一个组件&#xff0c;然后在应用程序中的多个地方使用该组件&#xff0c;而不必每次都编写相同…

User Diverse Preference Modeling by Multimodal Attentive Metric Learning

BACKGROUND 现有模型通常采用一个固定向量去表示用户偏好&#xff0c;在假设——特征向量每一个维度都代表了用户的一种特性或者一个方面&#xff0c;这种方式似乎不妥&#xff0c;因为用户对于不同物品的偏好是不一样的&#xff0c;例如因演员喜欢一部电影&#xff0c;而因特…

Linux 静态库的制作与使用

目录 静态库1、 什么是库2、 静态库的制作2.1 命名规则与制作规则 3、 静态库的使用 静态库 1、 什么是库 库文件是计算机上的一类文件&#xff0c;可以简单的把库文件看成一种代码仓库&#xff0c;它提供使用者可以直接拿来用的变量、函数或类。库是一种特殊的程序&#xff…

多兴趣推荐召回模型:ComiRec

前言 多兴趣向量召回系列&#xff1a; 通过Youtube DNN推荐模型来理解推荐流程 多兴趣召回模型&#xff1a;MIND 推荐系统可以表达为序列推荐问题的形式&#xff0c;序列推荐任务是通过用户的历史行为来预测用户下一个感兴趣的item&#xff0c;这也与真实场景的推荐场景是符…

ERROR org.springframework.web.context.ContextLoader

项目启动时报错&#xff1a; ERROR org.springframework.web.context.ContextLoader - Context initialization failed java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotationUtils.clearCache() 原因分析 这个错误的原因可能是因为 Spring 的不同…

Go 语言进阶与依赖管理

作者&#xff1a;非妃是公主 专栏&#xff1a;《Golang》 博客主页&#xff1a;https://blog.csdn.net/myf_666 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录 一、语言进阶1. 并发和并行2. 协程(Goroutine…

Ubuntu20.04软件安装大全

目录 Ubuntu20.04 软件安装大全前言1. Windows和Ubuntu双系统安装1.1 下载Ubuntu系统镜像1.2 磁盘分区1.3 GPT分区安装Ubuntu1.4 系统完成后的一些设置1.5 遇到的一些小bug 2. 换源2.1 apt换源2.2 pip换源 3. 显卡驱动安装3.1 卸载显卡驱动3.2 准备工作3.3 驱动安装3.4 验证 4.…

Python自动发送消息小脚本,可用于各种聊天框~

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,YOLO,活动领域博主爱笑的男孩。擅长深度学习,YOLO,活动,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typecollect 个…

2023-04-23 算法面试中常见的动态规划问题

动态规划 1 什么是动态规划 以菲波那切数列求和为例&#xff0c;通过 1.普通的递归2.引入记忆数组memo3.自下而上地解决问题&#xff0c;即动态规划 动态规划的定义 dynamic programming (also known as dynamic optimization) is a method for solving a complex problem by…

C嘎嘎~~ 【初识C++ 下篇】

初识C 下篇 1.引用1.1引用的概念1.2引用的特点1.3常引用1.4引用使用的场景1.5引用和指针的区别 2.指针空值 --- nullptr3.内联函数3.1 内联函数的概念3.2内联函数的使用场景3.3内联函数的特性 1.引用 1.1引用的概念 相信大家小时候&#xff0c; 肯定有小名、绰号、亲朋好友的昵…

Zuul源码解析(二)

Zuul 的自动配置 ZuulProxyAutoConfiguration 如何触发 如上图&#xff0c;在 spring.factory 中配置 ZuulProxyAutoConfiguration 自动配置了&#xff0c;直接点进去 如上图所示&#xff0c;发现这有个条件注解&#xff0c;需要有 org.springframework.cloud.netflix.zuul.Zu…

“支付+SaaS”赋能传统产业数字化转型

易观&#xff1a;传统支付业务利润空间在政策监管和市场竞争下不断被压缩&#xff0c;多家上市支付机构逐步将业务经营重点转移切入到企业交易环节&#xff0c;为企业提供包括SaaS服务、行业解决方案、营销服务及金融科技服务等在内的企业服务收入成为新的增长点。 伴随着“十四…

Linux网络服务之yum仓库

目录 一、yum仓库简介二. ftp搭建yum源三. 搭建国内在线源四. 本地源和在线yum同时使用五. 通过缓存的方式保存所下载的软件包六 . 制作yum仓库 一、yum仓库简介 yum是一个基于RPM包&#xff08;是Red-Hat Package Manager红帽软件包管理器的缩写&#xff09;构建的软件更新机…

Java入门教程||Java 继承||Java 重写(Override)与重载(Overload)

Java 继承 继承是所有 OOP 语言和 Java 语言不可缺少的组成部分。 继承是 Java 面向对象编程技术的一块基石&#xff0c;是面向对象的三大特征之一&#xff0c;也是实现软件复用的重要手段&#xff0c;继承可以理解为一个对象从另一个对象获取属性的过程。 如果类 A 是类 B …

Automa自动化爬取文本(一)

目录 介绍 下载地址 安装教程 爬取百度热搜 介绍 Automa 是一个免费、开源的 Chrome 扩展&#xff0c;它通过目前流行的 No Code 无代码方式&#xff0c;只需要拖拽模块就实现了浏览器自动化&#xff0c;比如自动填写表格、执行重复性任务。 在工作中&#xff0c;如果我们…