从零开始的Android音视频学习(三)AudioTrack播放PCM音频
  uKQjWIlT8LqG 2023年11月19日 15 0
   public enum PlayStatus {
        NO_READY,
        START,
        STOP
    }

    private static final int AUDIO_SOURCE = MediaRecorder.AudioSource.MIC;
    private static final int SAMPLE_RATE_INHZ = 44100;
    private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_OUT_MONO;
    private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;

    private final ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
    private AudioTrack mAudioTrack;
    private PlayStatus mPlayStatus;
    public void playPcmOnMainThread(String filePath) {
        mExecutorService.execute(() -> {
            try {
                playPcm(filePath);
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            }
        });
    }


    //播放是文件流中读取所以需要放在子线程操作
    @WorkerThread
    public void playPcm(String filePath) throws FileNotFoundException {
        int minBufferSizeInBytes = AudioTrack.getMinBufferSize(SAMPLE_RATE_INHZ, CHANNEL_CONFIG, AUDIO_FORMAT);
	//注意在较新的Android设备中废弃了原本的构造方法
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            AudioAttributes attributes = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_MEDIA)
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                    .build();
            AudioFormat audioFormat = new AudioFormat.Builder()
                    .setSampleRate(SAMPLE_RATE_INHZ)
                    .setChannelIndexMask(CHANNEL_CONFIG)
                    .setEncoding(AUDIO_FORMAT)
                    .build();
            mAudioTrack = new AudioTrack.Builder()
                    .setAudioAttributes(attributes)
                    .setAudioFormat(audioFormat)
                    .setBufferSizeInBytes(minBufferSizeInBytes)
                    .setTransferMode(AudioTrack.MODE_STREAM)
                    .build();
        } else {
            mAudioTrack = new AudioTrack(
                    AudioManager.STREAM_MUSIC,
                    SAMPLE_RATE_INHZ,
                    CHANNEL_CONFIG,
                    AUDIO_FORMAT,
                    minBufferSizeInBytes,
                    AudioTrack.MODE_STREAM);
        }
        if (mAudioTrack == null) {
            Log.e(TAG, "playPcm: create audiotrack error");
            throw new IllegalArgumentException("playPcm: create audiotrack error");
        }
        File pcmFile = new File(filePath);
        if (!pcmFile.exists()) {
            throw new FileNotFoundException("pcmFile not found");
        }
        try (FileInputStream fis = new FileInputStream(pcmFile)) {
            if (mPlayStatus != PlayStatus.START
                    && mAudioTrack.getState() != AudioTrack.STATE_UNINITIALIZED
                    && mAudioTrack.getState() != AudioTrack.PLAYSTATE_PLAYING) {
                mPlayStatus = PlayStatus.START;
                mAudioTrack.play();
            }
            byte[] bytes = new byte[minBufferSizeInBytes];
            int dataLength = 0;
            while ((dataLength = fis.read(bytes)) != -1 && mPlayStatus == PlayStatus.START) {
                mAudioTrack.write(bytes, 0, dataLength);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月19日 0

暂无评论

uKQjWIlT8LqG