前一篇讲了如何录制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播放音频(二)的更多相关文章

  1. android音视频点/直播模块开发

      音视频 版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白, ...

  2. Android音视频点/直播模块开发实践总结-zz

    随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能.那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及 ...

  3. Android 音视频开发(一):PCM 格式音频的播放与采集

    什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...

  4. Android Webview中解决H5的音视频不能自动播放的问题

    在开发webview的时候,当加载有声音的网页的时候,声音不会自动播放, 解决方法:在webview中调用js方法.这个方法需要在webview的setWebViewClient方法之后在onPage ...

  5. Android 音视频开发学习思路

    Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...

  6. Android 音视频同步机制

    一.概述 音视频同步(avsync),是影响多媒体应用体验质量的一个重要因素.而我们在看到音视频同步的时候,最先想到的就是对齐两者的pts,但是实际使用中的各类播放器,其音视频同步机制都比这些复杂的多 ...

  7. Android 音视频开发(七): 音视频录制流程总结

    在前面我们学习和使用了AudioRecord.AudioTrack.Camera.MediaExtractor.MediaMuxer API.MediaCodec. 学习和使用了上述的API之后,相信 ...

  8. Android音视频开发(1):H264 基本原理

    前言 H264 视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的.随着 x264/openh264 以及 ffmpeg 等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大 ...

  9. Android 音视频开发(六): MediaCodec API 详解

    在学习了Android 音视频的基本的相关知识,并整理了相关的API之后,我们应该对基本的音视频有一定的轮廓了. 下面开始接触一个Android音视频中相当重要的一个API: MediaCodec.通 ...

随机推荐

  1. unity3d从入门到精通要掌握什么内容

    Unity3d就业方向广.游戏行业占据了65%的比例,也有虚拟现实,增强现实等方向,就业前景火爆.可以从事的岗位:游戏开发工程师.移动应用开发工程师.游戏场景设计师.游戏特效设计师.VR开发工程师.A ...

  2. 《与C语言相恋》

    第一章 <与C语言相恋> 目录: 1.1 C语言的诞生 1.2 相恋C语言的理由 1.3 相恋C语言的7个步骤 1.4 目标代码文件,可执行文件和库 1.5 本章小结 C语言的诞生 197 ...

  3. PAT1129:Recommendation System

    1129. Recommendation System (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...

  4. jsp页面日期格式不正确

    第一种: 如果是从数据库获取的时间(数据库中日期格式是乱的)可以在数据库取数据时   进行格式化   例如  ;TO_CHAR(SYSDATE,'YYYY-MM-DD') 第二种: 在数据库取出数据后 ...

  5. MySql 物理文件组成

    1.日志文件        MySQL 各类日志文件介绍 2.数据文件        MySQL 各类数据文件介绍

  6. RestTemplate的设置及使用

    概述 RestTemplate是spring内置的http请求封装,在使用spring的情况下,http请求直接使用RestTemplate是不错的选择. Rest服务端 使用RestTemplate ...

  7. 【转】拍拍网2015年mysql最新开发规范

    1.命名规范 (1)库名.表名.字段名必须使用小写字母,并采用下划线分割. (2)库名.表名.字段名禁止超过32个字符. (3)库名.表名.字段名必须见名知意.命名与业务.产品线等相关联. (4)库名 ...

  8. bootgrid

    编写bootgrid前提条件  有关bootgrid的.css和.js库文件 参数:ajax:   必须设置为true  post:   传递给Java的参数  url:   与java连接的方法名  ...

  9. Hbase中HMaster作用

    HMaster在功能上主要负责Table表和HRegion的管理工作,具体包括: 1.管理用户对Table表的增.删.改.查操作: 2.管理HRegion服务器的负载均衡,调整HRegion分布: 3 ...

  10. bash: scrapy: command not found

    一.场景 执行  pip install scrapy 后,安装成功且执行 import scrapy  成功 二.问题 在shell中执行 scrapy 返回 bash: scrapy: comma ...