版權聲明:本文為衛(wèi)偉學習總結文章,轉載請注明出處猫十!
MediaMuxer的使用比較簡單览濒,方法很少,就那么幾個炫彩。但是需要注意的是我們添加音視頻軌的時候匾七,MediaMuxer.addTrack(MediaFormat)需要一個MediaFormat參數,而這個參數不是我們打開的MediaCodec的時候簡單構造的那個江兢,這個MediaFormat必須是從MediaCodec.getOutputFormat()獲取的昨忆,他們完全不一樣。如果我們直接使用自己簡單構造的MediaFormat杉允,是無法寫入音視頻數據的邑贴。
我們也可以自己構造自己添加音視頻軌道的MediaFormat,MediaMuxer的主要方法:
-
1.int addTrack(@NonNull MediaFormat format)
一個視頻文件是包含一個或多個音視頻軌道的席里,這個方法就是用于添加一個視頻或視頻軌道,并返回對應的ID.之后通過這個ID向相應的軌道寫入數據拢驾。用于新建音視頻軌道的MediaFormat是需要從MediaCodec.getOutputFormat()獲取的奖磁,而不是簡單構造的MediaFormat。 - 2.start()
添加完所有音視頻軌道之后繁疤,需要調用這個方法告訴Muxer咖为,開始寫入數據。需要注意的是稠腊,調用這個方法之后躁染,無法再次addTrack了。 - 3 void writeSampleData(int trackIndex, @NonNull ByteBuffer byteBuf, @NonNull BufferInfo bufferInfo)
用于向Muxer寫入編碼后的音視頻數據架忌。trackIndex是addTrack的時候返回的ID,byteBuf便是要寫入的數據吞彤,而bufferInfo是跟這一幀byteBuf相關的信息,包括時間戳叹放、數據長度和數據在ByteBuffer中的位移 - void stop()
與start()向對應饰恕,用于停止寫入數據,并生成文件井仰。
- void stop()
- 5.void release()
釋放Muxer資源埋嵌。
整個流程用到的就是這五個方法。先構造一個Muxer糕档,需要兩個參數莉恼,第一個是音視頻文件的保存路徑拌喉,第二個是音視頻封裝文件的格式速那,可以選擇mp4或3gp,用mp4就好尿背。
private fun start() {
//用于標記是否已經添加視頻軌道
mVideoTrackReady = false
//用于標記是否已經添加銀頻軌道
mAudioTrackReady = false
//用于標記是否已經開始
mStart = false
//刪除已存在的文件
val file = File(path)
if (file.exists()) file.delete()
muxer = MediaMuxer(path, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
}
需要在添加音頻和視頻軌道之后才能開始Muxer,所以分別用兩個bool來標記對應的軌道已經添加端仰,并且每次添加軌道時,都使用ready()檢查是否開啟Muxer.
private fun ready() {
if (mVideoTrackReady && mAudioTrackReady) {
muxer?.start()
mStart = true
debug_e("Muxer start")
}
}
override fun addVideoTrack(format: MediaFormat) {
try {
videoTrack = muxer!!.addTrack(format)
} catch (e: Exception) {
//Add video track failed
e.printStackTrace()
return
}
mVideoTrackReady = true
ready()
}
override fun addAudioTrack(format: MediaFormat) {
try {
audioTrack = muxer!!.addTrack(format)
} catch (e: Exception) {
//Add audio track failed
e.printStackTrace()
return
}
mAudioTrackReady = true
ready()
}
添加完軌道之后田藐,就可以開始給Muxer寫入數據了荔烧,這部分也很簡單。我們只需要根據addTrack時返回的ID對應的寫入數據就好汽久。
private fun writeSample(track: Int, sample: Sample) {
try {
muxer?.writeSampleData(track, sample.sample, sample.bufferInfo)
} catch (e: Exception) {
//Write sample failed
e.printStackTrace()
}
最后我們寫完數據之后鹤竭,一定要記得調用stop()來生成文件和release()釋放資源。
private fun stop() {
if (mStart) {
mStart = false
try {
muxer?.stop()
} catch (e: IllegalStateException) {
e.printStackTrace()
}
}
muxer?.release()
}
使用MediaMuxer對音視頻進行混合封裝景醇。