AudioTrack播放acc格式音频

news/2024/11/29 6:34:44/

AudioTrack本身只支持播放pcm格式音频,想要使用AudioTrack播放acc格式音频,还需要其他api来进行数据封装。

MediaExtractor

MediaCodec

package com.zero.demo;/**
* Created by yingkun_che on 19-6-19.
* 使用AudioTrack 播放acc音频测试
*/
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.util.Log;
import java.io.IOException;
import java.nio.ByteBuffer;public class AudioDecoderThread {private static final int TIMEOUT_US = 1000;private MediaExtractor mExtractor;private MediaCodec mDecoder;private boolean eosReceived;private int mSampleRate = 0;private final String TAG = "AACPlay";String accPath="/storage/emulated/0/Android/data/com.zero.demo/files/zero_editor_kuato/resources/themes/satura/Stratosphere.aac";public void startPlay(String path) throws IOException {eosReceived = false;//创建MediaExtractor对象用来解AAC封装mExtractor = new MediaExtractor();try {//设置需要MediaExtractor解析的文件的路径mExtractor.setDataSource(path);} catch (IOException e) {e.printStackTrace();}MediaFormat format = mExtractor.getTrackFormat(0);if (format == null){Log.e(TAG,"format is null");return;}//判断当前帧的文件类型是否为audioString mime = format.getString(MediaFormat.KEY_MIME);if (mime.startsWith("audio/")) {Log.d(TAG, "format : " + format);//获取当前帧的采样率mExtractor.selectTrack(0);mSampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);//获取当前帧的通道数int channel  = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);//音频文件长度long duration = format.getLong(MediaFormat.KEY_DURATION);Log.d(TAG,"length:"+duration/1000000);}//创建MediaCodec对象mDecoder = MediaCodec.createDecoderByType(mime);//配置MediaCodecmDecoder.configure(format, null, null, 0);if (mDecoder == null) {Log.e(TAG, "Can't find video info!");return;}//启动MediaCodecmDecoder.start();new Thread(AACDecoderAndPlayRunnable).start();}Runnable AACDecoderAndPlayRunnable = new Runnable() {@Overridepublic void run() {AACDecoderAndPlay();}};private void AACDecoderAndPlay() {ByteBuffer[] inputBuffers = mDecoder.getInputBuffers();ByteBuffer[] outputBuffers = mDecoder.getOutputBuffers();BufferInfo info = new BufferInfo();int buffsize = AudioTrack.getMinBufferSize(mSampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);// 创建AudioTrack对象AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, mSampleRate,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT,buffsize,AudioTrack.MODE_STREAM);//启动AudioTrackaudioTrack.play();int num=0;while (!eosReceived) {int inIndex = mDecoder.dequeueInputBuffer(TIMEOUT_US);if (inIndex >= 0) {ByteBuffer buffer = inputBuffers[inIndex];//从MediaExtractor中读取一帧待解数据int sampleSize = mExtractor.readSampleData(buffer, 0);if (sampleSize < 0) {// We shouldn't stop the playback at this point, just pass the EOS// flag to mDecoder, we will get it again from the// dequeueOutputBufferLog.d(TAG, "InputBuffer BUFFER_FLAG_END_OF_STREAM");mDecoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);} else {//向MediaDecoder输入一帧待解码数据mDecoder.queueInputBuffer(inIndex, 0, sampleSize, mExtractor.getSampleTime(), 0);mExtractor.advance();}//从MediaDecoder队列取出一帧解码后的数据int outIndex = mDecoder.dequeueOutputBuffer(info, TIMEOUT_US);if (info.size>0){Log.d(TAG, "INFO_OUTPUT_BUFFERS_CHANGED num: "+num);num=0;}else{num++;}switch (outIndex) {case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:Log.d(TAG, "INFO_OUTPUT_BUFFERS_CHANGED");outputBuffers = mDecoder.getOutputBuffers();break;case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:MediaFormat format = mDecoder.getOutputFormat();Log.d(TAG, "New format " + format);audioTrack.setPlaybackRate(format.getInteger(MediaFormat.KEY_SAMPLE_RATE));break;case MediaCodec.INFO_TRY_AGAIN_LATER:Log.d(TAG, "dequeueOutputBuffer timed out!");break;default:ByteBuffer outBuffer = outputBuffers[outIndex];//Log.v(TAG, "outBuffer: " + outBuffer);final byte[] chunk = new byte[info.size];// Read the buffer all at onceoutBuffer.get(chunk);//清空buffer,否则下一次得到的还会得到同样的bufferoutBuffer.clear();// AudioTrack write dataaudioTrack.write(chunk, info.offset, info.offset + info.size);mDecoder.releaseOutputBuffer(outIndex, false);//这一行必须加,因为在P上mDecoder.dequeueOutputBuffer 前面会有80次没有数据,需要释放缓冲区,否则无声音break;}// 所有帧都解码、播放完之后退出循环if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {Log.d(TAG, "OutputBuffer BUFFER_FLAG_END_OF_STREAM");break;}}}//释放MediaDecoder资源mDecoder.stop();mDecoder.release();mDecoder = null;//释放MediaExtractor资源mExtractor.release();mExtractor = null;//释放AudioTrack资源audioTrack.stop();audioTrack.release();audioTrack = null;}public void stop() {eosReceived = true;}
}


http://www.ppmy.cn/news/181308.html

相关文章

AUXR AUXR1

博主发现在STC89C51RC/RD的说明手册上没有辅助寄存器AUXR的内容&#xff0c;但是STP-ISP烧录软件上的提供的定时器代码里有这样一项设置。 STC15系列用户手册 P487 STC-ISP提供的代码 /——————————————————————————————/ 8.6更新&#xff1a; …

常见AU AAX VST3音乐音频处理插件安装目录

Logic Pro X 常见AU AAX VST3音乐音频处理插件安装目录 AU /Library/Audio/Plug-Ins/Components/ VST3 /Library/Audio/Plug-Ins/VST3/ AAX /Library/Application\ Support/Avid/Audio/Plug-Ins/

AU声音处理参数

参考&#xff1a;1.让你视频的声音更好听②[EQ均衡器]女声甜美动人男声低沉性感 如何让你视频的人声更好听&#xff5c;fcpx音频调整小技巧 男声 使用右下角的LP&#xff0c;低通滤波器&#xff08;通过低频&#xff0c;衰弱高频&#xff09;因为男生一般是提高中低音&#xf…

PAM8403 3.3V音频功放调试笔记

做I2S输出用了PT8211(实际上买到的丝印是GH8211), 双声道, LSB格式, 工作正常但是输出功率非常低, 喇叭声音要贴近了才能勉强听到, 所以打算做一个PT8211带功放的I2S模块. 最开始用的是PT8211 LM386 * 2, 能正常工作就是LM386的电压要求比较高, 只能工作在5V下, 在3.3V下不行,…

Audio Device Strategy 音频设备输出、输入 选择 基于7.0 代码

存档&#xff0c;不想留本地了&#xff0c;没啥含量 都在Enginee.cpp里写着呢 1. 输出选择 整体流程 首先我们会获取当前存在的设备集合availableOutputDevices 然后根据传入的strategty类型进行匹配选择 在选择之前会先检测是否处于特殊情况下&#xff08;如通话中&#x…

联想think system sr550信息

带外管理口 默认IP地址&#xff1a;192.168.70.125 默认用户名密码 USERID PASSW0RD 0是数字0 转载于:https://www.cnblogs.com/cnqfz/p/11410765.html

ThinkPad P1 Gen4 是否支持单条4T固态?

与一年前&#xff08;2022.4&#xff09;固态相比&#xff0c;固态每T的价格直接减半&#xff0c;估计是国产的加入&#xff0c;这对消费者绝对是好事&#xff0c;但长江存储居然没有4T的产品&#xff0c;至少现在没有找到&#xff0c;看着现在的价格可以购进 "英睿达&am…