MediaPlayer

1、概念

MediaPlayer是Android原生的多媒体播放器,可以用它来实现本地或者在线音视频的播放。

2、MediaPlayer的状态

下面的图是官方给出的状态转换图,也可易理解为MediaPlayer的生命周期。

  • 椭圆形:表示MediaPlayer的状态;
  • 弧形:表示驱动对象状态转换的控制操作,有两种类型的弧,具有单箭头的弧表示同步方法调用,而具有双箭头的弧表示异步方法调用。

MediaPlayer的状态转换.png

MediaPlayer状态转换说明:

  • Idle状态:当新建对象或者在对象创建之后调用reset()时,MediaPlayer对象处于Idle状态。

  • End状态:Idle状态下,调用方法release()会直接进入End状态。MediaPlayer对象处于End状态,就无法再使用它,也无法将其恢复为其他任何状态。

生命周期开始 : 进入 Idle (闲置) 状态;
生命周期结束 : 进入 End (结束) 状态;

  • Initialized状态:Idle状态下,调用setDataSource()设置视频资源,正常情况下MediaPlayer对象会进入Initialized状态。如果调用setDataSource()方法的时候,MediaPlayer对象不是处于Idle状态就会抛出异常IllegalStateException。

  • Error状态:如果设置了回调setOnErrorListener(),此时遇到音频/视频格式不支持的,分辨率太高,流式传输超时等问题时,会回调onError()方法,此时进入Error状态。可以使用 reset() 方法进入Idle 状态。

  • Prepared状态:Initialized状态下,调用prepared()方法或preparedAsync()方法进入Prepared状态。prepared()方法直接进入Parpared状态,preparedAsync()方法是异步执行,会先进入Preparing状态,播放引擎准备完毕后会通过OnPreparedListener.onPrepared()回调方法通知进入Prepared状态。
    只有在 Initialized状态下才能调用 prepare() 和 prepareAsync()方法, 在其它状态下调用就会抛出异常IllegalStateException。

创建 MediaPlayer : 通过 new MediaPlayer() 创建的对象处于Idle (闲置) 状态;
重载 MediaPlayer : 通过 create() 方法创建的 MediaPlayer 对象处于Prepare (准备) 状态;
因此使用create() 方法创建后不需要在调用prepared()方法或preparedAsync()方法,否则会报错。

  • Started状态:Prepared状态下,调用start()方法进入Started()状态。isPlaying()可以测试MediaPlayer对象是否处于Started状态。在Started状态时,可以通过setOnBufferingUpdateListener()在其OnBufferingUpdateListener.onBufferingUpdate()回调中对流播放缓冲的状态进行追踪,可以做加载进度显示。

  • Pause状态:Started状态下,调用 pause()暂停,MediaPlayer对象将进入Pause状态。调用start()方法重新进入Started状态,继续播放。pause()和start()方法是成对的。

  • Stopped状态:在Started状态时,调用stop()方法会使MdiaPlayer从Started、Paused、Prepared、PlaybackCompleted等状态进入到Stoped状态,播放停止。处于Stopped状态,就无法开始播放,直到调用prepare()或prepareAsync()将MediaPlayer对象重新设置为Prepared状态。

  • PlaybackCompleted状态:当视频播放完成之后,如果设置setLooping()为false,并且设置了回调setOnCompletionListener(),会执行OnCompletion.onCompletion()方法,在回调后进入PlaybackCompleted状态。在此状态里可以调用start()方法重新进入Started状态。
    如果设置setLooping()为true,开启了循环模式,播放完毕之后MediaPlayer会重新进入Started状态。

3、MediaPlayer回调接口

  • OnBufferingUpdateListener
    该接口的作用是在流媒体缓冲状态发生改变的时候回调,percent表示已经缓冲了的或者播放了的媒体流百分比。
mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        mBufferPercentage = percent;
    }
}
  • OnCompletionListener
    在媒体流播放完毕之后回调。可以在该回调中设置播放下一个视频文件。
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
     @Override
    public void onCompletion(MediaPlayer mp) {        
    }
}
  • OnErrorListener
    在异步操作中出现错误时会回调该方法, 其它情况下出现错误时直接抛出异常。
    what:出现的错误类型。
    extra:针对与具体错误的附加码, 用于定位错误更详细信息。
mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        return false;
    }
}
  • OnInfoListener
    该方法在媒体播放时出现信息或者警告时回调该方法。
    what:信息或者警告的类型。
    extra:信息或者警告的附加码,关于警告更详细信息。
mGamePlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        return false;
    }
}
  • OnPreparedListener
    该方法在进入Prepared状态并开始播放的时候回调。
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        //这里可以调用start()方法开始播放视频      
        mPlayer.start(); 
    }
}
  • OnSeekCompleteListener
    查找操作完成的时候回调该方法。
mPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
    @Override
    public void onSeekComplete(MediaPlayer mediaPlayer) {
    }
}
  • OnVideSizeChangedListener
    当视频大小首次加载的时候及视频大小更新时回调该方法,如果没有视频返回0。
mPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {        
    }
}

4、MediaPlayer常用函数

  • seekTo()
    调整播放位置可以通过seekTo()方法,由于seekTo()是异步的,实际上查找需要一定时间才能完成,实际的查找位置完成时会走setOnSeekCompleteListener()的OnSeekComplete.onSeekComplete()回调。
    seekTo()在Prepared,Paused和PlaybackCompleted 状态下执行仍然会保持当前的状态。

  • setDataSource():设置数据源,正常调用后会进入Initialized状态。

  • setAudioStreamType():设置音频流类型,设置方式如下。

mGamePlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
  • setDisplay(): 设置播放视频的SurfaceHolder,设置方式如下,使用SurfaceView播放的时候使用该方法。
SurfaceView surfaceView = findViewById(R.id.surfaceView);
SurfaceHolder surfaceHolder = surfaceView.getHolder()
mPlayer.setDisplay(surfaceHolder);
  • setSurface(): 设置播放视频的Surface,设置方式如下,需要在SurfaceTexture准备就绪onSurfaceTextureAvailable回调的时候设置,使用TextureView播放的时候使用该方法。
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        // SurfaceTexture准备就绪
        mPlayer.setSurface(new Surface(surface));
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        // SurfaceTexture缓冲大小变化
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        // SurfaceTexture即将被销毁
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        // SurfaceTexture通过updateImage更新
    }
});
  • setVolume(): 设置音量。

  • getCurrentPosition():获取当前播放器播放的位置,返回值是已经播放了的毫秒数。

  • getDuration():获取文件的播放时长 (毫秒),如果没有可用的时长,就会返回 -1。

参考文章:
用MediaPlayer+TextureView封装一个完美实现全屏、小窗口的视频播放器
MediaPlayer+TextureView实现视频播放器
【Android 多媒体开发】 MediaPlayer 状态机 接口 方法 解析

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

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

相关文章

Python环境下LaTeX数学公式转图像方案调研与探讨

目录 引言方案一:基于LaTeX环境方案二:基于KaTeX(推荐) 方案三:基于Matplotlib写在最后 引言 近来,涉及到一些公式识别的项目,输入是公式的图像,输出是LaTeX格式的数学公式字符串。 这类项目一般都采用深…

基于Pytorch的驾驶员分心行为实时检测

本文使用深度学习和Pytorch(PyTorch 2.0.1\Torchvision 0.15.2)实时检测驾驶员的分心行为,并附录完整代码。 检测分心驾驶是现代汽车中最重要的功能之一。无论是自动驾驶汽车还是其它高端汽车,都配备了驾驶员监控系统,以持续跟踪驾驶员的行为。这对确保驾驶员保持目光在道路…

前端技术知识(含八股)总结 - 持续更新中

前端技术知识(含八股)总结 - 持续更新中 参考文献1.HTML和CSS1.1 语义化标签1.2 CSS 选择器及优先级 / position 定位 / box-sizing 属性 / transition / 继承属性(如字体文字类的属性大部分有继承)/ 行内元素和块级元素 / html的…

【git】git使用教程

1、版本管理工具 如果有一个软件能记录我们对文档的所有修改,所有版本,这类软件我们一般叫做版本控制工具。 特性“ 能够记录历史版本,回退历史版本团队开发,方便代码合并 2、版本管理工具介绍 svn、git svn是集中式版本控制…

音视频开发(一)ffmpeg 简单学习

前言 简单音视频处理。 学习自: 小破站FFmpeg最强教学丨入门FFmpeg看这一篇就够了丨从入门到放弃系列_哔哩哔哩_bilibili 01 下载、配置_哔哩哔哩_bilibili 基础知识 音视频处理基本都是:采样-处理得到帧队列-编码得到包队列-封装得到文件。 视频…

视频分辨率/帧率/码率选择参考

1. 视频码率与分辨率的参考表 1080*720的分辨率,用5000K左右; 720*576的分辨率,用3500K左右; 640*480的分辨率,用1500K左右。 2. 计算公式 基本算法:码率(kb…

selenium 根据【关键词】获取知网文献信息

哈喽大家好,我是咸鱼 之前咸鱼写过几篇关于知网爬虫的文章,后台反响都很不错。虽然但是,咸鱼还是忍不住想诉苦一下 有些小伙伴文章甚至代码看都没看完,就问我 ”为什么只能爬这么多条文献信息?“(看过代码…

SpringMVC 资源状态转移RESTful

文章目录 1、RESTful简介a>资源b>资源的表述c>状态转移 2、RESTful的实现HiddenHttpMethodFilterRESTful案例 1、RESTful简介 REST:Representational State Transfer,表现层资源状态转移。 a>资源 资源是一种看待服务器的方式&#xff0c…

【面试题08.06.汉诺塔问题】

目录 一、题目描述二、算法原理三、代码实现 一、题目描述 二、算法原理 三、代码实现 class Solution { public:void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {int nA.size();_hanota(n,A,B,C);}void _hanota(int n,vector&l…

升级降级苹果手机iOS系统工具iMazing2024

像任何计算设备一样&#xff0c;iPhones和iPads偶尔也会出现问题。有时iOS会崩溃&#xff0c;你需要重新安装它&#xff0c;以确保你可以继续使用设备&#xff0c;而不会丢失任何数据。有时你会看到一个黑屏&#xff0c;你不能用你的设备做任何事情。有时iPhone或iPad会陷入循环…

VR酒店专业情景教学演示

VR酒店情景教学为学生带来的全新学习体验。在这个虚拟环境中&#xff0c;学生可以亲身经历各种酒店管理场景&#xff0c;从客房清洁、餐厅服务&#xff0c;到客人接待、突发事件处理&#xff0c;都能得到生动的模拟和实践。 客房清洁是酒店管理中最基础却也最重要的一环。通过V…

问题 R: 超级楼梯(递推,基础DP)查表

得到递推表达式&#xff1a; f(1)0&#xff0c;因为开始就站在第1级台阶上&#xff1b; f(2)1&#xff0c;只能从第1级台阶上1级&#xff1b; f(3)2&#xff0c;只能从第1级台阶上2级&#xff0c;或只能从第2级台阶上1级&#xff1b; f(n)f(n-2)f(n-1)&#xff0c;n>3 …

使用 Python 连接到 PostgreSQL 数据库

本文介绍了创建与 PostgreSQL 上的数据库的连接的过程。 我们需要安装 PostgreSQL 和创建数据库等先决条件&#xff0c;如下所述。 在系统中安装 PostgreSQL 顾名思义&#xff0c;PostgreSQL 是一款为高效管理数据库系统而创建的 SQL 系统软件。 在连接Python之前需要创建数据…

串行原理编程,中文编程工具中的串行构件,串行连接操作简单

串行通信原理编程&#xff0c;中文编程工具中的串行通信构件&#xff0c;串行通信连接设置简单 编程系统化课程总目录及明细&#xff0c;点击进入了解详情。https://blog.csdn.net/qq_29129627/article/details/134073098?spm1001.2014.3001.5502 串行端口 是串行的基础&#…

springboot的缓存和redis缓存,入门级别教程

一、springboot&#xff08;如果没有配置&#xff09;默认使用的是jvm缓存 1、Spring框架支持向应用程序透明地添加缓存。抽象的核心是将缓存应用于方法&#xff0c;从而根据缓存中可用的信息减少执行次数。缓存逻辑是透明地应用的&#xff0c;对调用者没有任何干扰。只要使用…

Python---break关键字对for...else结构的影响

for循环中添加else结构 循环可以和else配合使用&#xff0c; else下方缩进的代码指的是当循环正常结束之后要执行的代码。 强调&#xff1a; 循环 正常结束&#xff0c;else之后要执行的代码。 非正常结束&#xff0c;其else中的代码是不会执行的。&#xff08;如遇到br…

2023年第四届MathorCup高校数学建模挑战赛——大数据竞赛B题解题思路

比赛时长为期7天的妈杯大数据挑战赛如期开赛&#xff0c;为了帮助对B题有更深的理解&#xff0c;这里为大家带来B题的初步解题思路。 赛道B&#xff1a;电商零售商家需求预测及库存优化问题 由于妈杯竞赛分为初赛复赛&#xff0c;因此&#xff0c;对于B题大家仅仅看到了预测相…

gin 框架出现runtime error: index out of range [0] with length 0

之前是这样的&#xff1a; category : c.Request.Form["type"][0] 加上这一句就变成了 fmt.Println(c.Request.FormFile("type")) category : c.Request.Form["type"][0]

AIGC如何助力产品研发的创新和性能提升

1、现有的产品和系统的升级 a&#xff09;、关键算法的替换&#xff0c;用深度学习来替换&#xff0c;用数学来描述&#xff1a; 需要定义好中间状态的和&#xff0c;总体过程是,中间的过程,替换为。 总体过程表示成下面的方式: 完成替换过程&#xff1a; 。 b&#xff09;…