Costel 項目評審

//--- theme: github highlight: a11y-dark

項目背景:

該項目場景是方便用戶在廚房也能繼續經過智能平板觀看電視節目。咱們須要開發一個應用用來接收電視傳過來的音視頻數據,而後將音視頻數據傳輸到平板端進行播放,用戶能經過平板來操控電視。git

需求分析:

1.功能性需求分析

  • TV Box開機後,默認的WIFI名稱爲COSTEL001
  • PAD須要接收TV的APP,當打開須要默認與TV BOX相連
  • 818板卡解TV端發送的音視頻信號(後方案變爲從攝像頭獲取mipi信號的數據,經過錄音獲取音頻數據)
  • 經過網絡傳輸,音視頻數據在PAD端進行播放
  • PAD在播放網絡視頻的時候,可將聲音經過藍牙傳給TV BOX內置的喇叭播放
  • 須要的遙控菜單,包括音量+/-;頻道+/-;關機;確認鍵等,按鍵信息最終由RK3128控制

image.png

實際上,開發過程當中,還能挖掘出了下面幾個隱藏的需求。github

  • 因爲板卡沒法發出熱點,因此不能經過熱點的方式進行配對鏈接。經溝通,使用同一局域網進行鏈接。此方案存在的隱患爲:其它設備在同一局域網下,也可獲取TV數據,並調用TV的喇叭,因此須要 鑑權功能;
  • 當TV進行傳輸音視頻的同時,PAD本地若是也正在播放媒體,就會將聲音傳給TV喇叭,這很明顯是不合理的。

2. 非功能性需求分析

項目中視頻方面採用的技術邏輯爲: 咱們還須要考慮不少非功能性的需求。具體來說,我總結了如下幾個比較重要的方面。算法

  • 易用性

包括產品的易用性和代碼的易用性。產品的易用性是指:用戶不須要花太多時間思考就能上手應用,老小皆宜。代碼的易用性是指:框架是否易集成、易插拔、跟業務代碼是否鬆耦合、提供的接口是否夠靈活等等,都是咱們應該花心思去思考和設計的。markdown

  • 性能

咱們但願應用自己的代碼執行效率,對系統沒有太多性能上的影響。音視頻播放一方面,咱們但願它是低延遲的,音視頻是同步的;另外一方面,咱們但願應用自己對內存的消耗不能太大。這塊後期需認真思考。網絡

  • 擴展性

是指在不修改或儘可能少修改代碼的狀況下添加新的功能,即符合開閉原則。在增長一些新的視頻數據的獲取方式、音頻獲取方式、或者編碼方式的時候,不需改動原有邏輯。框架

技術選型:

  • 設備配對:818板卡發送NSD攜帶port,PAD端經過掃描同一ip網段下的該port設備,經過CRCP協議實現配對ide

  • 應用鑑權初步方案:1.818板卡未配對,正常發送帶port的NSD服務;2.當有設備配對後,818用配對設備的DeviceId經算法加密後發送加密port的NSD服務,PAD端有重試機制,第一次直接鏈接該port,失敗後使用算法解密後嘗試鏈接。鏈接成功之後默認配對性能

  • 818視頻採集、解碼及播放:Camera2 + MediaCodeC + SurfaceTexture,編碼格式採用h264ui

  • 818音頻採集、解碼及播放:AudioRecord + MediaCodec/OpusLib +AudioTrack,編碼格式爲Opus。 VS AAC:在編碼延時方面。首先,Opus是由兩個編解碼器Silk和Celt融合而成。Celt 僅編碼延時方面是優於AAC 的,合併成Opus後有所增加,但仍是低於AAC。 質量方面:Celt 最初的質量不如 AAC。在成爲 Opus 的一部分後,犧牲了一部分的延時,增長了一些新技術以後,質量與 AAC 至關,甚至更好一些。在壓縮率方面,Opus裏共有32種模式用來處理不一樣種類的信號,opus在碼率和音質上的確是有優點的。(參考 :https://zhuanlan.zhihu.com/p/66719842)this

  • TVBOX喇叭進行播放: 當PAD中止電視回傳 且 本地有媒體播放時,經過BlueTooth藍牙配對

  • PAD遙控器指令發送:PAD 與818間經過CRCP傳輸遙控碼,818與3553之間經過AIDL傳遙控碼

總體工做流程

image.png

時序圖

1.Camera2採集視頻數據:

image.png 整個過程使用Camera2來獲取數據,獲取的數據經過MediaCodec編碼,使用H264協議,接收端接收到數據以後解碼,而後經過TextureView渲染,大概是這麼一個流程,下面記錄下實現過程。

1.相機初始化 獲取可用的相機列表、相機相關的屬性

String[] cameraIdList = mCameraManager.getCameraIdList();
 CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(cameraId);
複製代碼

2.在打開相機以前先,先要去獲取相機支持的最接近的預覽尺寸,而後要實例化一個ImageReader,用來接收Camera2的可用數據。這些作完以後,須要監測TextureView是否可用,不可用先設置setSurfaceTextureListener監聽,可用以後再來打開相機。 添加接收數據回調的Target Surface

mPreviewSize = getBestSupportedSize(new ArrayList<Size>(Arrays.asList(map.getOutputSizes(SurfaceTexture.class))));
mImageReader.setOnImageAvailableListener(this, mBackgroundHandler);
複製代碼

3.創建Camera2預覽會話,經過RepeatingRequest()進行連續請求

private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(@NonNull CameraDevice cameraDevice) {
        Camera2TextureView.this.mCameraDevice = cameraDevice;
        createCaptureSession();
    }
   
    mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        //添加接收數據回調的Target Surface
        mPreviewRequestBuilder.addTarget(mWorkingSurface);
        mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
        
        mCaptureSession.setRepeatingRequest(mPreviewRequest, null, mBackgroundHandler);

複製代碼

4.經過imageReader 讀取相機數據。因爲Camera2的yuv數據獲取到數據須要本身手動拼接,因此這裏是和Camera1不一樣的,獲取到的數據拼接成nv21,須要轉化成nv12,由於MediaCodec不支持nv21。採集到數據以後,經過mediaCodec進行編碼操做。

public void onImageAvailable(ImageReader reader) {

Image image= reader.acquireNextImage();
複製代碼

image.png

  1. 聲音錄製編碼及解碼播放

用戶登陸成功uml時序圖.png MirrorAudioManager是上帝類,持有AudioRecorder 和AudioEncoder的

UML圖

1.設備配對時鑑權

相關文章
相關標籤/搜索