调用方法
var url = "https://xxxx.mp3"
DownloadAndConvertTask(context.cacheDir.path).execute(url)
代码实现
class DownloadAndConvertTask constructor(cacheDirPath: String): AsyncTask<String?, Void?, Void?>() {
var cacheDir = File(cacheDirPath)
override fun doInBackground(vararg params: String?): Void? {
if (params.isNotEmpty()) {
val audioUrl = params[0]
if (audioUrl != null) {
val path = downloadAudioFile(audioUrl)
val pcmPath = decodeAudioToPcm(path)
if(!pcmPath.isNullOrBlank()){
}
}
}
return null
}
private fun downloadAudioFile(audioUrl: String): String{
Log.d("downloadAndConvert", "audioUrl = "+audioUrl)
var urlConnection: HttpURLConnection?
var outputStream: FileOutputStream?
val url = URL(audioUrl)
urlConnection = url.openConnection() as HttpURLConnection
urlConnection.connect()
val tempFile: File = File.createTempFile("temp_audio", null, cacheDir)
outputStream = FileOutputStream(tempFile)
val buffer = ByteArray(1024)
var bytesRead: Int
while (urlConnection.inputStream.read(buffer).also { bytesRead = it } != -1) {
outputStream.write(buffer, 0, bytesRead)
}
outputStream.close()
urlConnection.inputStream.close()
urlConnection.disconnect()
return tempFile.absolutePath
}
private fun decodeAudioToPcm(inputAudioFile: String): String? {
Log.d(TAG, "decodeAudioToPcm start inputAudioFile = $inputAudioFile")
if(inputAudioFile.isEmpty()){
return null
}
if(inputAudioFile.endsWith(".pcm")){
return inputAudioFile
}
val timeStart = System.currentTimeMillis()
val mediaExtractor = MediaExtractor()
var mediaCodec: MediaCodec? = null
var outputStream: FileOutputStream? = null
val tempPcmFile: File = File.createTempFile("temp_audio_pcm", ".pcm", cacheDir)
try {
mediaExtractor.setDataSource(inputAudioFile)
mediaExtractor.selectTrack(0)
val inputFormat = mediaExtractor.getTrackFormat(0)
Log.d(TAG, "decodeAudioToPcm MediaFormat.KEY_MIME = "+inputFormat.getString(MediaFormat.KEY_MIME))
mediaCodec = MediaCodec.createDecoderByType(inputFormat.getString(MediaFormat.KEY_MIME)!!)
mediaCodec.configure(inputFormat, null, null, 0)
mediaCodec.start()
val codecInputBuffers = mediaCodec.inputBuffers
val codecOutputBuffers = mediaCodec.outputBuffers
val bufferInfo = MediaCodec.BufferInfo()
val pcmOutputFile = File(tempPcmFile.absolutePath)
outputStream = FileOutputStream(pcmOutputFile)
var isDone = false
while (!isDone) {
val inputBufferIndex = mediaCodec.dequeueInputBuffer(10000)
if (inputBufferIndex >= 0) {
val inputBuffer = codecInputBuffers[inputBufferIndex]
val sampleSize = mediaExtractor.readSampleData(inputBuffer, 0)
if (sampleSize < 0) {
mediaCodec.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM)
isDone = true
} else {
mediaCodec.queueInputBuffer(inputBufferIndex, 0, sampleSize, mediaExtractor.sampleTime, 0 )
mediaExtractor.advance()
}
}
val outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 10000)
if (outputBufferIndex >= 0) {
val outputBuffer = codecOutputBuffers[outputBufferIndex]
val chunk = ByteArray(bufferInfo.size)
outputBuffer.get(chunk)
outputBuffer.clear()
outputStream.write(chunk, 0, chunk.size)
mediaCodec.releaseOutputBuffer(outputBufferIndex, false)
}
}
} catch (e: IOException) {
Log.e(TAG, "Error decoding audio to PCM: " + e.message)
return null
} finally {
try {
if (mediaCodec != null) {
mediaCodec.stop()
mediaCodec.release()
}
mediaExtractor.release()
outputStream?.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
Log.d(TAG, "decodeAudioToPcm end outputPcmFile = "+tempPcmFile.absolutePath)
Log.d(TAG, "decodeAudioToPcm end outputPcmFile.length = "+tempPcmFile.length())
Log.d(TAG, "decodeAudioToPcm time consuming (ms) = "+(System.currentTimeMillis()-timeStart))
return tempPcmFile.absolutePath
}
}