前一篇讲了如何录制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. Java开源生鲜电商平台-推荐系统模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-推荐系统模块的设计与架构(源码可下载) 业务需求: 对于一个B2B的生鲜电商平台,对于买家而言,他需要更加快速的购买到自己的产品,跟自己的餐饮店不相关的东西,他是不关心的,而 ...

  2. PHP开发基础知识

    PHP的学习 PHP脚本以<?php 开始 ?>结束 <?php //此处写代码 ? > php默认文件扩展名.php php文件通常包含HTML标签以及一些PHP脚本代码 “ ...

  3. JQ无缝轮播图-插件封装

    类似京东的这种无缝轮播效果: 实例代码下载 HTML代码: <body> <!-- /*觅me 探索生活*/ --> <div class="test" ...

  4. 在阿里云的CentOS环境中安装配置MySQL、JDK、Maven

    Welcome to Alibaba Cloud Elastic Compute Service ! [root@izbp19stm1x1k2io1e7r3tz ~]# rpm -Uvh http:/ ...

  5. .NET Orm 性能测试

    .NET Orm 性能测试 简介 OrmBenchmark 这个项目主要是为了测试主要的Orm对于 SqlServer 数据库的查询并将数据转换成所需 POCO 对象的耗时情况(好吧,实际上不完全or ...

  6. LeetCode Javascript实现 344. Reverse String 292. Nim Game 371. Sum of Two Integers

    344. Reverse String /** * @param {string} s * @return {string} */ var reverseString = function(s) { ...

  7. 用react重构个人网站 3-23

    1:  :before 选择器在被选元素的内容前面插入内容 2:  float是什么?浮动在CSS中的作用 3:CSS运用在React中的两种方式 使用className属性,CSS内容就用link加 ...

  8. centos7系统日志时间与系统时间相差8小时

    场景:当我们修改完系统时间的时区后,我们去查看我们的系统日志的时间发现时区还是在之前的系统时间时区. [root@vp-n ~]# ls -l /etc/localtime lrwxrwxrwx 1 ...

  9. SSE图像算法优化系列十八:三次卷积插值的进一步SSE优化。

    本文是在学习https://blog.csdn.net/housisong/article/details/1452249一文的基础上对算法的理解和重新整理,再次非常感谢原文作者的深入分析以及分享. ...

  10. MyBatis 中一对一和一对多的映射关系

    1 一对一映射 比如每位学生有一个地址. public class Address { private Integer addrId; private String street; private S ...