首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 影片播放:如何在 SurfaceView 中渲染伺服器傳來的幀數據

     編輯:程式設計綜合問答

問題背景

開發者需在 Android 上播放伺服器推送的原始幀數據,專案時程緊迫,希望獲得可落地的技術路線與開源庫推薦。

核心解決思路

  1. 解碼層:使用 MediaCodec (API 16+) 進行硬體解碼,將 H.264/H.265 幀數據解碼為 YUV 畫面。
  2. 渲染層:搭配 SurfaceView 或 TextureView 顯示解碼後的畫面;SurfaceView 適合全螢幕播放,效能較佳。
  3. 緩衝策略:建立環狀緩衝區(如 ArrayBlockingQueue),網路執行緒寫入,解碼執行緒讀取,平滑抖動。
  4. 同步機制:依據 PTS (Presentation Time Stamp) 控制渲染時機,必要時丟幀或重複幀。

推薦開源專案

  • ExoPlayer (Google 官方):支援自定義 MediaSource,可直接餵入幀數據,文檔完善、維護活躍。
  • ijkplayer (Bilibili):基於 FFmpeg,支援多種封裝格式,適合需相容舊協議的專案。
  • GifView:若幀數據已編碼為 GIF,可直接用此輕量庫顯示動畫(參考原回答連結)。

最小可行性原型 (MVP) 步驟

// 1. 建立 SurfaceView 與 Holder
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
    @Override public void surfaceCreated(SurfaceHolder holder) {
        // 2. 啟動解碼執行緒,傳入 holder.getSurface()
        new DecodeThread(holder.getSurface()).start();
    }
    // ...
});

// 3. 解碼執行緒邏輯
class DecodeThread extends Thread {
    private final Surface surface;
    private MediaCodec codec;
    DecodeThread(Surface s) { surface = s; }
    @Override public void run() {
        codec = MediaCodec.createDecoderByType("video/avc");
        codec.configure(format, surface, null, 0);
        codec.start();
        while (!isInterrupted()) {
            int idx = codec.dequeueInputBuffer(10000);
            if (idx >= 0) {
                ByteBuffer buf = codec.getInputBuffer(idx);
                buf.put(fetchFrameFromNetwork()); // 從隊列取幀
                codec.queueInputBuffer(idx, 0, buf.position(), pts, 0);
            }
            // 處理輸出緩衝區...
        }
    }
}

避坑指南

  • 網路層務必處理斷線重連與背壓,否則緩衝區易溢出導致 OOM。
  • 解碼前需送入 SPS/PPS (H.264) 或 VPS/SPS/PPS (H.265) 初始化解碼器。
  • 釋放資源時按順序:codec.stop() → codec.release() → surface.release()。

結語

若專案允許引入成熟播放器,首選 ExoPlayer 自定義 DataSource;若須自研,參考上述 MediaCodec + SurfaceView 架構,分模組實作網路、緩衝、解碼、渲染四層,單元測試逐層驗證,可在緊湊時程內交付穩定播放功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved