大神之路:重学Android——Android多媒体MediaPlayer

《重学安卓》两周年,kotlin协程处理并发 但十分令人遗憾的是,本是从 “实事求是” 出发概括的术语,却频繁被人拿去 “点缀文章” 和 “挂羊头卖狗肉”,这些滥用行为,无形中扭曲和破坏了术语 “实事求是” 的形象, 所以过去两年里,我们积极地举报 “培训机构的洗稿软文”,以及在相关文章的评论区补充参考文献来源, 非常感谢小伙伴们的主动反馈。 本质概括一览 基于深度思考,我们确立下来并广泛传播的 “本质概括” 包括但不限于: Jetpack 架构组件本质: Lifecycle 的本质是解决 “生命周期管理” 的一致性问题 LiveData 的本质是解决 阅读详情

大神之路:重学Android——Android多媒体MediaPlayer

引言

最近发现Android开发中使用的知识越来越不得心应手了,有好多的API方法都记得不太清楚了,所以打算重新学习一遍,今天正好项目中有音乐播放的需求,回想一下Android多媒体的相关的知识,但是在开发中怎么也想不起来了,个人很讨厌这种模棱两可的感觉,期待行云流水一般的编码能力。所以决定要重新学习Android相关的知识。 正好借着项目的机会把Android多媒体重新学习一遍。

MediaPlayer介绍

Android多媒体中的MediaPlayer,我们可以通过这个API来播放音频和视频。通过该MediaPlayer中的一个重要组件。通过该类,我们可以以最方便的步骤来实现音视频的播放。

MediaPlayer支持的媒体来源:

  • 内部的URL 可以通过ContentResolver来获取
  • 外部的URL 以流的形式
  • 对于Android所支持的媒体格式列表

相关方法详解

  1. 获得MediaPlayer实例: 可以直接new 或者调用create方法创建
      MediaPlayer mp = new MediaPlayer()
  2.   MediaPlayer mp = MediaPlayer.create(this,R.raw.test);
  3. 另外create还有另一种的形式:
      create(Context context,Uri uri,SurfaceHolder holder)

  4. 通过Uri和指定SurfaceHolder,创建一个多媒体播放器
  5. tips:如果创建MediaPlayer如果使用create方法,第一次启动前不需要再调用prepare(),如果是使用构造方法构造的话,则需要调用一次prepare()方法
  6. 设置播放文件:
     //raw下的资源
  7. MediaPlayer.create(this,R.raw.test);
  8. //本地文件路径
  9. mp.setDataSource("/sdcard/test.mp3");
  10. //网络URL文件
  11. mp.setDataSource("http://www.xxx.com/music/test.mp3");
  12. 其他方法
    • getCurrentPosition(): 得到当前的播放位置
    • getDuration():得到文件的时间
    • getVideoHeight() 得到视频高度
    • getVideoWidth() 得到视频宽度
    • isLooping():是否循环播放
    • isPlaying():是否正在播放
    • pause():暂停
    • prepare():准备(同步)
    • prepareAsync():准备(异步)
    • relase():释放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) 视频尺寸监听
    • setScrennOnWhilePlaying(boolean screenOn):设置是否使用SurfaceHolder显示
    • setVolume(float leftVolume,float rightVolume)设置音量
    • start():开始播放
    • stop():停止播放

官方文档中,从其他两种途径音频的实例

  • 内部URL:
      Uri uri =
  •   MediaPlayer mediaplyer = new MediaPlayer();
  •   mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
  •   mediaPlayer.setDataSource(getApplicationContext(),myUri);
  •   mediaPlayer.prepare();
  •   mediaPlayer.start();
  • 外部URL:
      String url = "http://.....";
  •   MediaPlayer mediaPlayer = new MediaPlayer();
  •   mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
  •   mediaPlayer.setDataSource(url);
  •   mediaPlayer.prepare();
  •   mediaPlayer.start();

Note:假假如你通过一个URL以流的形式播放在线音频文件,该文件必须可以进行渐进式下载

状态


解释:

  • MediaPlayer对象被刚刚用new操作符创建或是调用了reset()方法后,它就处于Idle状态。当调用了release()方法后,它就处于End状态。这两种状态MediaPlaer对象的生命周期
  • 在一个新构建的MediaPlayer对象和一个调用了reset()方法的MediaPlayer对象的差别。在处于Idle状态时,调用getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamType(int), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(int), prepare() 或者 prepareAsync() 方法都是编程错误。当一个MediaPlayer被重建的时候,内部的播放引擎和对象的状态都没有改变,这个时候调用以上的方法,框架将无法回调客户端程序注册的OnErrorListener()方法;但若这个MediaPlayer对象调用reset()方法之后,再调用以上的那些方法,内部播放引擎就会回调客户端程序注册的OnErrorListener.onError()方法,并将错误状态传入。
  • 一旦一个MediaPlayer对象不再被使用,应立即调用release()方法来释放在内部播放引擎中与这个MediaPlayer对象关联的资源,调用 release()后,播放器会进入end状态,一旦MediaPlayer对象进入End状态,它不能再被使用,也没有办法再迁移到其它状态
  • 由于某些原因MediaPlayer会发生错误,一旦发生错误,MediaPlayer对象会进入到Error状态,此时可调用reset()方法来把这个对象恢复成Idle状态
  • 调用setDataSource(FileDescriptor)方法,或setDataSource()方法,会使处于Idel状态的MediaPlayer的对象迁移到Initialized状态
  • 当MediaPlayer处于其它状态下,调用setDataSource()方法,会抛出异常
  • 在开始播放之前,MediaPlayer对象必须要进入Prepared状态
  • 在不合适的状态下调用prepare()和prepareAsync()方法会抛出异常,当MediaPlayer对象处于Prepared状态的时候,可以调整音频/视频的属性,如音量,播放时是否一直亮屏,循环播放等。
  • 要开始播放,必须调用start()方法,当方法返回时,MediaPlayer的对象处于Started状态。
  • 播放可以被暂停,停止,以及调整当前播放的位置,当调用pause()方法并返回时,会使MediaPlayer对象进入Paused状态。started与paused状态的互相转换在内部的播放引擎中是异步的。
  • 调用start()方法会让一个处于Paused状态的MediaPlayer对象从之前暂停的地方恢复播放。调用start()方法返回后,MediaPlayer对象的状态会变成Started状态
  • 调用stop()会停止播放,会让MediaPlayer进入Stopped状态
  • 当播放到流的末尾,播放就完成了
  • 如果没有开启循环模式,那么内部的播放引擎会调用客户端提供的OnCompletion.onCompletion()回调方法,内部引擎一旦调用了onCompletion()回调方法说明这个MediaPlayer对象进入了PlaybackCompleted状态
  • 当处于PlaybackCompleted状态的时候,可以再调用start()方法来让这个MediaPlayer对象再进入Started状态
      在停止播放的是代码应这样写才可以在下次播放时重新开始播放 
  •       private void stop(){ 
  •   if(mediaplayer!=null){//mediaplayer 是M    ediaPlayer的 instance 
  •   mediaplayer.stop(); 
  •       try{ 
  •       mediaplayer.prepare();//stop后下次重新播放要首先进入    prepared状态 
  •       mediaplayer.seekTo(0);//须将播放时间设置到0;这样才能在下次播放是重新开始,否则会继续上次播放 
  •       }catch(IOException e){ 
  •       e.printStackTrace(); 
  •   } 
  •   }   
重学Android基础系列篇(五):Android虚拟机指令 本系列文章主要是汇总了一下大佬们的技术文章,属于Android基础部分,作为一名合格的安卓开发工程师,咱们肯定要熟练掌握java和android,本期就来说说这些~ 阅读详情

相关推荐

重学Android基础系列篇(三):架构动态编程技术原理

本系列文章主要是汇总了一下大佬们的技术文章,属于Android基础部分,作为一名合格的安卓开发工程师,咱们肯定要熟练掌握java和android,本期就来说说这些~

m0_64420071的博客 1334

Java泛型遇到多态与Java泛型边界

说明: 今天,继续学姐java编程思想-泛型这一章的时候,对于通配符的理解不够明白,于是又网上查了些资料,发现一篇写的很好的文章,在此记录学习一下

yx19861211的博客 1812

别再手动写样式了!5分钟用WeUI v2.6.11搞定微信风格H5页面

本文介绍了如何使用WeUI v2.6.11快速搭建微信风格H5页面,显著提升开发效率。WeUI作为微信官方维护的UI框架,提供像素级还原的组件,开箱即用,支持CDN引入,适合快速原型开发。文章还分享了核心组件实战、企业级项目中的进阶用法以及适用场景分析。

weixin_33738555的博客 596

[Android开发] 重学Android-EditText的进阶操作

EditText是我们常用的输入框控件,平常我们只是使用它输入文本,这里记录一些它不太常见的操作和一些解决方案。

Eqiqi的博客 1656

【面试经验】大疆笔试-计算机视觉算法B卷

3、a=np.random.randn(3,3) b=np.random.randn(3,1) ,那么c=a*b的维度应该是:*是元素乘法或者torch.mul,@才是矩阵乘法或者torch.matmul,不会触发广播机制;8、将分辨率降低一半时,精标定内参(fx、fy、cx、cy、k1、k2、k3)焦距、光心、畸变系数将分别变成(fx、fy、cx/2、cy/2、k1、k2、k3),只能搜到光心变成一半,畸变系数不变。12、KLT算法在频闪光源、重复纹理、高速机动、环境照度低的情况下效果显著下降。

litterfinger的博客 1444

【视频编码学习】AVS3参考软件HPM-4.1简单配置运行

1、用Visual Studio2017打开HPM-4.1文件夹 2、找到文件夹目录下x86_windows文件夹,因为是在win上运行该代码 3、然后找到对应vs版本(我当时2017版)的解决方案sln文件,双击打开可以看到该解决方案下的全部项目。 4、重新生成解决方案时发现提示sdk版本问题,所以右键点击所有的项目,选择重定向项目,修改一下sdk版本。 ...

谦虚勤奋诚实感恩 3100

【亲测免费】 重学安卓:深入理解Android开发精髓

重学安卓:深入理解Android开发精髓 项目基础介绍 本项目名为“重学安卓”,是一个专注于Android开发技术和架构模式的开源项目。项目主要由Java语言编写,同时也包含部分CMake和C++代码。该项目旨在深入探讨Android开发中的各种概念,分享作者的深度思考和实战经验,帮助开发者更好地理解和运用Android技术。 核心功能 项目的核心功能包括: 深度技术文章分享:项目包含了一系列关...

gitblog_00034的博客 482

SPAD单光子雪崩二极管:从基础原理到前沿应用

本文深入解析SPAD单光子雪崩二极管的基础原理、硬件实现关键及核心性能参数,并探讨其在激光雷达、量子通信和生物医学成像等前沿领域的创新应用。SPAD凭借超高灵敏度和精确的时间分辨率,正在推动自动驾驶、量子技术和医学诊断等领域的革命性发展。

weixin_30335575的博客 661

重学安卓项目简介与入门指南

重学安卓项目简介与入门指南 1. 项目目录结构及介绍 . ├── app # 主应用模块,包含了Android应用程序的源码 │ ├── build.gradle # 应用模块的构建脚本,定义依赖项和其他构建设置 │ └── ... # 其他应用模块相关文件 ├── gradle # 包含Gradle构建...

gitblog_00758的博客 439

SPI 协议帧格式深度解析:从 8 位数据到 16 位扩展的 3 种模式

本文深入解析SPI协议的帧格式,涵盖从8位标准到16位扩展的三种模式。通过详细讲解SPI时钟模式、数据宽度配置及实际应用案例,帮助开发者掌握SPI外设的深度定制能力,提升嵌入式系统开发效率。特别适用于连接传感器、存储器和显示器等高速通讯场景。

weixin_34110749的博客 345

【雕爷学编程】Arduino动手做(45)---红外光电避障传感器模块4

雕爷学编程,Arduino动手做,开源硬件,创客传感器,红外光电避障传感器模块

雕爷学编程 2503

《重学安卓》:深度思考与实践的结晶

《重学安卓》:深度思考与实践的结晶 项目介绍 《重学安卓》是一个专注于Android开发的付费专栏,自2019年6月在小专栏平台开设以来,已经连接了1111名优秀开发者。这个项目不仅仅是一个学习资源,更是一个深度思考和实践的社区。通过基于“第一性原理”和“实事求是”精神的深度思考方式,项目团队开源了一系列高频使用的仓库,包括《UnPeek-LiveData》等,这些仓库被腾讯音乐、BMW、TCL等...

gitblog_01156的博客 741

复现报告:《多回路人机控制系统仿真及II型PIO分析》方法复现与代码实现

本文复现了谭文倩硕士论文《多回路人机控制系统仿真及II型PIO分析》中的关键方法,重点实现了频域驾驶员模型辨识和参数灵敏度分析。通过数字化提取论文图表数据,构建了结构驾驶员模型传递函数,并验证了参数变化对系统特性的影响。采用MATLAB实现了描述函数计算、模型参数辨识和灵敏度分析算法,为后续神经网络模型辨识和II型PIO研究奠定了基础。由于缺乏原始实验数据,部分结果通过数值模拟获得,但仍有效重现了论文的核心分析方法。~~~~~

huanghm88的专栏 175

2024年安卓最全重学设计模式——你真的面向对象了吗?,三年老Android经验面经

【Android开发核心知识点笔记】【Android思维脑图(技能树)】【Android核心高级技术PDF文档,BAT大厂面试真题解析】【Android高级架构视频学习资源】网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化学习资料的朋友,可以戳这里获取一个人可以走的很快,但一群人才能走的更远!

2401_84562576的博客 901

JSON 与 JSON-RPC 的区别

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,基于文本,采用人类可读的语法来表示结构化数据。它起源于JavaScript,但如今已被几乎所有主流编程语言支持。标准文档:RFC 4627数据类型:支持 String、Number、Boolean、Null、Object、Array 六种基本类型格式示例"name": "张三","age": 30,JSON-RPC(JSON Remote Procedure Call)是一种远程过程调用(RPC)协议。

h a 6 6 6 c k 为 你解决复杂难题! 144

基于MATLAB的小波包分解(WPD)算法详解

本文详细介绍了基于MATLAB的小波包分解(WPD)算法。WPD作为信号处理领域的重要技术,继承并发展了小波分析的优点,通过正交镜像滤波器组将信号分解为不同频率子带,形成完整的二叉树结构。相比传统小波变换,WPD具有更精细的频带划分、自适应基选择能力和更高的灵活性,特别适合分析非平稳信号。文章系统阐述了WPD的数学原理、算法实现流程及其在机械故障诊断、生物医学信号处理等领域的应用。通过MATLAB代码示例展示了WPD的具体实现方法,并分析了不同参数设置对分解效果的影响,为工程实践提供了有价值的参考。

qq_42212808的博客 292

重学 Android 之 Handler 机制

重学 Android 之 Handler 机制 一、前言 在 Android 开发中,handler 机制的使用几乎随处可见,作为面试中的常客,我们真的了解 handler 吗? 想必很多同学会想,当然了,handler 机制不就是 Looper 、handler、MessageQueue吗? 下面抛砖引玉,我们先来看看这些问题 为什么子线程中不可以直接 new Handler() 而主线程中可以? 真的只能在主(UI)线程中更新 ...

戎马书生IT的博客 463

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

重学Android:从位运算到二进制表示(零)

以下内容针对非科班同学,可以快速掌握位运算和二进制表示等计算机基础运算知识,看过源码的同学都知道,源码中大量运用了位运算知识,如果你对这方面不了解的话,看起来是比较困难的,如果你工作接触到蓝牙数据,串口数据收发等内容,这方面更是你必须了解的。

WriteBug001的博客 1356

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Android-重学kotlin(协程基础)新学习总结

Kotlin协程是轻量级的线程任务,可灵活切换线程并实现非阻塞并发。协程通过launch、async和runBlocking启动,其中launch返回Job但不返回结果,async返回Deferred可获取结果,runBlocking会阻塞线程应谨慎使用。协程遵循结构化并发原则,父子协程间存在生命周期绑定和异常传播机制,可通过Job监控和操控状态。挂起函数和CPS转换有效解决了回调地狱问题。同步机制采用Mutex互斥锁,其非阻塞特性优于线程锁,withLock{}能自动处理锁释放。协程通过延迟执行(dela

2301_80329517的博客 1135

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

重学 Android 自定义 View 系列(十):带指针的渐变环形进度条

该篇文章根据前面重学 Android 自定义 View 系列(六):环形进度条拓展而来。绘制指针的步骤:调整指针的绘制半径:确保指针贴合圆环外侧,加入一个 outerSize 参数用于控制指针漏出圆环的长度。计算指针位置:使用三角函数计算图片中心点坐标。旋转画布并绘制图片(关键):将画布旋转到指定角度后,再绘制指针图片。用到的三角函数原理如下,再重温一下学校的知识:),因为在Java中Math函数计算三角函数用的是弧度而不是角度,所以代码使用了进行了角度转弧度。

WriteBug001的博客 1324

Android 中封装优雅的 MediaPlayer 音频播放器,支持多个播放器

使用 AudioPlayer 类播放音频的示例代码

白高林的专栏 3143

Windows Media Player单例模式

原文链接:http://www.cnblogs.com/qy5201314/articles/2599205.html 1 #region 单例模式 2 public static bool ExitNo = false; //判断程序是否退出 3 static FrmPlayer newPlayer; //声明一个静态的FrmPlayer对象 4 ...

java开发指南博客 【转载】 214

Android进阶-Gradle

百度App技术 - Gradle 与 Android 构建入门 Gradle 爬坑指南 – 概念初解 Android Gradle (一)Gradle的Android插件入门 Android Gradle (二)签名配置和依赖管理 Gradle是一个框架,作为框架,它负责定义流程和规则。而具体的编译工作则是通过插件的方式来完成的。比如编译Java有Java插件,编译Groovy有Groovy插件,编译Android APP有Android APP插件,编译Android Library有Android

Donkey的博客 1696

重学安卓:Activity 的快乐你不懂!

本文由作者 KunMinX 原创,已授权某公众号独家转载

weixin_34334744的博客 1195

android重学知识点

clzolo的博客 2524

Android MediaPlayer播放MIDI文件stop后无法prepare,之后start也失败

创建midi文件后 调用start播放正行 调用stop声音也停止了 但是之后再start或先prepare再start也不行 自后解决方法是用pause代替stop,下次播放用 seekTo(0); start(); 就可以播放了   但是其他的ARM或者WAV文件好像就正常不用这麻烦?

brook0344的专栏 4644
上一篇: [Android工具类]Android File工具类
下一篇: 大神之路:Java再撸一遍:Java多特么的线程
ProbuINg
博客等级 码龄14年 10粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值