当前位置:首页 > 编程笔记 > 正文
已解决

android pcm播放器:有进度条同步、快进、快退、倍速功能

来自网友在路上 159859提问 提问时间:2023-09-23 12:09:11阅读次数: 59

最佳答案 问答题库598位专家为你答疑解惑

PCM(脉冲编码调制)是一种常见的数字音频编码格式,它代表原始音频数据的一种无损编码方式。以下是关于PCM格式的一些重要信息:

定义:PCM 是一种脉冲编码调制技术,它将模拟音频信号转换为数字形式,通过对模拟信号进行采样和量化,然后将样本表示为二进制编码来实现。PCM 不压缩音频数据,因此每个音频样本都以其原始值表示。

采样率:PCM 文件中的音频数据以一定的采样率(Samples Per Second,通常以Hz表示)进行采样。常见的采样率包括 44100 Hz(CD音质)、48000 Hz(DVD音质)和16000 Hz(电话音质)等。更高的采样率通常意味着更高的音频质量,但也会占用更多的存储空间。

位深度:PCM 数据以一定的位深度来表示每个样本的值,通常以位数表示。常见的位深度包括16位和24位。较高的位深度可以提供更好的音频质量,因为它可以更准确地表示音频振幅,但也会占用更多的存储空间。

声道数:PCM 可以是单声道(单声道)或立体声(双声道)等多声道格式。单声道表示音频仅具有一个声道,而立体声表示音频具有左右两个声道,允许立体声效果。

文件格式:PCM 数据通常存储在不同的文件格式中,如WAV(Waveform Audio File Format)或AIFF(Audio Interchange File Format)等。这些文件格式包含了PCM音频数据以及元数据,以描述音频的参数和格式。

总之,PCM 是一种直观的音频编码格式,它以原始的数字形式表示音频数据,没有压缩,因此在需要高音质的应用中很常见,如音乐制作和专业音频处理。但是,由于它不进行压缩,所以文件大小通常较大。

播放器工具类:

package com.realtop.translatemodule.utils;import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;import androidx.lifecycle.MutableLiveData;import java.io.File;
import java.io.FileInputStream;public class AudioTrackUtils {private static final String TAG = "audio_track_utils";private AudioTrack audioTrack;private int sampleRate = 16000;private int channelConfig = AudioFormat.CHANNEL_OUT_MONO;private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;private boolean isPlaying;private Thread mThread;private FileInputStream mFileInput;private boolean isUseSpeed;// 开启两倍速度public void setUseSpeed(boolean useSpeed) {isUseSpeed = useSpeed;}public final MutableLiveData<Float> PROGRESS_OBSERVER = new MutableLiveData<>();public final MutableLiveData<Integer> PLAY_START_END = new MutableLiveData<>();private final Handler mHandler = new Handler(Looper.getMainLooper());public void playAudio(String filePath, int ratio) {if (audioTrack != null) {Log.i(TAG, "playAudio: is init");return;}int bufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat);Log.i(TAG, "playAudio: file path:" + filePath + "; buffer size:" + bufferSize);audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate,channelConfig,audioFormat,bufferSize,AudioTrack.MODE_STREAM);audioTrack.play();isPlaying = true;File sourceFile = new File(filePath);try {mFileInput = new FileInputStream(sourceFile);long currentPos = (long) (ratio * 1.0f / 100 * sourceFile.length());long skip = mFileInput.skip(currentPos);Log.i(TAG, "playAudio: skip:" + skip);} catch (Exception e) {Log.i(TAG, "playAudio: error:" + e.getMessage());}mThread = new Thread(() -> {byte[] bytes = new byte[bufferSize * 2];byte[] real = new byte[bufferSize];// 倍速使用int len = -1;while (isPlaying) {try {len = mFileInput.read(bytes);} catch (Exception e) {Log.i(TAG, "playAudio: read file end:" + e.getMessage());len = -1;// 默认异常退出}if (len == -1)break;if (isUseSpeed) {for (int i = 0, j = 0; i < len * 0.25f; i += 4, j += 2) {// damagetry {real[j] = bytes[i];real[j + 1] = bytes[i + 1];} catch (Exception e) {Log.i(TAG, "playAudio: speed change error:" + e.getMessage());}}audioTrack.write(real, 0, (int) (len * 0.5f));} else {audioTrack.write(bytes, 0, len);}// 处理进度handleProgress(sourceFile);}// 自动停止了mHandler.post(this::stopAndRelease);Log.i(TAG, "playAudio: looper end");});mThread.start();PLAY_START_END.postValue(1);Log.i(TAG, "playAudio: begin record");}private void handleProgress(File sourceFile) {try {long position = mFileInput.getChannel().position();long length = sourceFile.length();float progress = 1.0f * position / length;if (progress < 0 || progress > 1) {progress = 0;}PROGRESS_OBSERVER.postValue(progress * 100);Log.i(TAG, "playAudio: pos:" + position + "; " + length);} catch (Exception e) {Log.i(TAG, "playAudio: error get pos:" + e.getMessage());}}public void stopAndRelease() {if (audioTrack == null) {Log.i(TAG, "release: is ended");return;}isPlaying = false;try {mThread.join();mFileInput.close();audioTrack.flush();audioTrack.stop();audioTrack.release();Log.i(TAG, "release: end");} catch (Exception e) {Log.i(TAG, "release: error:" + e.getMessage());}audioTrack = null;PLAY_START_END.postValue(2);}
}
查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"android pcm播放器:有进度条同步、快进、快退、倍速功能":http://eshow365.cn/6-12086-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!