Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
WebCodecsの実装状況 / Status of WebCodecs
Search
mganeko
June 23, 2023
Technology
1.8k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
WebCodecsの実装状況 / Status of WebCodecs
WebRTC Meetup Tokyo #24 のLT資料です。
WebCodecsの2023年6月の実装状況についてのまとめです
mganeko
June 23, 2023
More Decks by mganeko
See All by mganeko
OpenAI RealTime API WebRTCモード - シグナリングとDataChannelの使い道 -
mganeko
0
350
Canvasで簡易背景ぼかしをやってみた
mganeko
0
1.1k
M1 Macと将棋AIとUSI
mganeko
2
1.5k
Small Tips to use Bun with WebSocket Server and WebAssembly Modules
mganeko
0
5.4k
Build Node.js–WASM/WASI tiny compiler with Node.js
mganeko
0
790
Node.js x Chrome headless for WebRTC MCU
mganeko
1
3.4k
Extend User Experience of WebRTC with Cool Sensor Devices
mganeko
1
750
Playing with OSS WebRTC SFU meidasoup (update for v1.2)
mganeko
0
960
Build WebRTC iOS Gateway on Browser
mganeko
0
1.3k
Other Decks in Technology
See All in Technology
継続的なAIコスト最適化
bgpat
1
300
[AWS 秋のクラウドオペレーション祭り 2026]AWS DevOps Agentで変わるリリースと運用対応 ~リリース管理機能と Directed actions のご紹介~
furuton
4
1.2k
go-sqletch
moznion
0
140
Claude Code本は、どのように執筆チームで書かれたか
oikon48
1
370
自作バイナリを動かす「入口」8選
puhitaku
2
1.3k
M5Stackで作る BLEマウス GPSログの世界
tomokusaba
0
260
NDIでApple Vision Proにリアルタイム映像送信
jyouryuusui
0
110
Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
1
280
味覇で作るパスタが美味い - 20261001_yabaubuki.dev
livesense
PRO
0
130
PagerDuty Tech Hub-鳴らすけれど、人は動かない
ezaki
0
130
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
1.5k
Kiro Crewをはじめよう
kizawa2020
1
150
Featured
See All Featured
Context Engineering - Making Every Token Count
addyosmani
9
1.2k
Darren the Foodie - Storyboard
khoart
PRO
4
4k
Believing is Seeing
oripsolob
1
240
Being A Developer After 40
akosma
92
590k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
Ten Tips & Tricks for a 🌱 transition
stuffmc
1
260
brightonSEO & MeasureFest 2025 - Winning Strategies for Black Friday CRO & PPC - Christian Goodrich
cargoodrich
3
870
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
67k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
340
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
980
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.2k
Transcript
WebCodecs 実装状況 (2023年6月現在) WebRTC Meetup Tokyo #24 2023.06.23 @massie_g /
が こまさし
WebCodecs APIと • VideoやAudioをエンコード、デコードするAPI • 仕様 ◦ WebCodecs W3C Working
Draft, 11 May 2023 ◦ https://www.w3.org/TR/webcodecs/ • 関連する仕様 ◦ MediaStreamTrack Insertable Media Processing using Streams ▪ Editor’s Draft, 20 October 2022 • https://w3c.github.io/mediacapture-transform/ ▪ Unofficial Proposal Draft, 26 November 2021 • https://alvestrand.github.io/mediacapture-transform/chrome-96.html
https://caniuse.com/webcodecs • Chrome 114 / Edge 114 … Video, Audio
サポート • Safari TP171 … Video みサポート, オプション指定 • Firefox … 未対応
Video
VideoFrame VideoEncoder EncodedVideoChunk EncodedVideoChunk EncodedVideoChunk VideoDecoder VideoFrame VideoEncoder / VideoDecoder
VideoFrame VideoEncoder EncodedVideoChunk EncodedVideoChunk EncodedVideoChunk VideoDecoder VideoFrame VideoFrameを作る/使う <img> <canvas>
<video> ImageBitmap OffscreenCanvas VideoFrame <canvas> コンストラクタ new VideoFrame() drawImage()
VideoFrameを作る const frame = new VideoFrame(element, { timestamp: timestamp_in_micro_second, //
タイムスタンプをμ秒で指定 duration: duration_in_micro_second, // フレーム 長さをμ秒で指定 }); // do something with frame // release frame.close(); 属性 • readonly attribute VideoPixelFormat? format; • readonly attribute unsigned long codedWidth; • readonly attribute unsigned long codedHeight; • readonly attribute DOMRectReadOnly? codedRect; • readonly attribute DOMRectReadOnly? visibleRect; • readonly attribute unsigned long displayWidth; • readonly attribute unsigned long displayHeight; • readonly attribute unsigned long long? duration; // μs • readonly attribute long long timestamp; // μs • readonly attribute VideoColorSpace colorSpace;
VideoFrame フォーマット • 元にした要素により、フォーマットが異なる • ブラウザによっても、フォーマットが異なる 元 要素 Chrome 114
/ Canary 116 (Win10, M1 Mac) afari P 171 (M1 Mac) img(jpeg) BG X GBA canvas GBA GBA video(mp4) NV12 I420 video(camera) I420 I420 • BGRX ◦ Blue, Green, Red, ◦ X:透明度 … 255で透明 • RGBA ◦ Red, Green, Blue ◦ A:αチャンネル … 255で不透明 • YUV420 (NV12, I420) ◦ 画像/映像 情報量を抑える形式 ▪ https://qiita.com/Yossy_Hal/items/8e0b9676698 ba552c210 ◦ Y(輝度), U(青色式差), V(赤色式差) ▪ Y そ まま ▪ U, V 縦横半分に間引く ◦ U, V 並べ方 違いでNV12とI420がある
VideoFrameを使う: Canvasに描画 const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, width, height);
ctx.drawImage(videoframe, 0, 0);
Encode → Decode実験 (1) Encoder const encoder = new VideoEncoder({
output: (chunk) => { // エンコード成功時 処理 }, error: (err) => { /* エラー時 処理 */ } }); await encoder.configure({ codec: CODEC, // コーデック 指定 width: WIDTH, // 幅 指定 height: HEIGHT, // 高さ 指定 framerate: 10 // フレームレート 指定 }); // フレーム取得 const frame = new VideoFrame(element, { timestamp: timestamp_in_micro_second, duration: duration_in_micro_second }); // エンコード (成功すると、output に指定した関数が呼 れ る) encoder.encode(frame, { keyFrame : true}); // true: キーフレーム、false: 差分フレーム frame.close(); // フレームを解放
Encode → Decode実験 (2) Decoder const decoder = new VideoDecoder({
output: (frame) => { // デコード成功時 処理 frame.close(); //フレームを解放 }, error: (err) => { /* エラー時 処理 */ } }); await decoder.configure({ codec: CODEC }); // デコード (成功すると、output に指定した関数が呼 れる) decoder.decode(chunk); // chunk エンコード済み データ
Encode → Decode実験(img, mp4, カメラ映像、全てkeyframe) コーデック Chrome 114 / Canary
116 (Win10, M1 Mac) Safari TP 171 (M1 Mac) デコード結果 デコード後 フォーマット デコード結果 デコード後 フォーマット VP8 〇 2フレーム目 デコードで表示 (outputが呼 れる) I420 〇(img, video:カメラ映像) 1フレーム目 デコードで表示 ✕(video:mp4) 緑色や崩れた描画 I420 VP9 profile0 〇 1フレーム目 デコードで表示 NV12 〇(img, video:カメラ映像) 1フレーム目 デコードで表示 ✕(video:mp4) 緑色や崩れた描画 I420 VP9 profile2 〇 1フレーム目 デコードで表示 null ✕ エラー: Not supported ✕ AV1 〇 4フレーム目 デコードで表示 I420 ✕ NotSupportedError: VPx encoding initialization failed with error -1 ✕ H.264 〇 2フレーム目 デコードで表示 NV12 〇 1フレーム目 デコードで表示 I420
参考: Encoder/Decoder 初期化オプション コーデック encoder.configure() オプション例 decoder.configure() オプション例 VP8 codec
: "vp8" codec : "vp8" VP9 profile0 codec: "vp09.00.10.08" codec: "vp09.00.10.08" VP9 profile2 codec: "vp09.02.10.10" codec: "vp09.02.10.10" AV1 codec: "av01.0.01M.08" codec: "av01.0.01M.08" H.264 codec: "avc1.42001E", avc: { format: "annexb" } codec: "avc1.42001E"
Audio
AudioEncoder EncodedAudioChunk EncodedAudioChunk AudioDecoder AudioEncoder / AudioDecoder AudioData AudioData AudioData
AudioData AudioData AudioData AudioData AudioData AudioData AudioData Chromeで 20ms 長さで分割 EncodedAudioChunk EncodedAudioChunk EncodedAudioChunk EncodedAudioChunk EncodedAudioChunk EncodedAudioChunk Chromeで 48k sample/sec, 20ms 長さ Chromeで 3k~768k sample/sec 長さ 自由
AudioData const audioData = new AudioData({ format: format, // "u8",
"s16", "s32", "f32", (※"f32" み確認) // "u8-planar", "s16-planar", "s32-planar", "f32-planar" sampleRate: sampleRate, // Chromeで 3,000 ~ 768,000 numberOfFrames: frames, // 何個分 サンプルを持っているか numberOfChannels: channels, // 1:モノラル or 2:ステレオ (※1: み確認) timestamp: timestamp, // μ秒で指定 data: data }); ※WebAudio AudioBufferと 異なる。そ ままで 再生できない
AudioEncoder encoder = new AudioEncoder({ output: (chunk) => { //
エンコード成功時 処理 }, error: (err) => { /* エラー時 処理 */ } }); await encoder.configure({ codec: CODEC, numberOfChannels: 1 sampleRate: SAMPLE_RATE, }); 仕様上 CODEC • Audio Codecs https://w3c.github.io/webcodecs/codec_registry.htm l#audio-codec-registry • "flac" ... Flac • "mp3" ... MP3 • "mp4a.*" ... AAC • "opus" ... OPUS • "vorbis" ... Vorbis • "ulaw" ... u-law PCM • "alaw" ... A-law PCM • "pcm-*" ... Linear PCM → 現状Chrome OPUS みサポート
AudioDecoder decoder = new AudioDecoder({ output: async (audioData) => {
// デコード成功時 処理 audioData.close(); }, error: (err) => { /* エラー時 処理 */ } }) await decoder.configure({ codec: CODEC, numberOfChannels: 1, sampleRate: SAMPLE_RATE, }); // エンコード encoder.encode(audioData); // デコード decoder.decode(chunk);
MediaStreamTrack Insertable Media Processing using Streams Processor / Generator
Processor / Generator MediaStream MediaStreamTrack (video) MediaStreamTrack (audio) MediaStreamTrack Processor
MediaStreamTrack Processor VideoFrame AudioData AudioData AudioData MediaStreamTrack Generator MediaStreamTrack Generator MediaStreamTrack (video) MediaStreamTrack (audio) MediaStream Encoder ↓ Decoder VideoFrame AudioData AudioData AudioData
MediaStream/MediaStreamTrackと 組合せ MediaStreamTrack Insertable Media Processing using Streams Unofficial Proposal
Draft, 26 November 2021 Editor’s Draft, 20 October 2022 Chrome 114 (Unofficial Proposal) Safari TP171 未対応 MediaStreamTrack → VideoFrame MediaStreamTrackPr ocessor MediaStreamTrack Processor MediaStreamTrack Processor 未対応 VideoFrame → MediaStreamTrack MediaStreamTrackG enerator VideoTrackGenera tor MediaStreamTrack Generator 未対応 MediaStreamTrack → AudioData MediaStreamTrackPr ocessor MediaStreamTrack Processor MediaStreamTrack Processor 未対応 AudioData → MediaStreamTrack MediaStreamTrackG enerator なし MediaStreamTrack Generator 未対応
まとめ • WebCodecs ◦ Chrome かなり実装もこなれてきた ▪ Chrome限定なら、使える場面もありそう ◦ Safari
まだまだ、Audio無し ▪ Safariで使うなら、H.264が無難 • MediaStreamTrack Insertable Media Processing using Streams ◦ 仕様がまた整理されていない、使うに まだ早い ▪ Chromeで 実験 、もう始められる 個人 見解 • WebCodecsが普及する まだまだ先(5年以上) • し らく WebRTCで行く が吉