音频---播放PCM音频数据

1、代码实现

public class PCMAudioPlayer {
    //默认配置AudioTrack-----此处是解码,要环和编码的配置对应
    private static final int DEFAULT_STREAM_TYPE = AudioManager.STREAM_MUSIC;//音乐
    private static final int DEFAULT_SAMPLE_RATE = 16000;//采样频率
    private static final int DEFAULT_CHANNEL_CONFIG = AudioFormat.CHANNEL_CONFIGURATION_MONO;//注意是out
    private static final int DEFAULT_AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    private static final int DEFAULT_PLAY_MODE = AudioTrack.MODE_STREAM;
    private final ExecutorService mExecutorService;

    private AudioTrack audioTrack;//音轨
    private DataInputStream dis;//流
    private boolean isStart = false;
    private static PCMAudioPlayer mInstance;//单例
    private int mMinBufferSize;//最小缓存大小

    public PCMAudioPlayer() {
        mMinBufferSize = AudioTrack.getMinBufferSize(
                DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_CONFIG, AudioFormat.ENCODING_PCM_16BIT);
        //实例化AudioTrack
        audioTrack = new AudioTrack(
                DEFAULT_STREAM_TYPE, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_CONFIG,
                DEFAULT_AUDIO_FORMAT, mMinBufferSize * 2, DEFAULT_PLAY_MODE);
        mExecutorService = Executors.newSingleThreadExecutor();//线程池
    }

    /**
     * 获取单例对象
     *
     * @return
     */
    public static PCMAudioPlayer getInstance() {
        if (mInstance == null) {
            synchronized (PCMAudioPlayer.class) {
                if (mInstance == null) {
                    mInstance = new PCMAudioPlayer();
                }
            }
        }
        return mInstance;
    }

    /**
     * 播放文件
     *
     * @param path
     * @throws Exception
     */
    private void setPath(String path) throws Exception {
        File file = new File(path);
        dis = new DataInputStream(new FileInputStream(file));
    }

    /**
     * 启动播放
     *
     * @param path 文件了路径
     */
    public void startPlay(String path) {
        try {
            isStart = true;
            setPath(path);//设置路径--生成流dis
            mExecutorService.execute(new PlayRunnable());//启动播放线程
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止播放
     */
    public void stopPlay() {
        try {
            if (audioTrack != null) {
                if (audioTrack.getState() == AudioRecord.STATE_INITIALIZED) {
                    audioTrack.stop();
                }
            }
            if (dis != null) {
                isStart = false;
                dis.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 释放资源
     */
    public void release() {
        if (audioTrack != null) {
            audioTrack.release();
        }
        mExecutorService.shutdownNow();//停止线程池
    }

    //播放线程
    private class PlayRunnable implements Runnable {
        @Override
        public void run() {
            try {
                //标准较重要音频播放优先级
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
                byte[] tempBuffer = new byte[mMinBufferSize];
                int readCount = 0;
                while (dis.available() > 0) {
                    readCount = dis.read(tempBuffer);//读流
                    if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) {
                        continue;
                    }
                    if (readCount != 0 && readCount != -1) {//
                        audioTrack.play();
                        audioTrack.write(tempBuffer, 0, readCount);
                    }
                }
                stopPlay();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

2、直接调用上面方法就可以了

 PCMAudioPlayer.getInstance().startPlay("/storage/Tfcard/DCIM/test_pcm.pcm");
备注:使用时需要添加权限:<uses-permission android:name="android.permission.RECORD_AUDIO" />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值