Android中播放音乐的几种方式

电脑杂谈  发布时间:2019-08-26 23:03:20  来源:网络整理

android ios 音频格式_android 音频播放框架_android 音频播放

前几天一直在研究RxJava2,也写了记录了几篇博客,但由于工作任务缘由,需要探究音频相关的常识,暂时放下Rxjava,本文的demo中,MediaPalyer 部分使用RxJava编写一点逻辑,其中涉及,RxJava2的被压、解除订阅等知识点,虽然简单,最至少没有丢了RxJava,后续Rxjava会再次研究,做记录.

andorid提供了对声音和视频处理的api包android.media.本文编写了对于这几种方式播放的Demo,文章最终贴出。

对于android音频的播放,这个类也许是你们最熟知的了,从入门就经常想编写一个自己的音乐播放器,有木有?MediaPlayer确实强大,提供了对音频播放的各类控制,生命周期:

这里写图片描述

1. MediaPlayer支持:AAC、AMR、FLAC、MP3、MIDI、OGG、PCM等格式

2. 播放Raw下的元数据

//直接创建,不需要设置setDataSource
mMediaPlayer=MediaPlayer.create(this, R.raw.audio);
mMediaPlayer.start();

3. MediaPlayer设置播放源的4中形式

//从sd卡中加载音乐
mMediaPlayer.setDataSource("../music/samsara.mp3") ;
//从网路加载音乐
mMediaPlayer.setDataSource("http://..../xxx.mp3") ;
//需使用异步缓冲
mMediaPlayer.prepareAsync() ;
//需将资源文件放在assets文件夹
 AssetFileDescriptor fd = getAssets().openFd("samsara.mp3");
 mMediaPlayer.setDataSource(fd)
 mMediaPlayer.prepare() ;
 Ps:此方法系统需大于等于android 
这个方法没什么好说的,一般通过ContentProvider获取Android系统提供
的共享music获取uri,然后设置数据播放

android ios 音频格式_android 音频播放框架_android 音频播放

 //需将资源文件放在assets文件夹
 AssetFileDescriptor fd = getAssets().openFd("samsara.mp3");
 mMediaPlayer.setDataSource(fd, fd.getStartOffset(), fd.getLegth())
 mMediaPlayer.prepare() ;

4. 注意点

资源占用量较高、延迟时间较长、不支持多个音频同时播放等

//创建播放时间格式化工具
mFormat = new SimpleDateFormat("mm:ss");
//创建MediaPlayer和设置
mPlayer = new MediaPlayer() ;
mSeekBar.setOnSeekBarChangeListener(new MySeekBarChangeListener());
mPlayer.setOnPreparedListener(new MyOnPrepareListener());
mPlayer.setOnCompletionListener(new MyOnCompletionListener());
/**
    * 从assets资源文件夹中播放
     * @param name
     */
    private void playSoundFromA(String name) {
        if (mPlayer.isPlaying()) {
            mPlayer.stop();
        }
        // 设置当前播放歌曲的名字
        title.setText(names[current]);
        mPlayer.reset();
        AssetFileDescriptor afd = getAssetFileDescriptor(name);
        try {
            mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            hasResource = true;
            mPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

SoundPool支持多个音频文件同时播放(组合音频也是有上限的),延时短,比较合适短促、密集的画面,是游戏开发中音效播放的福音。

SoundPool(int maxStreams, int streamType, int srcQuality)
从android5.0开始此方法被标记为过时,稍微说以下几个参数。
1.maxStreams :允许同时播放的流的最大值
2.streamType :音频流的类型描述,
               在Audiomanager中有种类型声明,游戏应用通常会使用流媒体音乐。
3. srcQuality:采样率转化质量
//设置描述音频流信息的属性
AudioAttributes abs = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build() ;
SoundPool mSoundPoll =  new SoundPool.Builder()
                .setMaxStreams(100)   //设置允许同时播放的流的最大值
                .setAudioAttributes(abs)   //完全可以设置为null
                .build() ;
// 几个load方法和上文提到的MediaPlayer基本一致,不做多的解释
//------------------------------------------------------------
int load(AssetFileDescriptor afd, int priority)
int load(Context context, int resId, int priority)
int load(String path, int priority)
int load(FileDescriptor fd, long offset, long length, int priority)
//-------------------------------------------------------------
// 通过流id暂停播放
final void pause(int streamID)
// 播放声音,soundID:音频id; left/rightVolume:左右声道(默认1,1);loop:循环次数(-1无限循环);rate:播放速率(1为标准)
final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
//释放资源(很重要)
final void release()
//恢复播放
final void resume(int streamID)
//设置指定id的音频循环播放次数
final void setLoop(int streamID, int loop)
//设置加载(因为加载是异步的,需要加载,完成后再播放)
void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener)
//设置优先级(同时播放个数超过最大值时,优先级低的先被移除)
final void setPriority(int streamID, int priority)
//设置指定音频的播放速率,0.5~2.0(rate>1:加快播放,反之慢速播放)
final void setRate(int streamID, float rate)
//停止指定音频播放
final void stop(int streamID)
//卸载指定音频
final boolean unload(int soundID)
//暂停所有音频的播放
final void autoPause()
//恢复所有暂停的音频播放
final void autoResum()

以上方式基本上是SoundPool的所有办法了,也都很常用。

看了Sounpool的api,是不是感觉对 streamID 和 soundID 一脸懵逼?

1. soundID:加载音乐资源时的返回值,int load(String path, int priority),这个int返回值就是soundID

android 音频播放框架_android ios 音频格式_android 音频播放

2. streamID:播放时返回的值,即play()方法的返回值

这两个值都很重要,需要缓存下来

注:我把SoundPool做了简单封装,SoundPoolUtil,会在文末上传,
有兴趣可下载看一下,时间比较急,还有很多不足的地方
//初始化SoundPool
if(Build.VERSION.SDK_INT >=  Build.VERSION_CODES.LOLLIPOP){
            AudioAttributes aab = new AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    .setUsage(AudioAttributes.USAGE_MEDIA)
                    .build() ;
            mSoundPool = new SoundPool.Builder()
                    .setMaxStreams(10)
                    .setAudioAttributes(aab)
                    .build() ;
        }else{
            mSoundPool = new SoundPool(60, AudioManager.STREAM_MUSIC,8) ;
        }
        mSoundPool = new SoundPool(60, AudioManager.STREAM_MUSIC,8) ;
        //设置资源加载
        mSoundPool.setOnLoadCompleteListener(new MyOnLoadCompleteListener());
//加载资源
/**
     * 加载指定路径列表的资源
     * @param map
     */
    public void loadR(Map<String, String> map){
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for(Map.Entry<String, String> entry : entries){
            String key = entry.getKey() ;
            if(checkSoundPool()){
                if(!idCache.containsKey(key)){
                    idCache.put(key, mSoundPool.load(entry.getValue(),1)) ;
                }
            }
        }
    }
    /**
     * 播放指定音频,并返用于停止、暂停、恢复的StreamId
     * @param name
     * @param times
     * @return
     */
    public int play(String name, int times){
        return this.play(name,1,1,1,times,1) ;
    }


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-120691-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...