`

Android 实现多个Audio文件的顺序播放

阅读更多

最近开发Android通讯录播报号码时需用到播放多个连续音频文件,用传统的MediaManager无法满足复杂性需求,而 SoundPool则满足,于是写了一个SoundPool的管理类SoundManager管理音频的播放。

代码如下:

package com.yous365.android.util;

import org.xml.sax.SAXException;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Handler;
import android.util.Log;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import javax.xml.parsers.ParserConfigurationException;

public class SoundManager {

    private SoundPool mSoundPool;

    private HashMap<String, Integer> mSoundPoolMap;

    private AudioManager mAudioManager;

    private Context mContext;

    private Handler mHandler = new Handler();

    private Vector<Integer> mKillSoundQueue = new Vector<Integer>();

    private VoicePhoneNumberUtil util;

    private long delay = 1000;

    private long seperateTime = 700;

    private float rate = 1.0f;

    private String locale;

    static private SoundManager _instance;

    /**
     * Requests the instance of the Sound Manager and creates it if it does not
     * exist.
     * 
     * @return Returns the single instance of the SoundManager
     */
    static synchronized public SoundManager getInstance() {
        if (_instance == null)
            _instance = new SoundManager();
        return _instance;
    }

    /**
     * 
     */
    private SoundManager() {
        util = VoicePhoneNumberUtil.getInstance();
    }

    /**
     * Initialises the storage for the sounds
     * 
     * @param theContext The Application context
     */

    public void initSounds(Context theContext) {
        mContext = theContext;
        mSoundPool = new SoundPool(1,
                AudioManager.STREAM_MUSIC, 0);
        mSoundPoolMap = new HashMap<String, Integer>();
        mAudioManager = (AudioManager) mContext
                .getSystemService(Context.AUDIO_SERVICE);
    }

    /**
     * Add a new Sound to the SoundPool
     * 
     * @param key - The Sound Index for Retrieval
     * @param SoundID - The Android ID for the Sound asset.
     */

    public void addSound(String key, int SoundID) {
        mSoundPoolMap.put(key,
                mSoundPool.load(mContext, SoundID, 1));
    }
    /**
     * 
     * @param key the key we need to get the sound later
     * @param afd  the fie store in the asset
     */
    public void addSound(String key, AssetFileDescriptor afd) {
        mSoundPoolMap.put(key, mSoundPool.load(
                afd.getFileDescriptor(),
                afd.getStartOffset(), afd.getLength(), 1));
    }
    
    /**
     * play the sound loaded to the SoundPool by the key we set
     * @param key  the key in the map
     */
    public void playSound(String key) {

        int streamVolume = mAudioManager
                .getStreamVolume(AudioManager.STREAM_MUSIC);
        streamVolume = streamVolume
                / mAudioManager
                        .getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        int soundId = mSoundPool.play(
                mSoundPoolMap.get(key), streamVolume,
                streamVolume, 1, 0, rate);
        mKillSoundQueue.add(soundId);
        // schedule the current sound to stop after set milliseconds
        mHandler.postDelayed(new Runnable() {
            public void run() {
                if (!mKillSoundQueue.isEmpty()) {
                    mSoundPool.stop(mKillSoundQueue
                            .firstElement());
                }
            }
        }, delay);

    }
    
    /**
     * 
     * @param key  the key in the map
     */
    public void playLoopedSound(String key) {

        int streamVolume = mAudioManager
                .getStreamVolume(AudioManager.STREAM_MUSIC);
        streamVolume = streamVolume
                / mAudioManager
                        .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        
        int soundId = mSoundPool.play(
                mSoundPoolMap.get(key), streamVolume,
                streamVolume, 1, -1, rate);

        mKillSoundQueue.add(soundId);
        // schedule the current sound to stop after set milliseconds
        mHandler.postDelayed(new Runnable() {
            public void run() {
                if (!mKillSoundQueue.isEmpty()) {
                    mSoundPool.stop(mKillSoundQueue
                            .firstElement());
                }
            }
        }, delay);
    }
    
  /**
   * play the sounds have loaded in SoundPool 
   * @param keys the files key stored in the map
   * @throws InterruptedException
   */
    public void playMutilSounds(String keys[])
            throws InterruptedException {
        int streamVolume = mAudioManager
                .getStreamVolume(AudioManager.STREAM_MUSIC);
        streamVolume = streamVolume
                / mAudioManager
                        .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        for (String key : keys) {
            Log.d("playMutilSounds", key);
            if (mSoundPoolMap.containsKey(key)) {
                int soundId = mSoundPool.play(
                        mSoundPoolMap.get(key),
                        streamVolume, streamVolume, 1, 0,
                        rate);
                //sleep for a while for SoundPool play 
                Thread.sleep(seperateTime);
                mKillSoundQueue.add(soundId);
            }

        }

        // schedule the current sound to stop after set milliseconds
        mHandler.postDelayed(new Runnable() {
            public void run() {
                if (!mKillSoundQueue.isEmpty()) {
                    mSoundPool.stop(mKillSoundQueue
                            .firstElement());
                }
            }
        }, delay);

    }

    /**
     * Loads the various sound assets
     * @param locale the load to load audio files
     */

    public void loadSounds(String locale)
            throws SAXException, IOException,
            ParserConfigurationException {
        Log.d("load locale", locale);
        this.locale = locale;
        AssetFileDescriptor afd;
        Map<String, String> audioFiles = util
                .getAudioFileConfig(locale,
                        mContext.getAssets());

        for (String key : audioFiles.keySet()) {
            afd = mContext.getAssets().openFd(
                    audioFiles.get(key));
            addSound(key, afd);
        }

    }

    /**
     * Stop a Sound
     * 
     * @param index - index of the sound to be stopped
     */
    public void stopSound(int index) {
        mSoundPool.stop(mSoundPoolMap.get(index));
    }

    /**
     * Deallocates the resources and Instance of SoundManager
     */
    public void cleanup() {
        mSoundPool.release();
        mSoundPool = null;
        mSoundPoolMap.clear();
        mAudioManager.unloadSoundEffects();
        _instance = null;

    }

    /**
     * unload all resource in the sound pool
     * support for user change VoiceLanguage or Locale or user close the voice function !
     */

    public void unloadAllSoundsIn() {
        if (mSoundPoolMap.size() > 0) {
            for (String key : mSoundPoolMap.keySet()) {
                mSoundPool.unload(mSoundPoolMap.get(key));
            }
        }
        mKillSoundQueue.clear();
        mSoundPoolMap.clear();
    }

    /**
     * set the speed of soundPool
     * 
     * @param i i<0 means slow i= 0 means normal i>0 means fast
     */
    public void setVoiceSpeed(int i) {
        if (i > 0) {
            rate = 1.2f;
        }
        else if (i < 0) {
            rate = 0.8f;
        }
        else {
            rate = 1.0f;
        }

    }

    /**
     * set the delay after one number's sound have played
     * 
     * @param i i<0 means short i= 0 means normal i>0 means long
     */
    public void setVoiceDelay(int i) {
        if (i > 0) {
            seperateTime = 700;
        }
        else if (i < 0) {
            seperateTime = 400;
        }
        else {
            seperateTime = 500;
        }

    }

    public String getLocale() {
        return locale;
    }

    public void setLocale(String locale) {
        this.locale = locale;
    }

}
 
0
3
分享到:
评论
1 楼 304580500 2011-10-12  
VoicePhoneNumberUtil 这个类是你自己实现的,怎么没贴出来,用不了这些代码呀

相关推荐

    android 语音顺序播放

    要实现语音顺序播放,我们需要创建多个`MediaPlayer`实例,分别对应不同的音频文件,并控制它们按顺序播放。 1. **初始化MediaPlayer** - 在使用`MediaPlayer`之前,必须先通过`setDataSource()`方法设置音频文件...

    android 开源播放器,AudioPlay 源码,可以快速运行对接版

    9. **文件选择与播放列表**:如果AudioPlay支持播放列表功能,那么源码将展示如何处理多个音频文件的顺序播放、跳转和添加删除操作。 10. **自定义控件和效果**:可能包含自定义音效设置,如均衡器、环绕声等,这些...

    AudioRecorder实现语音录取 并转换为wav文件

    在实现多段录音合并时,需要处理每个pcm文件的顺序读取和追加到新的wav文件中。这涉及到读取pcm文件的大小,计算新的.wav文件的data子块长度,并更新头信息。合并过程中需确保各音频片段的采样率、通道数等参数一致...

    Android局域网音频通信程序(AudioRecord采集,AudioTrack播放)

    `AudioRecord`是Android提供的一个类,用于录制音频数据。它允许开发者从设备的麦克风或其他音频输入源获取原始的PCM(脉冲编码调制)音频流。在音频通信程序中,`AudioRecord`扮演着采集音频信号的角色。开发者...

    Android应用源码之audio_应用.zip

    - 应用可能包含对多个音频文件的管理和播放顺序控制。 10. **用户界面设计**: - 控制音频播放的UI元素,如播放/暂停按钮、进度条、音量滑块等,以及与之相关的事件监听和处理。 通过对这个音频应用源码的深入...

    android_audio_PCM

    在Android平台上,音频处理是...综合以上,`android_audio_PCM`项目是一个集成音频录制、播放和实时网络传输的Android应用程序,它利用了Android的音频API和网络编程技术,为用户提供了一种跨设备分享音频的解决方案。

    Android音频实时传输与播放-客户端_语音播放Android_android_

    综上所述,实现Android音频实时传输与播放涉及多个技术层面,包括音频录制、编码/解码、网络传输、播放控制以及性能优化。掌握这些知识点对于开发高质量的语音通信应用至关重要。通过研究提供的源代码,开发者可以更...

    Android-MediaPlayer-play_audios:Android MediaPlayer顺序播放原始存储的音频

    play_audios-master"这个项目中,很可能包含了实现上述功能的代码示例,通过阅读和学习这个项目的源码,你可以更深入地理解如何在Android中使用`MediaPlayer`组件进行音频播放,并掌握顺序播放多音频文件的技巧。...

    Android多媒体MP3播放器

    实现播放器通常需要创建播放列表,开发者需要理解如何动态添加或删除歌曲,以及如何根据播放列表顺序播放。 6. **UI设计**: 使用Android的布局和控件(如`RecyclerView`展示歌曲列表,`SeekBar`控制进度,`...

    Android 小钢琴源码.rar

    2. **Activity生命周期**:小钢琴应用中可能包括多个Activity,每个Activity都有其特定的生命周期方法,如onCreate(), onStart(), onResume(), onPause(), onStop()和onDestroy(),理解这些方法的调用顺序对于控制...

    Android摄像头RTMP推流

    在Android平台上进行...总的来说,Android摄像头RTMP推流涉及到Android多媒体处理、摄像头访问、FFmpeg库的使用等多个方面,需要对这些技术有深入理解。通过学习和实践,开发者可以创建出高效、稳定的视频直播应用。

    Android音乐播放器源码

    总之,"Android音乐播放器源码"涵盖了Android多媒体编程、文件系统访问、数据库操作、UI设计、事件监听和多线程等多个核心知识点,是学习和提升Android应用开发技能的好材料。通过深入研究这个项目,开发者可以更好...

    android歌曲播放器

    在Android平台上开发一款歌曲播放器是一项技术性强且充满挑战的任务,因为这涉及到音频处理、用户界面设计以及多媒体控制等多个方面。下面将详细讲解基于Android的歌曲播放器开发中涉及的关键知识点。 1. **媒体...

    Android音乐播放器简单

    总的来说,"Android音乐播放器简单"项目涵盖了Android应用开发中的多个核心知识点,包括多媒体处理、UI设计、数据绑定、状态管理以及服务和通知的使用。对于初学者来说,这是一个很好的起点,能够帮助他们建立起对...

    Android进行录音播放1(存储到指定文件夹)

    本知识点将深入探讨如何在Android上实现录音并存储到指定文件夹,以及如何播放这些录音文件。 首先,我们需要了解Android提供的MediaRecorder类,它是Android系统用于处理多媒体数据录制的核心工具。使用...

    Android音乐播放器demo

    总结来说,"Android音乐播放器demo"是一个涵盖了Android UI设计、多媒体处理、数据操作和软件架构等多个方面的综合项目。无论是对初学者还是经验丰富的开发者,都是一个值得研究和学习的实例。通过分析和实践,你...

    Android源码——音乐播放源码.zip

    通过分析这个“Android源码——音乐播放源码.zip”的源代码,开发者可以学习如何整合以上各个模块,了解Android系统的多媒体框架,以及如何实现一个功能完备、用户体验良好的音乐播放应用。此外,对于希望深入...

    安卓音乐播放器相关-android一个音乐播放的App.rar

    6. **音频焦点管理**:在Android系统中,音频焦点用于管理多个应用之间的音频播放,确保同一时间只有一个应用在播放声音。音乐播放器需要正确处理音频焦点的获取和释放,以避免音频冲突。 7. **通知栏控制**:为了...

    简单实现音乐播放器进度条功能

    10. **自定义扩展**:虽然项目提供了一个基础框架,但为了满足不同需求,你可以添加更多的功能,如音量控制、循环播放、随机播放等。 通过理解和实践这些知识点,你可以创建出一个功能完善的音乐播放器,并根据需要...

    android系统原理及开发要点详解

     第13章“Android应用程序概述及框架”,介绍Android应用程序层的基本概念和应用程序框架,这部分内容是Android自下而上的第4个层次,可以基于源代码或者SDK开发,它们之间的差别非常小。  第14章“Android应用...

Global site tag (gtag.js) - Google Analytics