2024/09/13 Qiita Summit リアルタイムコミュニケーション LT 「動画配信技術に入門する」

# イベントリンク
[【オンライン】Qiita Summit ～リアルタイムコミュニケーション～ - connpass](https://increments.connpass.com/event/326712/)

***

# 自己紹介

- [khayama - Qiita](https://qiita.com/khayama)  - Cloudflare に関する150記事/3年。いいね！お待ちしております
- [kyhayama（@kyhayama）さん / X](https://x.com/kyhayama) - フォロー、Qiita 記事リクエストなどウェルカムです
- `mermaid` も使える [Qiita スライドモード](https://qiita.com/Qiita/items/4ff5873776992f0511d6)を使って話します
    - `mermaid` で [Architecture Diagrams (v11.1.0+)](https://mermaid.js.org/syntax/architecture.html) が描けるように --> Qiita にもサポートしてほしい

<img width="1140" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/f9a09f61-c46d-34ca-48d1-339a86d77c0e.png">

***

# 今日話すこと

- 動くものを見せる
- 開発に使えるツールを紹介する
- 具体的な手順が書かれた記事も紹介

> 実はこういうの嫌いじゃないです
> [「技術的革新について話すだけのヤツはクソだ、黙って手を動かせ」とLinux生みの親のリーナス・トーバルズが語る - GIGAZINE](https://gigazine.net/news/20170217-talk-of-tech-innovation-linus-torvalds/)
> <img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/ac397584-028e-f279-a27d-584c6feb2633.png">

***

# リアルタイムって？
- 要は同期型の双方向通信
- 動画に関連して分類すると以下のようになる
    - テキストチャットとは独立して考えることができる

```mermaid:
---
config:
  theme: default
---
%%{init: {"quadrantChart": {"chartWidth": 1200, "chartHeight": 500, "quadrantLabelFontSize": 40, "xAxisLabelFontSize": 32, "yAxisLabelFontSize": 32} }}%%
quadrantChart
  x-axis "同期型" --> "非同期型"
  y-axis "双方向通信" --> "片方向通信"
  quadrant-1 "Video On Demand (VOD)"
  quadrant-2 "Live Streaming"
  quadrant-3 "Online Meeting"
  quadrant-4 "N/A"
```

***

# 参考：WebSocket を使った同期型の双方向通信

- クライアント/サーバー型通信 - [socket.io](https://github.com/socketio/socket.io)、[PartyKit](https://github.com/partykit/partykit)、[yjs](https://github.com/yjs/yjs) 等のライブラリ
- テキストや座標データを使ったユースケースがメイン（チャットルーム、IoTデバイス制御など）
- バイナリデータ（音声・画像・映像等）送受信のチャネルとして利用することは可能
    - 動画配信の場合、ストリーミングに関わる周辺機能がないため、高度な処理の実装が必要
- [WebSocketの次の技術！？WebTransportについての解説とチュートリアル #websocket - Qiita](https://qiita.com/yuki_uchida/items/d9de148bb2ee418563cf#websocket)

<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/0e5e1d9f-43c2-4248-7081-33b29f84139f.png">
 
***

# おさらい：[動画配信技術に入門する - Qiita](https://qiita.com/khayama/items/fe10e2068b53584cfbd6)

- Video On Demand (VOD) = **非同期**型の**片方向**通信：事前にファイルをアップロード
    - 動画ファイルのキャッシュを効かせたり、配信サービスを使う
- Live Streaming = **同期**型の**片方向**通信：入力から配信までを同時におこなう
    - 動画ファイルのキャッシュ効果は限定的で、最大瞬間風速の負荷に耐えうる準備が必要

```mermaid:
%%{init: {'theme': 'default','themeVariables': {'fontSize': '18px'}}}%%

graph LR

subgraph Live Streaming
subgraph ソース
direction TB
    音声
    映像
    音声~~~映像
end

subgraph 配信ソフト
    OBS[OBS など]
end
end

subgraph 配信システム
direction TB
    ストレージ
    計算リソース
    キャッシュ
    %%ストレージ~~~キャッシュ
end

subgraph VOD
    録画ファイル
end

視聴者
%%視聴者1[視聴者]
%%視聴者2[視聴者]
%%視聴者3[視聴者]

録画ファイル --> |アップロード|ストレージ
ソース --> |Input|配信ソフト
配信ソフト--> |"Ingestion<br>（RTMP, SRT, WebRTC など）"|配信システム 
配信システム --> |"Egress<br>（HLS, DASH, WebRTC など）"|視聴者
%%キャッシュ --> 視聴者1 & 視聴者2 & 視聴者3
```

***
# 技術があるのはわかったけど、どう使うの？
***

# [Video On Demand] VOD 構成例 + デモ

- [Cloudflare で HTTP Live Streaming (HLS) をキャッシュする #cloudflare - Qiita](https://qiita.com/khayama/items/98cfeb119f520fbf2a4d)
    - あくまで Enterprise Plan 向けの構成（Ref. [CDN Service-Specific Terms](https://www.cloudflare.com/ja-jp/service-specific-terms-application-services/#content-delivery-network-terms)）

```mermaid:
%%{init: {'theme': 'default','themeVariables': {'fontSize': '18px'}}}%%

graph LR

subgraph 配信サーバー
direction TB
    subgraph /video
        マニフェスト.m3u8
        セグメント1.ts
        セグメント2.ts
        ...
        動画.mp4 --> |ffmpeg 変換|マニフェスト.m3u8 & セグメント1.ts & セグメント2.ts & ...
    end
    subgraph HTML
        hls.js
    end
    %%ストレージ~~~キャッシュ
end

subgraph VOD
    Original[動画.mp4]
end

subgraph Cloudflare
    キャッシュ
end

視聴者
%%視聴者1[視聴者]
%%視聴者2[視聴者]
%%視聴者3[視聴者]

Original --> |アップロード|動画.mp4
/video ~~~ HTML
配信サーバー ---> Cloudflare --> |"Egress<br>（HLS）"|視聴者
%%キャッシュ --> 視聴者1 & 視聴者2 & 視聴者3
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/9e041337-1747-238b-c222-3ae0a997f6c9.png)

***

# [Video On Demand] Cloudflare でオリジンレスな VOD の構成例

- [Cloudflare Pages (Functions) と Stream と Access を使って動画サイトを作る #cloudflare - Qiita](https://qiita.com/khayama/items/6a644965bdbaa7207224)

```mermaid:
---
config:
  theme: default
---
graph LR

subgraph Cloudflare
    subgraph Pages
        Static[Static Assets]
        Functions
    end
    subgraph Stream
        Videos
    end
    Access
end

Viewer --> |"/admin"|Access
Static --> |"/index.html, /admin"|Viewer
Functions --> |"/api/*"|Viewer
Videos --> Viewer
Access --> |Allow|Static
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/1c978590-e57f-ac2e-3c9d-05575a3c0cb4.png)

***


# [Live Streaming] WebRTC を使った 構成例 + デモ (1-to-many)

- 1 秒未満の遅延 (Sub-second latency) を目指せる
- なんといってもブラウザだけあれば使える
- Ingestion ([WHIP](https://www.ietf.org/archive/id/draft-ietf-wish-whip-03.html), WebRTC-HTTP Ingest Protocol) と Egress ([WHEP](https://www.ietf.org/id/draft-murillo-whep-00.html), WebRTC-HTTP Egress Protocol) の両方で使える

> [WebRTC live streaming to unlimited viewers, with sub-second latency](https://blog.cloudflare.com/webrtc-whip-whep-cloudflare-stream/)
> <img width="1000" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/5b82b909-dda0-dee9-80b4-59ee8287d89d.png">

***

# [Online Meeting] Cloudflare Calls を活用した Orange Meets デモ
- Cloudflare Calls = サーバーレスな WebRTC SFU + TURN as a Service (Open Beta, 無償枠あり)
    - 1:1のビデオ通話から大規模な1-to-many / many-to-manyまで構築できるビルディングブロック
    - 強みを活かして [ICEPerf](https://iceperf.com/results) で最も高速なプロバイダを目指す

> Online Meeting デモ : [cloudflare/orange](https://github.com/cloudflare/orange)
> <img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/ea78976f-8fa9-658c-b5e8-deee16bd86ee.png">

***

# まとめ：動画配信 x リアルタイムコミュニケーション

- 3つのユースケースを体感
- WebRTC を活用すると「超低遅延・ブラウザベース」の仕組みが実現できる
- リアルタイムを作るって楽しそう

```mermaid:
---
config:
  theme: default
---
%%{init: {"quadrantChart": {"chartWidth": 1200, "chartHeight": 500, "quadrantLabelFontSize": 40, "xAxisLabelFontSize": 32, "yAxisLabelFontSize": 32} }}%%
quadrantChart
  x-axis "同期型" --> "非同期型"
  y-axis "双方向通信" --> "片方向通信"
  quadrant-1 "Video On Demand (VOD)"
  quadrant-2 "Live Streaming"
  quadrant-3 "Online Meeting"
  quadrant-4 "N/A"
```

# その他参考

- [Introduction | WebRTC for the Curious](https://webrtcforthecurious.com/)