上一篇我說了如何使用JNI進行h264編碼,但是由于效率的問題 感覺并不太實用。
經(jīng)過幾天的折騰,并參照http://www.javaeye.com/problems/27244大體實現(xiàn)的Android 的實時編碼問題,但是只是思路,還沒有進入代碼實現(xiàn)的階段。
比較重要的2個類 MediaRecorder ParcelFileDescriptor
MediaRecorder 是Android提供的進行采集編碼的類,而ParcelFileDescriptor是個用Socket實現(xiàn)setOutputFile的一個類
在測試liuzongan的程序的過程中,發(fā)現(xiàn)其他這位仁兄已經(jīng)實現(xiàn)了我們需要的大部分的功能,唯一要處理的就是在服務(wù)器端的程序。
在這里我先猜測一下MediaRecorder寫文件的過程
1 ,MediaRecorder寫入一個固定的頭,估計是占位用的 都是00H(占位的長度好像和使用的編碼器有關(guān)系)
再插入 00 00 00 08 6D 64 61 74 (mdat box)
2,開始編碼,并把編碼后的沒一個幀都添加到文件中,看到00 00 80了沒, 了解h263的同志一定很熟悉,根本就是263視頻的標(biāo)志嗎!
(如果有音頻數(shù)據(jù)的話,很定會和視頻數(shù)據(jù)交錯在一起,但是我們的目標(biāo)只是實時編碼視頻流,不需要處理音頻,所以在初始化MediaRecorder的時候我不不要 MediaRecorder.setAudioSource,這樣就沒有音頻數(shù)據(jù)了。)
3 結(jié)束捕獲。 MediaRecorder應(yīng)該會返回到文件的頭部填充文件頭。但由于不是真正文件的關(guān)系,不能返回到頭部,于是就把文件頭附加到文件的后面了,感覺也就是liuzongan這仁兄提出的問題的答案了。
這個是,文件開頭mdat box的長度,用于替換 00 00 00 08.
這個是3gp文件的頭, 用于替換開頭的占位。
4最后,MediaRecorder補充3gp文件的moov box ,這一部分已經(jīng)屬于3gp的媒體索引部分了,具體的內(nèi)容對于我們來說已經(jīng)不太關(guān)心了。大家可以參照http://www.cnitblog.com/zouzheng/archive/2007/04/04/25155.html研究。
下開始說我們要是實現(xiàn)的內(nèi)容了
其實有了上面的描述,大家應(yīng)該能想到我們要實現(xiàn)的其實就是視頻的分幀就可以了。。
server 端處理h263的方法
1一步 找到 mdat這個串, 后面的數(shù)據(jù)就是我們要的視頻數(shù)據(jù)了,
2在流中查找 00 00 80 這個標(biāo)志,每一個都是一幀數(shù)據(jù)的開始
對于 h264和mpeg4的,要預(yù)采集一次數(shù)據(jù),這是因為mp4v的相關(guān)解碼參數(shù),在esds box中的, 而esds box是在采集結(jié)束后才寫入的,所以對于我們的程序來說需要先編碼一次 獲取 mp4v的相關(guān)解碼參數(shù),然后在用相同的參數(shù)進行采集, 呵呵這樣我們就能獲得原始的mp4v流了
h264一樣 不過是存在了 avcC box 里
聯(lián)系客服