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();
        }
    }

}
时间: 2024-11-17 09:08:39

Android之AudioTrack实时播放的相关文章

FireBreath开发实时播放接口(Yate + SIP + FFMPEG + SDL)

当时真的是需要这样的一个博文来指导做这个功能模块,可惜网上FireBreath的资料很少,本身对C++的不是很熟悉,所以一路上是不断尝试和摸索,好在马马虎虎的将这个模块实现了,现在记录下来. 首先说明一点,我们的Yate的 SIP Server和终端的SIP Client以及Android的上面的SIP Client还有Windows PC终端的SIP Client和Linux PC终端的SIP Client都实现了. 所以大家的是建议借助这个现有的条件去实现web service实时播放的功能

Android 实现简单音乐播放器(二)

在Android 实现简单音乐播放器(一)中,我介绍了MusicPlayer的页面设计. 现在,我将解析MusicPlayer的功能实现,就讲一些主要的点和有趣的细节,结合MainActivity.java代码进行说明(写出来可能有点碎……一向不太会总结^·^). 一.功能菜单 在MusicPlayer中,我添加了三个菜单: search(搜索手机中的音乐文件,更新播放列表). clear(清除播放列表……这个功能是最初加进去的,后来改进之后,已经没什么实际意义). exit(退出). menu

Android 音频录音与播放

原文链接:https://www.jianshu.com/p/5966ed7c5baf 介绍音频的采集.编码.生成文件.转码等操作,通过 AudioRecord 采集音频,生成三种格式的文件格式(pcm.wav.aac),用 AudioStack 来播放这个音频. 一.PCM .WAV.AAC 的文件头介绍 这里简单的介绍一下常见的三种音频格式: PCM :PCM(Pulse Code Modulation--脉码调制录音).所谓 PCM 录音就是将声音等模拟信号变成符号化的脉冲列,使用三个參数

android webview 通过html5播放在线视频 切换大屏

1.添加网络访问权限 <uses-permission android:name="android.permission.INTERNET" /> 2.webview添加全屏支持 developer官方文档关于html5支持视频播放描述如下:In order to support inline HTML5 video in your application, you need to have hardware acceleration turned on, and set

Android直播实现 Android端推流、播放

最近想实现一个Android直播,但是对于这方面的资料都比较零碎,一开始是打算用ffmpeg来实现编码推流,在搜集资料期间,找到了几个强大的开源库,直接避免了jni的代码,集成后只用少量的java代码就可实现编码.推流和取流播放,整理了一下做了一个demo,在这里记录一下 效果图:  编码和推流,有两个方案选择: 一: 使用javacv来实现,最终也是用过ffmpeg来进行编码和推流,javacv实现到可以直接接收摄像头的帧数据 需要自己实现的代码只是打开摄像头,写一个SurfaceView进行

Android中的实时(real-time)调度

Linux的线程调度策略中有FIFO和RT的实时调度方法,但是在Android中做了限制,普通用户不能修改线程的调度算法为FIFO和RT,必须ROOT用户才能更改.但问题是程序是以普通用户启动和运行的,因此没有办法在程序里面设置FIFO调度.只能使用chrt命令手动修改. 要实现在程序中自动设置FIFO,必须弄清楚Android里面做了什么限制?在内核kernel/kernel/sched.c中我们发现了sched_setscheduler的系统调用,其调用了static 函数__sched_s

android 使用WebView 支持播放优酷视频,土豆视频

看了很多文章和所谓的解决android WebView播放优酷,土豆等视频的办法,都是什么 setPluginsEnabled,在android 4.x之后都不好使,压根就没这函数,因为android 4.x 都去除了flash的支持.就这东西弄的我折腾了半天时间,现在的网站都是采集复制,浪费时间. 只有自己操刀了, 下面给出我的解决办法, 1. 修改AndroidManifest.xml 在Application节点上增加 ? 1 android:hardwareAccelerated="tr

通过Android软件ZAX实时查看Zabbix监控

通过Android软件ZAX实时查看Zabbix监控 前言: 本文转自我的个人博客http://anyisalin.com  这几天在学习Zabbix, 昨天在Google Play上无意间看到一个软件, 可以通过连接Zabbix-Web来实时获取监控的信息 这款软件叫做ZAX 使用前提: 保证你的手机能够连接Zabbix-web 获取软件 下载地址 如果手机有GAPPS, 可以直接通过Google Play安装, 否则按下面给出的方法下载 1. 获取ZAX的下载地址 2.进入某网友自建的站点(

Android MediaRecorder录音与播放

上一篇讲到了使用意图录音,这篇文章将使用MediaRecorder类来录音,从而提供更多的灵活性. 效果图: 源代码奉上: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" andr