Android音视频之AudioTrack播放音频(二)
前一篇讲了如何录制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方法跳转到指定位置,可实现播放、暂停、继续播放的功能。
Android音视频之AudioTrack播放音频(二)的更多相关文章
- android音视频点/直播模块开发
音视频 版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白, ...
- Android音视频点/直播模块开发实践总结-zz
随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能.那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及 ...
- Android 音视频开发(一):PCM 格式音频的播放与采集
什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...
- Android Webview中解决H5的音视频不能自动播放的问题
在开发webview的时候,当加载有声音的网页的时候,声音不会自动播放, 解决方法:在webview中调用js方法.这个方法需要在webview的setWebViewClient方法之后在onPage ...
- Android 音视频开发学习思路
Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...
- Android 音视频同步机制
一.概述 音视频同步(avsync),是影响多媒体应用体验质量的一个重要因素.而我们在看到音视频同步的时候,最先想到的就是对齐两者的pts,但是实际使用中的各类播放器,其音视频同步机制都比这些复杂的多 ...
- Android 音视频开发(七): 音视频录制流程总结
在前面我们学习和使用了AudioRecord.AudioTrack.Camera.MediaExtractor.MediaMuxer API.MediaCodec. 学习和使用了上述的API之后,相信 ...
- Android音视频开发(1):H264 基本原理
前言 H264 视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的.随着 x264/openh264 以及 ffmpeg 等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大 ...
- Android 音视频开发(六): MediaCodec API 详解
在学习了Android 音视频的基本的相关知识,并整理了相关的API之后,我们应该对基本的音视频有一定的轮廓了. 下面开始接触一个Android音视频中相当重要的一个API: MediaCodec.通 ...
随机推荐
- VS2010+OpenCV3.4.1+zbar 64位
1. OpenCV3.4.1和zbar文件夹放到指定的路径下,我把它们放在了"D:\二维码\环境"中. zbar:链接:https://pan.baidu.com/s/11eCDV ...
- 网络营销行业十大看了就想吐的“滥词”
网络营销行业在国内的互联网界已"猖獗"数年之久,它是一个让企业爱让用户恨的行业.有互联网的地方,就有网络营销的机会,有了机会就有了相关产业的存在,只不过是业大业小的问题.但是随着互 ...
- USB/GPIO/SDIO
通用串行总线(英语:Universal Serial Bus,缩写:USB)是连接计算机系统与外部设备的一种串口总线标准,也是一种输入输出接口的技术规范.它只有4根线,两个电源(5V,地线),两个数据 ...
- java中使用hashSet的特性,判断数组是否有重复值
public static boolean cheakRepeat(int[] array){ HashSet<Integer> hashSet = new HashSet<Inte ...
- RabbitMQ 入门【精+转】
rabbitmq可以用一本书取讲,这里只是介绍一些使用过程中,常用到的基本的知识点.官方文档覆盖的内容,非常全面:http://www.rabbitmq.com/documentation.html ...
- 【原】用Java编写第一个区块链(一)
写这篇随笔主要是尝试帮助自己了解如何学习区块链技术开发. [本文禁止任何形式的全文粘贴式转载,本文来自 zacky31 的随笔] 目标: 创建一个最基本的"区块链" 实现一个简单的 ...
- .deb软件包的安装和软件的卸载
前言: .deb格式的软件包是Debian和Ubuntu等Linux发行版软件安装包的文件扩展名. 使用.deb格式软件安装包安装软件 命令如下: sudo dpkg -i package_file. ...
- sql server 高可用镜像
一.什么是数据库镜像 基本软件的高可用性解决方案 快速的故障转移恢复(3秒转移),低硬件成本 基于数据库级别的实现 二.数据库镜像中的服务器角色 主体服务器 承载主体数据库 接受用户连接和事务处理请求 ...
- 51nod1172 Partial Sums V2
推一下式子发现是裸的FFT,$ans[k]=\sum_{i}\sum_{j}[i+j=k]a[i]*C_{m-1+j}^{j}$ 比较坑爹的就是这个模数,于是我们上任意模数的FFT 任意模数的FFT目 ...
- 已配置好的vue全家桶项目router,vuex,api,axios,vue-ls,async/await,less下载即使用
github 地址: https://github.com/liangfengbo/vue-cli-project 点击进入 vue-cli-project 已构建配置好的vuejs全家桶项目,统一管 ...