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