android流媒體初探索(一)----獲取視頻數據


最近在做一個項目,簡單說一下需求吧:

android手機做前端視頻采集入口,能捕獲實時的視頻流並傳到服務器並且分發到pc客戶端實時的進行視頻的觀看。

就這個看似簡單的需求,由於我之前對流媒體全無了解,也因為接入了XX平台進行數據中轉,導致開發過程一再受阻。

但就目前已基本將該項目流程走通,所以必須在這里來作個小結。

在這里有幾個關鍵點:

a、視頻數據如何獲取。

b、獲取到的數據如何重新編碼,以何種形式編碼。

c、以什么協議進行傳輸。

d、視頻最后的解碼播放。

android充當攝像頭,進行流媒體傳輸的開源項目有spydroid。這個項目是研究android流媒體處理目前來說最好的切入點。網上也有很多對該項目源碼解析的文章,這里不再多說。我就上面提到的幾個關鍵點簡單說一下做法。

a獲取視頻數據

用android來實現還算是簡單。畢竟有豐富的sdk封裝。那么就會用到MediaRecorder。跟它相關的幾個類還有Camera、SurfaceHolder。

MediaRecorder用於錄像,相關設置如下:

 

if (mMediaRecorder == null) {
mMediaRecorder
= new MediaRecorder(); } else { mMediaRecorder.reset(); } camera = getCamera();
 

      camera.startPreview();
      camera.unlock();


    mMediaRecorder.setCamera(camera);

mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
<!--以上和以下順序不能顛倒,否則出錯>
mMediaRecorder.setVideoSize(reX, reY);
mMediaRecorder.setVideoFrameRate(fr);
mMediaRecorder.setMaxDuration(0);
mMediaRecorder.setMaxFileSize(Integer.MAX_VALUE);
mMediaRecorder.setVideoEncodingBitRate(bit * 1000);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.setOrientationHint(90);//豎屏播放,但貌似只有在android手機上播放有效,在pc上播放無效。
mMediaRecorder.setOutputFile(sender.getFileDescriptor());//設置輸出為本地socket

然后就是Camera的獲取和設置:

 1 public Camera getCamera(){
 2         if(camera==null){
 3             try{
 4                 camera = Camera.open();
 5                 Parameters paramters = camera.getParameters();
 6                 paramters.setPreviewSize(Integer.parseInt(getPreferences().resolution.split("×")[0]),Integer.parseInt(getPreferences().resolutio           n.split("×")[1]));
 7             }catch(Exception e){
 8                 e.printStackTrace();
 9                 try {
10                     if(camera!=null){
11                         camera.reconnect();
12                     }else{
13                         Toast.makeText(this, "連接攝像頭服務失敗!請重啟手機后再試。", Toast.LENGTH_SHORT).show();
14                     }
15                 } catch (IOException e1) {
16                     e1.printStackTrace();
17                 }
18             }
19             if (camera!=null) {
20                 camera.setDisplayOrientation(90);
           camera.setPreviewDisplay(mSurfaceHolder);
21 } 22 } 23 return camera; 24 }

負責預覽的SurfaceView和SurfaceHolder:

    /**
     * 初始化surfaceView
     */
    private void InitSurfaceView() {
        mSurfaceView = (SurfaceView) this.findViewById(R.id.surface_camera);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.setKeepScreenOn(true);
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//兼容低版本
    }

打開錄像:

try {
            mMediaRecorder.prepare();
            mMediaRecorder.start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            releaseMediaRecorder();
        }

到這里,已經可以在本地socket中拿到攝像頭獲取的流了。當然根據我的參數設置,獲得的流是系統MP4、h264編碼后的碼流。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM