Android 即時視頻編碼—H.264寫入程式碼

來源:互聯網
上載者:User

http://my.eoe.cn/682121/archive/1839.html

作者:changkai245發佈於 03月21日訪問(533)評論(0)

1 寫入程式碼 & 軟編碼
寫入程式碼:通過調用Android系統內建的Camera錄製視頻,實際上是調用了底層的高清編碼硬體模組,也即顯卡,不使用CPU,速度快
軟編碼:使用CPU進行編碼,如常見C/C++代碼,一般編譯產生的二進位都是的,速度相對較慢。例如使用Android NDK編譯H264產生so庫,編寫jni介面,再使用java調用so庫。

2 原理
① 過程:通過MediaRecoder採集視頻,再將視頻流映射到LocalSocket實現收發
② 原理:詳見【流媒體】H264—MP4格式及在MP4檔案中提取H264的SPS、PPS及碼流 和 “【流媒體】Android 即時視頻採集—MediaRecoder錄製 ”

3 核心代碼
① MediaRecoder視頻採集
視頻採集採用了MediaRecorde錄製方式,詳見 “【流媒體】Android 即時視頻採集—MediaRecoder錄製 ”

② 在initiativeVideo中setOutputFile設定以流方式輸出

 1 2 3 4 5 6 7 8 9101112131415
        // 設定輸出檔案方式: 直接本機存放區   or LocalSocket遠程輸出                if (bIfNativeORRemote == true) // Native        {            lVideoFileFullPath = strRecVideoFilePath + String.valueOf(System.currentTimeMillis())                    + lVideoFileFullPath;            mRecVideoFile = new File(lVideoFileFullPath);            // mMediaRecorder.setOutputFile(mRecVideoFile.getAbsolutePath());            mMediaRecorder.setOutputFile(mRecVideoFile.getPath()); // called after set**Source before prepare            Log.i(TAG, "start write into file~");        }         else // Remote        {            mMediaRecorder.setOutputFile(sender.getFileDescriptor()); // 設定以流方式輸出            Log.i(TAG, "start send into sender~");        }

③ startRecording
功能:通過這個函數啟動線程實現視頻流映射到LocalSocket,同時實現編碼

12345
private void startRecording(){    Log.i(TAG, "##startRecording....");    new Thread(this).start();            }

run:

@Override
public void run()
{
Log.i(TAG, "##run....");

 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
    // defines    DataInputStream dataInputStream = null;            int offSet=0,tmp=0,beLeft=0;    try    {        dataInputStream = new DataInputStream(receiver.getInputStream());    } catch (IOException e2)    {        // TODO Auto-generated catch block        e2.printStackTrace();    }        try    {        Thread.currentThread().sleep(500);    } catch (InterruptedException e1)    {        e1.printStackTrace();    }    // ①方式一:通過查看預先錄製的視頻,需要跳過mdat前面32個位元組(不同硬體平台不同!)    try    {                    dataInputStream.read(h264frame, 0, 32);         Log.i(TAG, "read mdat from");    } catch (IOException e1)    {        // TODO Auto-generated catch block        e1.printStackTrace();    }    // ②方式二:自動化尋找(待補充)    try    {        h264FileOutputStream = new FileOutputStream("/sdcard/avss/h264.264");//264碼流        Log.i(TAG, "h264FileOutputStream");    } catch (FileNotFoundException e)    {        // TODO Auto-generated catch block        e.printStackTrace();    }        try    {        h264FileOutputStream.write(h264head);        h264FileOutputStream.write(h264sps);        h264FileOutputStream.write(h264head);        h264FileOutputStream.write(h264pps);        Log.i(TAG, "run-write SPS/PPS to file");    } catch (IOException e1)    {        // TODO Auto-generated catch block        e1.printStackTrace();    }    while (bIfRecInProcess && (!bIfNativeORRemote))    {        try        {            Log.i(TAG, "**while...");                int h264length = dataInputStream.readInt();             Log.i(TAG, "h264length:"+h264length);            tmp=0; offSet = 0; beLeft = 0;            h264FileOutputStream.write(h264head);            while (offSet < h264length)            {                beLeft = h264length - offSet;                tmp = dataInputStream.read(h264frame, 0, READ_SIZE < beLeft ? READ_SIZE : beLeft);                Log.i(TAG, String.format("H264 %d,%d,%d", h264length, offSet, tmp));                offSet += tmp;                h264FileOutputStream.write(h264frame, 0, tmp);            }        } catch (Exception e)        {            // TODO: handle exception            e.printStackTrace();        }    }            //}

4 Ref/Related
1

http://blog.csdn.net/zblue78/article/details/6078040

2

http://blog.csdn.net/zblue78/article/details/6083374

3

http://www.docin.com/p-282454756.html

4

http://blog.csdn.net/qwertyuj/article/details/7029836

5

http://www.cnblogs.com/skyseraph/archive/2012/03/31/2427593.html

6

http://www.cnblogs.com/skyseraph/archive/2012/03/23/2415018.html

7

http://www.cnblogs.com/skyseraph/archive/2012/04/01/2429384.html

作者:skyseraph
出處:http://www.cnblogs.com/skyseraph/

Email/GTalk: zgzhaobo@gmail.com

聲明:eoe文章著作權屬於作者,受法律保護,轉載時請務必以超連結形式附帶如下資訊

原文作者:
changkai245

原文地址:

http://my.eoe.cn/682121/archive/1839.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.