在播放之前解密加密的 mp3 文件。有3种方式:
1、使用MediaPlayer api:
Android M 版之后:
you can play mp3 data in byte array directly by:
//Read encrypted mp3:
byte[] bytesAudioData = Utils.readFile(path); // or from a url.
final byte[] bytesAudioDataDecrypted = YourUtils.decryptFileToteArray(bytesAudioData);
ByteArrayMediaDataSource bds = new ByteArrayMediaDataSource(bytesAudioDataDecrypted) ;
mediaPlayer.setDataSource(bds);
在安卓版本 M 之前:
//Read encrypted mp3:
byte[] bytesAudioData = Utils.readFile(path); // or from a url.
final byte[] bytesAudioDataDecrypted = YourUtils.decryptFileToteArray(bytesAudioData);
File file =new File(dirofyouraudio.mp3");
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytesAudioDataDecrypted);
Log.d(TAG, "playSound :: file write to temp :: System. nanoTime() ="+System. nanoTime());
fos.close();
FileInputStream fis = new FileInputStream(file);
mediaPlayer.setDataSource(fis.getFD());
2,对于 AudioTrack api,如果您使用:
int minBufferSize = AudioTrack.getMinBufferSize(sampleRate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize,
AudioTrack.MODE_STREAM);
int i = 0;
byte[] tempMinBufferToRead = new byte[minBufferSize];
try {
byte[] bytesAudioData = Utils.readFile( lastRecordedAudiofilePath);
bytesAudioData = yourUtils.decryptYourFileToByteArray(bytesAudioData);
try {
fileInputStremForPlay = new FileInputStream( lastRecordedAudiofilePath);
dataInputStreamForPlay = new DataInputStream(new ByteArrayInputStream(bytesAudioData));
track.play();
while ((i = dataInputStreamForPlay.read(tempMinBufferToRead, 0, minBufferSize)) > -1) {
Log.d(LOG_TAG, "mThreadExitFlag= " + mThreadExitFlag);
if ((mThreadExitFlag == true) || (!audioFilePathInThisThread.equals(lastRecordedAudiofilePath))) {
m_handler.post(new Runnable() {
public void run() {
Log.d(LOG_TAG, "startPlaying: break and reset play button ");
startPlayBtnInToolbar.setEnabled(true);
stopPlayBtnInToolbar.setEnabled(false);
}
});
break;
}
track.write(tempMinBufferToRead, 0, i);
}
Log.d(LOG_TAG, "===== Playing Audio Completed ===== ");
track.stop();
track.release();
dataInputStreamForPlay.close();
fileInputStremForPlay.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
3,使用 MediaExtractor , MediaCodec 和 AudioTrack ,您可以设置数据源提取器:
extractor.setDataSource(this.url);
或者
extractor.setDataSource(this.Mediadatasource);
ps:ByteArrayMediaDataSource 类:
import android.annotation.TargetApi;
import android.media.MediaDataSource;
import android.os.Build;
import java.io.IOException;
import android.content.res.AssetFileDescriptor;
import android.media.MediaDataSource;
import android.util.Log;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
@TargetApi(Build.VERSION_CODES.M)
public class ByteArrayMediaDataSource extends MediaDataSource {
private static final String TAG = ByteArrayMediaDataSource.class.getSimpleName();
private byte[] data;
public ByteArrayMediaDataSource(byte []data) {
// assert data != null;
this.data = data;
}
@Override
public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
if (position >= data.length) {
return -1; // -1 indicates EOF
}
if (position + size > data.length) {
size -= (position + size) - data.length;
}
Log.d(TAG, "MediaDataSource size = "+size);
System.arraycopy(data, (int)position, buffer, offset, size);
return size;
}
@Override
public long getSize() throws IOException {
Log.d(TAG, "MediaDataSource data.length = "+data.length);
return data.length;
}
@Override
public void close() throws IOException {
// Nothing to do here
data =null;
}
}