• 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

  • 相关阅读:
    剑指offer——关于排序算法的应用(一):归并排序
    剑指offer——关于排序算法的应用:选择排序和冒泡排序
    剑指offer:将矩阵选择、螺旋输出矩阵——Python之光
    剑指offer:链表——常见的多指针协同操作:
    剑指Offer:编程习惯篇:代码鲁棒性,代码可扩展性——防御性的编程习惯,解决问题时方法分模块考虑
    剑指offer:数字二进制含1个数,快速幂运算:二进制位运算的运用
    剑指offer:斐波那契数列,跳台阶,变态跳台阶——斐波那契数列类题目:
    回溯法实现各种组合的检索:
    剑指offer:二维数组中查找
    jdk生成https证书的方法
  • 原文地址:https://www.cnblogs.com/whoislcj/p/5477229.html
Copyright © 2020-2023  润新知