当前位置: 移动技术网 > 移动技术>移动开发>Android > Android音视频之AudioTrack播放音频(二)

Android音视频之AudioTrack播放音频(二)

2019年04月04日  | 移动技术网移动技术  | 我要评论

讲了如何录制wav音频文件,本篇就来讲讲如何播放wav文件,这里就是使用audiotrack来播放音频,确切的说是播放pcm格式数据,使用audiotrack播放也没什么难度,主要就是将数据写入到audiotrack中就可以了,先贴代码

package cn.sskbskdrin.record.audio;

import android.media.audiomanager;
import android.media.audiotrack;

import java.io.filenotfoundexception;
import java.io.ioexception;
import java.io.randomaccessfile;

/**
 * @author sskbskdrin
 * @date 2019/april/3
 */
public class audiotrackmanager {
    private audiotrack audiotrack;

    private boolean playing = false;

    public audioparams playwav(string filepath, audiorecordmanager.recordcallback callback) {
        randomaccessfile file = null;
        audioparams params = null;
        try {
            file = new randomaccessfile(filepath, "r");
            params = readwavheader(file);
        } catch (filenotfoundexception e) {
            e.printstacktrace();
        } catch (ioexception e) {
            e.printstacktrace();
        }
        if (params == null) {
            return null;
        }
        int simplerate = params.simplerate;
        int channelconfig = params.getoutchannelconfig();
        int audioformat = params.getencodingformat();
        int minbufsize = audiotrack.getminbuffersize(simplerate, channelconfig, audioformat);
        audiotrack = new audiotrack(audiomanager.stream_music, simplerate, channelconfig, audioformat, minbufsize,
            audiotrack.mode_stream);
        final randomaccessfile finalfile = file;
        new thread(() -> {
            playing = true;
            audiotrack.play();
            byte[] buffer = new byte[minbufsize];
            try {
                finalfile.seek(44);
                while (playing) {
                    int read = finalfile.read(buffer);
                    if (read > 0) {
                        audiotrack.write(buffer, 0, read);
                    } else {
                        finalfile.close();
                        playing = false;
                        audiotrack.stop();
                        audiotrack.release();
                    }
                    if (callback != null) {
                        callback.onrecord(buffer, read);
                    }
                }
            } catch (ioexception e) {
                e.printstacktrace();
            }
        }).start();
        return params;
    }

    public static audioparams readwavheader(randomaccessfile file) throws ioexception {
        file.seek(22);
        byte channelcount = file.readbyte();
        file.seek(24);
        int samplerate = file.readbyte() & 0xff;
        samplerate |= (file.readbyte() & 0xff) << 8;
        samplerate |= (file.readbyte() & 0xff) << 16;
        samplerate |= (file.readbyte() & 0xff) << 24;

        file.seek(34);
        byte bits = file.readbyte();
        return new audioparams(samplerate, channelcount, bits);
    }

}

 

播放的方法,是传入文件路径,audiorecordmanager.recordcallback可以为空。先是通过readwavheader()方法读取wav文件的文件头信息,返回audioparams,这个类是我文章有列出来,可以得到一些需要的数据。

关于读数据头部信息,可以参考,读取重要数据。

 audiotrack.getminbuffersize(simplerate, channelconfig, audioformat)可以获取最小缓存大小。

audiotrack的构造方法中,第一个参数为播放流的类型,有下面几种

audiomanager.stream_music //音乐

audiomanager.stream_voice_call //电话

audiomanager.stream_ring //铃声

audiomanager.stream_alarm //闹钟

audiomanager.stream_notification //通知

最后了个参数是流写入的方式,有两种

audiotrack.mode_stream // 流写入

audiotrack.mode_static //静态写入

audiotrack.mode_stream看名字大概就能知道是流的方式写入,边写边播。

audiotrack.mode_static就是一次写完,然后播放,这种方式更适合比较短的声音播放,比如通知声音

开始播放时,先调用audiotrack.play(),然后从wav文件的数据块开始读,即第44个字节开始,读完调用audiotrack.write写入pcm数据。当读不到数据时,停止audiotrack,释放资源即可。

通过randomaccessfile方式读取文件,可以记录读取的位置,并通过seek方法跳转到指定位置,可实现播放、暂停、继续播放的功能。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网