Android 之 MediaPlayer 播放音频与视频
本节引言:
本节带来的是Android多媒体中的——MediaPlayer,我们可以通过这个API来播放音频和视频 该类是Androd多媒体框架中的一个重要组件,通过该类,我们可以以最小的步骤来获取,解码 和播放音视频。它支持三种不同的媒体来源:
- 本地资源
- 内部的URI,比如你可以通过ContentResolver来获取
- 外部URL(流) 对于Android所支持的的媒体格式列表
对于Android支持的媒体格式列表,可见:Supported Media Formats 文档
本节我们就来用MediaPlayer来写个简单的播放音视频的例子!
官方API文档:MediaPlayer
1.相关方法详解
1)获得MediaPlayer实例:
可以直接new或者调用create方法创建:
MediaPlayer mp = new MediaPlayer(); MediaPlayer mp = MediaPlayer.create(this, R.raw.test); //无需再调用setDataSource
另外create还有这样的形式: create(Context context, Uri uri, SurfaceHolder holder) 通过Uri和指定 SurfaceHolder 【抽象类】 创建一个多媒体播放器
2)设置播放文件:
//①raw下的资源:
MediaPlayer.create(this, R.raw.test);//②本地文件路径:
mp.setDataSource("/sdcard/test.mp3");//③网络URL文件:
mp.setDataSource("http://www.xxx.com/music/test.mp3");
另外setDataSource()方法有多个,里面有这样一个类型的参数:FileDescriptor,在使用这个 API的时候,需要把文件放到res文件夹平级的assets文件夹里,然后使用下述代码设置DataSource:
AssetFileDescriptor fileDescriptor = getAssets().openFd("rain.mp3");
m_mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),fileDescriptor.getStartOffset(), fileDescriptor.getLength());
3)其他方法
- getCurrentPosition( ):得到当前的播放位置
- getDuration() :得到文件的时间
- getVideoHeight() :得到视频高度
- getVideoWidth() :得到视频宽度
- isLooping():是否循环播放
- isPlaying():是否正在播放
- pause():暂停
- prepare():准备(同步)
- prepareAsync():准备(异步)
- release():释放MediaPlayer对象
- reset():重置MediaPlayer对象
- seekTo(int msec):指定播放的位置(以毫秒为单位的时间)
- setAudioStreamType(int streamtype):指定流媒体的类型
- setDisplay(SurfaceHolder sh):设置用SurfaceHolder来显示多媒体
- setLooping(boolean looping):设置是否循环播放
- setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener): 网络流媒体的缓冲监听
- setOnCompletionListener(MediaPlayer.OnCompletionListener listener): 网络流媒体播放结束监听
- setOnErrorListener(MediaPlayer.OnErrorListener listener): 设置错误信息监听
- setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener): 视频尺寸监听
- setScreenOnWhilePlaying(boolean screenOn):设置是否使用SurfaceHolder显示
- setVolume(float leftVolume, float rightVolume):设置音量
- start():开始播放
- stop():停止播放
2.使用代码示例
示例一:使用MediaPlayer播放音频:
运行效果图:

关键代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{private Button btn_play;private Button btn_pause;private Button btn_stop;private MediaPlayer mPlayer = null;private boolean isRelease = true; //判断是否MediaPlayer是否释放的标志@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bindViews();}private void bindViews() {btn_play = (Button) findViewById(R.id.btn_play);btn_pause = (Button) findViewById(R.id.btn_pause);btn_stop = (Button) findViewById(R.id.btn_stop);btn_play.setOnClickListener(this);btn_pause.setOnClickListener(this);btn_stop.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.btn_play:if(isRelease){mPlayer = MediaPlayer.create(this,R.raw.fly);isRelease = false;}mPlayer.start(); //开始播放btn_play.setEnabled(false);btn_pause.setEnabled(true);btn_stop.setEnabled(true);break;case R.id.btn_pause:mPlayer.pause(); //停止播放btn_play.setEnabled(true);btn_pause.setEnabled(false);btn_stop.setEnabled(false);break;case R.id.btn_stop:mPlayer.reset(); //重置MediaPlayermPlayer.release(); //释放MediaPlayerisRelease = true;btn_play.setEnabled(true);btn_pause.setEnabled(false);btn_stop.setEnabled(false);break;}}
}
注意事项:
播放的是res/raw目录下的音频文件,创建MediaPlayer调用的是create方法,第一次启动播放前 不需要再调用prepare(),如果是使用构造方法构造的话,则需要调用一次prepare()方法! 另外贴下官方文档中,从其他两种途径播放音频的示例代码:
本地Uri:
Uri myUri = ....; // initialize Uri here MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDataSource(getApplicationContext(), myUri); mediaPlayer.prepare(); mediaPlayer.start();
外部URL:
String url = "http://........"; // your URL here MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDataSource(url); mediaPlayer.prepare(); // might take long! (for buffering, etc) mediaPlayer.start();
Note:假如你通过一个URL以流的形式播放在线音频文件,该文件必须可以进行 渐进式下载
示例二:使用MediaPlayer播放视频
MediaPlayer主要用于播放音频,没有提供图像输出界面,所以我们需要借助其他的 组件来显示MediaPlayer播放的图像输出,我们可以使用用SurfaceView 来显示,下面我们使用SurfaceView来写个视频播放的例子:
运行效果图:

实现代码:
布局文件:activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="5dp"><SurfaceViewandroid:id="@+id/sfv_show"android:layout_width="match_parent"android:layout_height="300dp" /><Buttonandroid:id="@+id/btn_start"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="开始" /><Buttonandroid:id="@+id/btn_pause"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="暂停 " /><Buttonandroid:id="@+id/btn_stop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="终止" /></LinearLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity implements View.OnClickListener, SurfaceHolder.Callback {private MediaPlayer mPlayer = null;private SurfaceView sfv_show;private SurfaceHolder surfaceHolder;private Button btn_start;private Button btn_pause;private Button btn_stop;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bindViews();}private void bindViews() {sfv_show = (SurfaceView) findViewById(R.id.sfv_show);btn_start = (Button) findViewById(R.id.btn_start);btn_pause = (Button) findViewById(R.id.btn_pause);btn_stop = (Button) findViewById(R.id.btn_stop);btn_start.setOnClickListener(this);btn_pause.setOnClickListener(this);btn_stop.setOnClickListener(this);//初始化SurfaceHolder类,SurfaceView的控制器surfaceHolder = sfv_show.getHolder();surfaceHolder.addCallback(this);surfaceHolder.setFixedSize(320, 220); //显示的分辨率,不设置为视频默认}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_start:mPlayer.start();break;case R.id.btn_pause:mPlayer.pause();break;case R.id.btn_stop:mPlayer.stop();break;}}@Overridepublic void surfaceCreated(SurfaceHolder holder) {mPlayer = MediaPlayer.create(MainActivity.this, R.raw.lesson);mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mPlayer.setDisplay(surfaceHolder); //设置显示视频显示在SurfaceView上}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {}@Overrideprotected void onDestroy() {super.onDestroy();if (mPlayer.isPlaying()) {mPlayer.stop();}mPlayer.release();}
}
代码很简单,布局有个SurfaceView,然后调用getHolder获得一个SurfaceHolder对象, 在这里完成SurfaceView相关的设置,设置了显示的分辨率以及一个Callback接口, 重写了SurfaceView创建时,发生变化时,以及销毁时的三个方法!然后按钮控制播放 以及暂停而已~
示例三:使用VideoView播放视频
除了使用MediaPlayer + SurfaceView播放视频的方式,我们还可以使用VideoView来直接 播放视频,我们稍微改点东西就可以实现视频播放!运行效果和上面的一致,就不贴了, 直接上代码!
MainActivity.java:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {private VideoView videoView;private Button btn_start;private Button btn_pause;private Button btn_stop;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bindViews();}private void bindViews() {videoView = (VideoView) findViewById(R.id.videoView);btn_start = (Button) findViewById(R.id.btn_start);btn_pause = (Button) findViewById(R.id.btn_pause);btn_stop = (Button) findViewById(R.id.btn_stop);btn_start.setOnClickListener(this);btn_pause.setOnClickListener(this);btn_stop.setOnClickListener(this);//根据文件路径播放if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {videoView.setVideoPath(Environment.getExternalStorageDirectory() + "/lesson.mp4");}//读取放在raw目录下的文件//videoView.setVideoURI(Uri.parse("android.resource://com.jay.videoviewdemo/" + R.raw.lesson));videoView.setMediaController(new MediaController(this));}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_start:videoView.start();break;case R.id.btn_pause:videoView.pause();break;case R.id.btn_stop:videoView.stopPlayback();break;}}
}相关文章:
Android 之 MediaPlayer 播放音频与视频
本节引言: 本节带来的是Android多媒体中的——MediaPlayer,我们可以通过这个API来播放音频和视频 该类是Androd多媒体框架中的一个重要组件,通过该类,我们可以以最小的步骤来获取,解码 和播放音视频。它支持三种不同的…...
React中事件处理器的基本使用
在React中,为了提高性能,跨浏览器兼容性和开发体验,React实现了一套自己的事件机制,利用事件委托和合成事件的方式统一管理事件订阅和分发。 为了让组件能够响应用户的交互行为,React提供了一系列的事件处理器…...
RobotFramework
一、RobotFramework的简介和特点 1、关键字驱动: 把项目中的业务逻辑封装成一个一个的关键字,然后调用不同的关键字组成不同的业务 2、数据驱动 把测试数据放到excel:yaml文件中 通过改变文件中的数据去驱动测试用例执行 3、特点ÿ…...
【Matplotlib 绘制折线图】
使用 Matplotlib 绘制折线图 在数据可视化中,折线图是一种常见的图表类型,用于展示随着变量的变化,某个指标的趋势或关系。Python 的 Matplotlib 库为我们提供了方便易用的功能来绘制折线图。 绘制折线图 下面的代码展示了如何使用 Matplo…...
ARM汇编基本变量的定义和使用
一、ARM汇编中基本变量是什么? 数字变量: GBLA LCLA SETA 逻辑变量:GBLL LCLL SETL 字符串:GBLS LCLS SETLS 注意需要TAB键定义变量和行首改变值 二、使用步骤 1.引入库 代码如下(示例): GBLA led_num Reset_Handler PROCEXPORT Reset_Handler [WEA…...
排序算法汇总
每日一句:你的日积月累终会成为别人的望尘莫及 目录 常数时间的操作 选择排列 冒泡排列 【异或运算】 面试题: 1)在一个整形数组中,已知只有一种数出现了奇数次,其他的所有数都出现了偶数次,怎么找到…...
cocos2d 中UserDefault在windows平台下的路径问题
在使用cocos2dx c开发项目时,通常使用cocos自带的UserDefault来存储一些项目所用到的一些配置信息:如游戏的音量,游戏的闯关数等... 但是windows平台下,测试发现如果用户的帐户名使用是中文,在启动程序时会报错&#…...
ChatGPT与高等教育变革:价值、影响及未来发展
最近一段时间,ChatGPT吸引了社会各界的目光,它可以撰写会议通知、新闻稿、新年贺信,还可以作诗、写文章,甚至可以撰写学术论文。比尔盖茨、马斯克等知名人物纷纷为此发声,谷歌、百度等知名企业纷纷宣布要提供类似产品。…...
Matlab Image Processing toolbox 下载安装方法
当安装好Matlab之后,发现没有Image Processing toolbox这个图像处理工具箱 从新安装一遍, 选上 Image Processing toolbox 但是不用选matlab即可 1.找到之前安装时的Setup安装程序包,按照之前安装Matlab步骤,到选择需要安装的Ma…...
什么是消息键(Key)?如何使用消息键进行消息顺序性保证?
消息键(Key)是Kafka消息的一个可选属性,用于标识消息的逻辑关联关系。每条消息可以携带一个关键字作为其键,这个键可以是字符串、整数等数据类型。 使用消息键可以在Kafka中实现消息的顺序性保证,具体方式如下&#x…...
慎思笃行,兴业致远:金融行业的数据之道
《中庸》中说,“博学之,审问之,慎思之,明辨之,笃行之”。这段话穿越千年,指引着中国千行百业的发展。对于金融行业来说,庞大的数据量可以说是“博学”的来源。但庞大的数据体量,既是…...
Git-分支管理
文章目录 1.分支管理2.合并冲突3.合并模式4.补充 1.分支管理 Git分支管理是指在Git版本控制系统中,使用分支来管理项目的不同开发线路和并行开发的能力。通过分支,开发者可以在独立的环境中进行功能开发、bug修复等工作,而不会影响到主分支上…...
[Ubuntu 22.04] containerd配置HTTP方式拉取私仓Harbor
文章目录 1. 基础环境配置2. Docker安装3. 部署Harbor,HTTP访问4. 部署ContainerD5. 修改docker配置文件,向harbor中推入镜像6. 配置containerd6.1. 拉取镜像验证6.2. 推送镜像验证 1. 基础环境配置 [Ubuntu 22.04] 安装K8S基础环境准备脚本 2. Docker安…...
入门指南:深入解析OpenCV的copyTo函数及其与rect的应用场景
文章目录 导言copyTo函数的示例copyTo函数与rect的应用场景结论 导言 OpenCV是一个功能强大的开源计算机视觉库,广泛应用于图像处理和计算机视觉任务。在OpenCV中,copyTo函数是一个重要的图像处理函数,它允许我们在不同的图像之间复制像素数…...
2018年全国硕士研究生入学统一考试管理类专业学位联考写作试题——解析版
2018年1月真题 四、写作:第56~57小题,共65分。其中论证有效性分析30 分,论说文35分。 56.论证有效性分析: 分析下述论证中存在的缺陷和漏洞,选择若干要点,写一篇600字左右的文章,对该论证的有…...
系统集成|第七章(笔记)
目录 第七章 范围管理7.1 项目范围管理概念7.2 主要过程7.2.1 规划范围管理7.2.2 收集需求7.2.3 定义范围7.2.4 创建工作分解结构 - WBS7.2.5 范围确认7.2.6 范围控制 上篇:第六章、整体管理 第七章 范围管理 7.1 项目范围管理概念 概述:项目范围管理就…...
Qt —— Vs2017编译hiredis源码并测试调用(附调用hiredis库源码)
下载hiredis源码 编译hiredis源码 1、解压下载的hiredis源码包,如图使用Vs2017打开hiredis_win.sln 2、如下两图,Vs2017打开.sln后点击升级。 分别对两个工程的debug、release进行配置。Debug配置为多线程调试DLL(MDd)、Release配置为多线程DLL(/MD),这样做是为了配合被调用…...
深入理解设计模式:设计模式定义、设计原则以及组织编目
文章目录 一、设计模式1.1 设计模式的起源1.2 设计模式的定义1.3 记录要素1.4 合理使用模式 二、设计模式的六大原则2.1 开闭原则(Open-Closed Principle, OCP)2.1.1 定义2.1.2 原则分析2.1.3 开闭原则的意义所在 2.2 单一职责原则(Single Responsibility Principle, SRP)2.4.1…...
鸿鹄协助管理华为云与炎凰Ichiban
炎凰对华为云的需求 在炎凰日常的开发中,对于服务器上的需求,我们基本都是采用云服务。目前我们主要选择的是华为云,华为云的云主机比较稳定,提供的云主机配置也比较多样,非常适合对于不同场景硬件配置的需求ÿ…...
Vite创建Vue+TS项目引入文件路径报错
使用vite搭建vue3脚手架的时候,发现main.ts中引入App.vue编辑器会报错,但是不影响代码运行。 报错信息:TS2307: Cannot find module ‘./App.vue’ or its corresponding type declarations. 翻译过来是找不到模块或者相关的声明类型&#…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
Linux安全加固:从攻防视角构建系统免疫
Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...
