Flutterで動画配信するプラグインを作った話

 Flutterで動画配信するプラグインを作った話

FlutterでPlatformViewを使わずにカメラ画像を表示する動画配信プラグインを作成しました。

9d9ab1b45680b4f673e398b2c394797d?s=128

Takashi Kawasaki

July 16, 2019
Tweet

Transcript

  1. Flutterで 動画配信するプラグインを 作った話 川崎 高志 @espresso3389 クミナス株式会社

  2. 自己紹介 • 川崎 高志 (@espresso3389) • クミナス株式会社 代表取締役 CEO •

    恵比寿の会社です • なんでもやる人 • Flutterは好きなんだけどどちらかというと底レイヤー担当
  3. 動画配信概要 カメラ プレビュー画面 FLV H.264 RTMP配信 多数の閲覧者 配信サーバー Android/iOSアプリ HLS配信

    test.m3u8 test-0.ts test-1.ts test-2.ts …
  4. PlatformView撲滅 • いろいろ不安定 • 異物感がある • 単に嫌い • 回避技術に興味がある

  5. カメラ~エンコード/表示周り • Android • Camera/Camera2 でカメラ画像取り込み • MediaCodec でH.264変換 •

    SurfaceTextureに表示 • iOS • AVFoundationでカメラ画像取り込み • AVFoundationとかの何かでH.264変換 • 多分、OpenGL Metalでなんとか表示 自分でやると死ぬ
  6. 他力本願 • 無修正のまま使えるRTMPライブラリは見つからない • 最低限の調整で何とかなりそうなライブラリを探す • Android • RtmpPublisher by

    TakuSemba • 結構大掛かりな修正が必要だが他よりはかなり修正範囲が少ないかも • iOS • HaishinKit.swift by shogo4405 • とてもきれいなライブラリ! • でもFlutterで使うにはちょっとだけ問題あり
  7. Flutterプラグイン with Texture • PlatformViewを使わず、Texture Widgetを使う • プラットフォーム側からTexture IDを受け取るだけ ※Flutter

    Camera/Video Player Pluginのコードを頑張って理解した
  8. Flutterプラグイン with Texture • Android • registrar.textures().createSurfaceTexture()でSurfaceTextureEntryを作成 • SurfaceTextureEntry.surfaceTexture()でSurfaceTextureを取得 •

    SurfaceTextureEntry.id()でTexture IDを取得 • iOS • FlutterTextureプロトコルを実装 • func copyPixelBuffer() -> Unmanaged<CVPixelBuffer>? • Registrar.textures().register(obj) で登録すると疑似的なTexture IDが返る
  9. Androidでの実装 with RtmpPublisher • パッケージとしての取り込みは断念 • ライブラリ部分だけをソースとして引き込み • RtmpPublisher.javaをほぼ全書き直し for

    Flutter • FlutterGLSurfaceView • TODO: Camera→Camera2
  10. Androidでの実装 with RtmpPublisher • RtmpPublisherはGLSurfaceViewに大きく依存している • GLSurfaceViewをFlutter向けに継承 • 実際の描画はバイパスされFlutter側のTextureに対して行われる •

    Activityにぶら下がるGLSurfaceViewは基本的には何も表示しない
  11. Androidでの実装 with RtmpPublisher

  12. iOSでの実装 with HaishinKit.swift • サンプルそのままで90%はOK ネイティブのUIViewを 埋め込むのは避けたい

  13. iOSでの実装 with HaishinKit.swift • HKViewはNetStreamDrawableというプロトコルを実装してい る • CIImage.pixelBuffer(iOS10以降)はCVPixelBufferなので FlutterTextureに渡すのは簡単

  14. iOSでの実装 with HaishinKit.swift • NetStreamDrawableはフレームワークの外には公開されてない • Podを使うことを断念 • ソースを直接引き込むことにする

  15. まとめ • 全部自分で実装するのはシンドイ • iOSは簡単だったというか、HaishinKit.swiftは美しい • AndroidのRTMPライブラリには決定打がないっぽい • GradleとかCocoaPodsで楽はできませんでした •

    Flutterは楽しくて開発も早いが、プラグイン側は死ねる
  16. ソースコード • flutter_rtmp_publisher • https://github.com/espresso3389/flutter_rtmp_publisher • 大枠は動いた • エラー処理が甘すぎる •

    iOS/Androidで一部挙動が異なる