zoukankan      html  css  js  c++  java
  • Android音频开发之AudioTrack实时播放

    前言:

          其实在Android中录音可以用MediaRecord录音,操作比较简单。但是不能对音频进行处理。考虑到项目中做的是实时语音只能选择AudioRecord进行录音。然后实时播放也只能采用AudioTrack进行播放。

    下文为具体实现:

    public class AudioTrackManager {
        public static final String TAG = "AudioTrackManager";
        private AudioTrack audioTrack;
        private DataInputStream dis;
        private Thread recordThread;
        private boolean isStart = false;
        private static AudioTrackManager mInstance;
        private int bufferSize;
    
        public AudioTrackManager() {
            bufferSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
            audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize * 2, AudioTrack.MODE_STREAM);
        }
    
        /**
         * 获取单例引用
         *
         * @return
         */
        public static AudioTrackManager getInstance() {
            if (mInstance == null) {
                synchronized (AudioTrackManager.class) {
                    if (mInstance == null) {
                        mInstance = new AudioTrackManager();
                    }
                }
            }
            return mInstance;
        }
    
        /**
         * 销毁线程方法
         */
        private void destroyThread() {
            try {
                isStart = false;
                if (null != recordThread && Thread.State.RUNNABLE == recordThread.getState()) {
                    try {
                        Thread.sleep(500);
                        recordThread.interrupt();
                    } catch (Exception e) {
                        recordThread = null;
                    }
                }
                recordThread = null;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                recordThread = null;
            }
        }
    
        /**
         * 启动播放线程
         */
        private void startThread() {
            destroyThread();
            isStart = true;
            if (recordThread == null) {
                recordThread = new Thread(recordRunnable);
                recordThread.start();
            }
        }
    
        /**
         * 播放线程
         */
        Runnable recordRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
                    byte[] tempBuffer = new byte[bufferSize];
                    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();
                }
            }
    
        };
    
        /**
         * 播放文件
         *
         * @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 {
                setPath(path);
                startThread();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 停止播放
         */
        public void stopPlay() {
            try {
                destroyThread();
                if (audioTrack != null) {
                    if (audioTrack.getState() == AudioRecord.STATE_INITIALIZED) {
                        audioTrack.stop();
                    }
                    if (audioTrack != null) {
                        audioTrack.release();
                    }
                }
                if (dis != null) {
                    dis.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }

    使用前要添加如下权限:

    <!-- 录音权限 -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <!-- 往SDCard写入数据权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- 在SDCard中创建与删除文件权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

    相关音频知识链接:

       http://ticktick.blog.51cto.com/823160/1748506

  • 相关阅读:
    基于fis的前端模块化和工程化方案
    网页中font-family的属性解析
    centos 基础环境配置
    golang的各种数据格式的互相转换
    golang 的编译安装以及supervisord部署
    ip地址库选择
    golang中使用mongodb的操作类以及如何封装
    golang中使用mongodb
    golang使用sqlite
    centos 安装nginx
  • 原文地址:https://www.cnblogs.com/whoislcj/p/5477229.html
Copyright © 2011-2022 走看看