自定义MediaPlayer(一) -- 关于MediaPlayer的碎碎念

本文探讨了在Android平台上使用MediaPlayer进行音频播放时遇到的问题,特别是在需要边解密边播放的场景下。介绍了AudioTrack作为解决方案的优势,并给出了具体的实现代码。

一、 不可复用的MediaPlayer

  MediaPlayer,对每个android开发者来说,都不陌生。

  简单的调用

  

   mMediaPlayer = new MediaPlayer();
   mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
   mMediaPlayer.setOnPreparedListener(this);
   mMediaPlayer.setOnErrorListener(this);
   mMediaPlayer.setOnCompletionListener(this);
   mMediaPlayer.setOnInfoListener(this);
   mMediaPlayer.setDataSource(this.mUrlString);
   mMediaPlayer.prepareAsync();

  这几段代码,调用起来也是得心应手。对于简单的歌曲播放,确实满足了平常应用的开发。


  可是,程序员的天敌 -- 策划大爷,他们就看不得你们这么安逸的Working。

  现在问题来了,策划说要对音频文件分段加密,意味着我们就是要边解密边播放了。

  带着这个问题,我开始研究MediaPlayer,看看能不能一段一段文件播放。结果自然是没有了。。

   

  setDataSource(String path);//设置文件的路径
  setDataSource(FileDescriptor fd);//设置文件的流标识
   

  最最无奈的是,MediaPlayer是用C++编写的。不就是操作流文件嘛。干嘛写的这么复杂而且还没办法自定义。

二、寻找新的MediaPlayer

  无奈归无奈,功能还是要去实现的。谁让我们是快乐的IT民工呢!

  好吧,开始翻墙,google,等待浏览器缓冲,开启有道翻译!

  http://stackoverflow.com/questions/10060165/android-mediaplayer-buffer-size-in-ics-4-0

  这是不错的方案,就是麻烦了点。自己搭建一个SocketService,Service读取服务器上的流文件传给MediaPlayer播放。

  大体就是:

  

   1. MediaPlayer.SetDataSource("127.0.0.1:123456");
   2. stream = inputStream.read();
   3. buff = decode(stream);//解密
   4. output.write(buff, 0, readBytes);

  这是个不错的方案。但是操作起来就麻烦了。音乐盒播放器,经常要切换歌曲,每次切换歌曲都要去对Socket和MediaPlay经常操作,就会产生很多的异步问题。给自己增加无数的bug。。。。

  将Socket的方案保留,做个备胎。

三、 开源的Android,没有不能实现的功能

   有没有类似,outputStream.write的方式呢?就是不断的解码,然后不断的写入流,最后底层系统不断的播放音频流。

   经过一定的努力,找到了AudioTrack类。

   http://www.cnblogs.com/innost/archive/2011/01/09/1931457.html

 trackplayer.write(bytes_pkg, 0, bytes_pkg.length) ;//往track中写数据
  看到这段代码,所有的问题都引刃而解了。

四、神奇的AudioTrack

    AudioTrack类实现将音频数据输出到音频设备中。
    该类的SDK文档是如下描述的:
    The AudioTrack class manages and plays a single audio resource for Java applications. It allows streaming of PCM audio buffers to the audio sink for playback. This is achieved by "pushing" the data to the AudioTrack object using one of the write(byte[], int, int), write(short[], int, int), and write(float[], int, int, int) methods. 

   以下再摘自网上的一段代码,结束本篇幅:

  //根据采样率,采样精度,单双声道来得到frame的大小。

    int bufsize = AudioTrack.getMinBufferSize(8000,//每秒8K个点
   AudioFormat.CHANNEL_CONFIGURATION_STEREO,//双声道
    AudioFormat.ENCODING_PCM_16BIT);//一个采样点16比特-2个字节
    //注意,按照数字音频的知识,这个算出来的是一秒钟buffer的大小。
    //创建AudioTrack
    AudioTrack trackplayer = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
  AudioFormat.CHANNEL_CONFIGURATION_ STEREO,
  AudioFormat.ENCODING_PCM_16BIT,
  bufsize,
    AudioTrack.MODE_STREAM);//
    trackplayer.play() ;//开始
    trackplayer.write(bytes_pkg, 0, bytes_pkg.length) ;//往track中写数据
    ….
    trackplayer.stop();//停止播放
    trackplayer.release();//释放底层资源。

内容概要:本文系统介绍了基于Matlab构建的简化单粒子(SPM)电化学模型及其参数化方法,聚焦于锂离子电池的降阶电化学模型P2D的简化实现,涵盖模型建立、参数辨识、测试数据提供及仿真验证全流程。资源核心在于深入剖析电化学模型的关键参数提取与优化过程,帮助科研人员理解电池内部反应机理与数学建模范式,支持后续的模型扩展与工程应用。文档不仅提供了完整的SPM模型代码与参数拟合工具,还整合了丰富的科研辅助资源,包括智能优化算法、机器学习、电力系统管理、路径规划、信号处理等多个领域的Matlab/Simulink仿真案例与Python实现方案,极大拓展了该模型在电池健康状态(SOH)估计、寿命预测、充放电控制策略等方向的应用潜力。; 适合人群:具备定Matlab编程能力,从事新能源技术、电化学建模、电池管理系统(BMS)、储能控制、自动化仿真等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①开展锂离子电池电化学模型的建模与参数辨识研究;②实现P2D与SPM降阶模型的仿真与实验验证;③结合实测数据进行模型参数拟合与精度优化;④拓展应用于电池老化分析、SOH估算、充放电策略设计及储能系统动态响应研究。; 阅读建议:建议读者按照文档结构循序渐进学习,重点研读SPM模型构建与参数辨识章节,结合所提供的测试数据与代码进行动手实践,并积极借鉴附带的智能算法与机器学习模块以提升模型鲁棒性与预测精度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值