AudioTrack的简单用法

参考 https://github.com/renhui/AudioDemo/blob/master/audiodemo/src/main/java/com/renhui/audiodemo/MainActivity.java

https://blog.csdn.net/ronaldo4511/article/details/89155457

AudioTrack:用于输出音频数据,它有两种数据加载模式

        MODE_STREAM:以流的形式持续把音频数据写到AudioTrack内部的Buffer中

        MODE_STATIC:在play之前只需要把所有数据通过一次write调用传递到AudioTrack中的内部缓冲区

示例代码

import android.Manifest;
import android.annotation.SuppressLint;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class AudioTrackActivity extends AppCompatActivity {

    // 采样率
    // 44100是目前的标准,但是某些设备仍然支持22050,16000,11025
    // 采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级
    private final static int AUDIO_SAMPLE_RATE = 16000;

    // 音频通道 单声道
    private final static int AUDIO_CHANNEL = AudioFormat.CHANNEL_OUT_MONO;

    // 音频格式:PCM编码
    private final static int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

    // 音频格式:PCM编码
    private final static int AUDIO_TRACK_TYPE_STREAM = AudioTrack.MODE_STREAM;

    /**
     * 需要申请的运行时权限
     */
    private String[] permissions = new String[]{
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
    private static final int MY_PERMISSIONS_REQUEST = 1001;
    private final String pcmFileName = Environment.getExternalStorageDirectory() + "/Download/record.pcm";
    private AudioTrack audioTrack;
    private byte[] audioData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_audio_track);

        ActivityCompat.requestPermissions(this, permissions, MY_PERMISSIONS_REQUEST);

        findViewById(R.id.staticStart).setOnClickListener(v -> staticStart());

        findViewById(R.id.streamStart).setOnClickListener(v -> streamStart());

        findViewById(R.id.stop).setOnClickListener(v -> stop());

    }

    @SuppressLint("StaticFieldLeak")
    private void staticStart(){

        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    InputStream in = new FileInputStream(new File(pcmFileName));
                    try {
                        ByteArrayOutputStream out = new ByteArrayOutputStream();
                        for (int b; (b = in.read()) != -1; ) {
                            out.write(b);
                        }

                        audioData = out.toByteArray();
                    } finally {
                        in.close();
                    }
                } catch (IOException e) {
                }
                return null;
            }


            @Override
            protected void onPostExecute(Void v) {
                audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, AUDIO_SAMPLE_RATE,
                        AUDIO_CHANNEL, AUDIO_ENCODING, audioData.length, AUDIO_TRACK_TYPE_STREAM);
                audioTrack.write(audioData, 0, audioData.length);
                audioTrack.play();
            }

        }.execute();

    }

    private void stop(){
        if (null != audioTrack) {
            audioTrack.stop();
            audioTrack.release();
            audioTrack = null;
        }
    }

    private void streamStart(){

        final int minBufferSize = AudioTrack.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_ENCODING);
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, AUDIO_SAMPLE_RATE,
                AUDIO_CHANNEL, AUDIO_ENCODING, minBufferSize, AUDIO_TRACK_TYPE_STREAM);
        audioTrack.play();
        File file = new File(pcmFileName);

        new Thread(() -> {

            try {
                FileInputStream fileInputStream = new FileInputStream(file);
                byte[] tempBuffer = new byte[minBufferSize];
                while (fileInputStream.available() > 0) {
                    int readCount = fileInputStream.read(tempBuffer);
                    if (readCount == AudioTrack.ERROR_INVALID_OPERATION ||
                            readCount == AudioTrack.ERROR_BAD_VALUE) {
                        continue;
                    }
                    if (readCount != 0 && readCount != -1) {
                        audioTrack.write(tempBuffer, 0, readCount);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }).start();

    }

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Android中,AudioTrack默认支持PCM(脉冲编码调制)格式的音频数据播放,而不支持AC3(杜比数字编码3)格式。AC3是一种常见的压缩音频格式,通常用于DVD、蓝光等高清视频的音频部分。 要在Android中播放AC3格式的音频数据,你需要使用第三方库或解码器来解码AC3数据,并将解码后的PCM数据传递给AudioTrack进行播放。一种常用的方法是使用FFmpeg库进行解码。 以下是一个简单的示例代码,展示了如何使用FFmpeg来解码AC3数据并将解码后的PCM数据传递给AudioTrack进行播放: ```java import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioTrack; import wseemann.media.FFmpegMediaPlayer; public class AC3Player { private AudioTrack audioTrack; private FFmpegMediaPlayer mediaPlayer; public void playAC3(String filePath) { // 初始化AudioTrack int sampleRate = 44100; // 采样率 int channelConfig = AudioFormat.CHANNEL_OUT_STEREO; // 声道配置 int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 位深度 int bufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat); audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfig, audioFormat, bufferSize, AudioTrack.MODE_STREAM); // 初始化FFmpegMediaPlayer mediaPlayer = new FFmpegMediaPlayer(); mediaPlayer.setDataSource(filePath); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepareAsync(); mediaPlayer.setOnPreparedListener(new FFmpegMediaPlayer.OnPreparedListener() { @Override public void onPrepared(FFmpegMediaPlayer mp) { // 开始播放 audioTrack.play(); mediaPlayer.start(); // 将解码后的PCM数据写入AudioTrack进行播放 byte[] buffer = new byte[bufferSize]; while (mediaPlayer.isPlaying()) { int bytesRead = mediaPlayer.read(buffer, 0, bufferSize); audioTrack.write(buffer, 0, bytesRead); } } }); } public void stop() { if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } if (audioTrack != null) { audioTrack.stop(); audioTrack.release(); audioTrack = null; } } } ``` 请注意,以上代码使用了第三方库FFmpegMediaPlayer来解码AC3数据。你需要将FFmpegMediaPlayer的依赖库添加到你的项目中。 希望这个简单的示例代码可以帮助你理解如何在Android中播放AC3格式的音频数据。如果你需要更详细的解决方案或遇到其他问题,请提供更多细节,以便我能够给出更具体的建议。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值