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是否释放的标志

    @Override
    protected 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);
    }

    @Override
    public 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();     //重置MediaPlayer
                mPlayer.release();   //释放MediaPlayer
                isRelease = 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">

    <SurfaceView
        android:id="@+id/sfv_show"
        android:layout_width="match_parent"
        android:layout_height="300dp" />

    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始" />

    <Button
        android:id="@+id/btn_pause"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="暂停 " />

    <Button
        android: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;

    @Override
    protected 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);   //显示的分辨率,不设置为视频默认

    }

    @Override
    public 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;
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mPlayer = MediaPlayer.create(MainActivity.this, R.raw.lesson);
        mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mPlayer.setDisplay(surfaceHolder);    //设置显示视频显示在SurfaceView上
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {}

    @Override
    protected 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;

    @Override
    protected 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));
    }

    @Override
    public 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;
        }
    }
}

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

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

相关文章

PHP8的运算符-PHP8知识详解

运算符是可以通过给出的一或多个值&#xff08;用编程行话来说&#xff0c;表达式&#xff09;来产生另一个值&#xff08;因而整个结构成为一个表达式&#xff09;的东西。 PHP8的运算符有很多&#xff0c;按类型分有一元运算符、二元运算符、三元运算符。 一元运算符只对一…

第四讲:利用ADO方式连接Access数据库

【分享成果&#xff0c;随喜正能量】最值得信赖的&#xff0c;其实是自己从孤独中得来的东西&#xff0c;而不是别人给予自己的东西。每个人都是一座孤岛&#xff0c;有些人一生都在想要逃离这座岛&#xff0c;有些人一生都在创造并丰富自己这座岛。。 《VBA数据库解决方案》教…

解释器模式——自定义语言的实现

1、简介 1.1、文法规则和抽象语法树 解释器模式描述了如何为简单的语言定义一个文法&#xff0c;如何在该语言中表示一个句子&#xff0c;以及如何解释这些句子。在正式分析解释器模式结构之前&#xff0c;先来学习如何表示一个语言的文法规则以及如何构造一棵抽象语法树。 …

安全文件传输:如何避免数据泄露和黑客攻击

网络安全问题日益严重&#xff0c;导致许多数据被泄露和黑客袭击的事件频发。为了保证文件传输的安全&#xff0c;需要实施一系列安全文件传输策略来防止数据被泄露和黑客袭击。 第一、选择适合的加密方法是非常关键的 加密是一种将明文转换成密文的过程&#xff0c;这样只有授…

跨部门协作,企业图文档管理的协同管理的重要性

随着企业规模的扩大和业务流程的复杂化&#xff0c;图文档管理涉及的部门和人员越来越多&#xff0c;因此跨部门协作成为了必不可少的管理方式。在线图文档管理作为现代企业的数字化解决方案之一&#xff0c;为跨部门协作提供了强大的支持和便利。在线图文档管理在企业图文档管…

计算机视觉实验:图像增强应用实践

本次实验主要从基于统计、函数映射的图像增强方法和基于滤波的图像增强方法两种方法中对一些图像增强的算法进行实现。主要的编程语言为python&#xff0c;调用了python自带的PIL图像库用于读取图像&#xff0c;利用numpy进行图像运算&#xff0c;最后使用opencv第三方库进行对…

最新版Android13使用Notification,Notification的基本使用和进阶使用

一、使用Notification 1、创建一个通知 1.1 注册一个渠道 在Android13&#xff0c;版本通知的使用发生了新的变化。 首先我们需要创建一个NotificationManager用于管理通知。 //创建notificationManager对通知进行管理 NotificationManager notificationManager getSyste…

输入筛选框搜索

文章目录 输入筛选框实现效果图需求前端工具版本添加依赖main.js导入依赖 代码 后端代码对应 sql对应 mapper.xml 文件的动态 sql 输入筛选框实现 效果图 需求 通过筛选框&#xff0c;选择公司&#xff0c;传入后端&#xff0c;后端根据公司名称去文章的内容中进行模糊查询 …

【云原生】K8S二进制搭建上篇

目录 一、环境部署1.1操作系统初始化 二、部署etcd集群2.1 准备签发证书环境在 master01 节点上操作在 node01与02 节点上操作 三、部署docker引擎四、部署 Master 组件4.1在 master01 节点上操 五、部署Worker Node组件 一、环境部署 集群IP组件k8s集群master01192.168.243.1…

Linux lvs负载均衡

LVS 介绍&#xff1a; Linux Virtual Server&#xff08;LVS&#xff09;是一个基于Linux内核的开源软件项目&#xff0c;用于构建高性能、高可用性的服务器群集。LVS通过将客户端请求分发到一组后端服务器上的不同节点来实现负载均衡&#xff0c;从而提高系统的可扩展性和可…

Redis 集群 (cluster)

是什么 官网&#xff1a;Redis cluster specification | Redis 由于数据量过大&#xff0c;单个Master复制集难以承担&#xff0c;因此需要对多个复制集进行集群&#xff0c;形成水平扩展每个复制集只负责存储整个数据集的一部分&#xff0c;这就是Redis的集群&#xff0c;其作…

【BASH】回顾与知识点梳理(七)

【BASH】回顾与知识点梳理 七 七.前六章知识点总结及练习7.1 总结7.2 练习 七.前六章知识点总结及练习 7.1 总结 由于核心在内存中是受保护的区块&#xff0c;因此我们必须要透过『 Shell 』将我们输入的指令与 Kernel 沟通&#xff0c;好让 Kernel 可以控制硬件来正确无误的…

Open3D (C++) 基于拟合平面的点云地面点提取

目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示1、原始点云2、提取结果四、相关链接本文由CSDN点云侠原创,原文链接。爬虫网站自重,把自己当个人,爬些不完整的误导别人有意思吗???? 一、算法原理

C# Blazor 学习笔记(7):组件嵌套开发

文章目录 前言相关资料组件嵌套组件模板RenderFragment 意义传统前端样式组件化css 前言 我们在组件化一共有三个目的。 不用写CSS不用写html不用写交互逻辑 简单来说就是Java常说的约定大于配置。我们只需要必须的参数即可&#xff0c;其它的都按照默认配置。我们不需要关系…

Java多线程(四)

目录 一、线程的状态 1.1 观察线程的所有状态 1.2 线程状态和状态转移的意义 1.2.1 NEW、RUNNABLE、TERMINATED状态转换 1.2.2 WAITING、BLOCKED、TIMED_WAITING状态转换 1.2.3 yield()大公无私让出cpu 一、线程的状态 1.1 观察线程的所有状态 public class Demo9 {public st…

《向量数据库指南》——腾讯云向量数据库Tencent Cloud Vector DB正式上线公测!提供10亿级向量检索能力

8月1日,腾讯云向量数据库(Tencent Cloud Vector DB)已正式上线公测。在腾讯云官网上搜索“向量数据库”,就可以正式体验该产品。 腾讯云向量数据库不仅能为大模型提供外部知识库,提高大模型回答的准确性,还可广泛应用于推荐系统、文本图像检索、自然语言处理等 AI 领域。…

selenium 遇到更新chorme驱动

打开浏览器,在地址栏输入chrome://version/便可以查看到谷歌当前的版本号 谷歌浏览器驱动的下载网址 http://chromedriver.storage.googleapis.com/index.htmlhttp://chromedriver.storage.googleapis.com/index.html 解压后把chromedriver.exe 放到python安装的目录下&am…

【第一阶段】kotlin语言引用数据类型

Java语言中有两种数据类型 第一种&#xff1a;基本数据类型 如int double等 第二种&#xff1a;引用数据类型。如String kotlin只有一种数据类型&#xff0c;看起来都是引用数据类型&#xff0c;实际上编译器会在Java字节码中&#xff0c;修改成基本类型 //Java语言中有两种数…

微信小程序使用editor富文本编辑器 以及回显 全屏弹窗的模式

<!--富文本接收的位置--><view class"white-box"><view class"title"><view class"yellow-fence"></view><view class"v1">教研记录</view></view><view class"add-btn"…

Hbase pe 压测 OOM问题解决

说明&#xff1a;本人使用CDH虚拟机搭建了Hbase集群&#xff0c;但是在压测的时发现线程多个的时候直接回OOM,记录一下 执行命令 hbase pe --nomapred --oneContrue --tablerw_test_1 --rows1000 --valueSize100 --compressSNAPPY --presplit10 --autoFlushtrue randomWrite …