Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
WebCodecsの実装状況 / Status of WebCodecs
Search
mganeko
June 23, 2023
Technology
0
970
WebCodecsの実装状況 / Status of WebCodecs
WebRTC Meetup Tokyo #24 のLT資料です。
WebCodecsの2023年6月の実装状況についてのまとめです
mganeko
June 23, 2023
Tweet
Share
More Decks by mganeko
See All by mganeko
Canvasで簡易背景ぼかしをやってみた
mganeko
0
590
M1 Macと将棋AIとUSI
mganeko
0
1.1k
Small Tips to use Bun with WebSocket Server and WebAssembly Modules
mganeko
0
4.9k
Build Node.js–WASM/WASI tiny compiler with Node.js
mganeko
0
600
Node.js x Chrome headless for WebRTC MCU
mganeko
1
3.1k
Extend User Experience of WebRTC with Cool Sensor Devices
mganeko
0
550
Playing with OSS WebRTC SFU meidasoup (update for v1.2)
mganeko
0
690
Build WebRTC iOS Gateway on Browser
mganeko
0
1.1k
Playing with OSS WebRTC SFU meidasoup
mganeko
0
510
Other Decks in Technology
See All in Technology
JEP 480: Structured Concurrency
aya_ebata
0
120
Optuna: a Black-Box Optimization Framework
pfn
PRO
1
110
20240911_New_Relicダッシュボード活用例
speakerdeckfk
0
100
2024年版 運用者たちのLLM
nwiizo
3
550
Jetpack Compose Modifier 徹底解説 / Jetpack Compose Modifier
wiroha
0
110
「家族アルバム みてね」における運用管理・ オブザーバビリティの全貌 / Overview of Operation Management and Observability in FamilyAlbum
isaoshimizu
4
150
ナレッジグラフとLLMの相互利用
koujikozaki
0
320
Envoy External AuthZとgRPC Extensionを利用した「頑張らない」Microservices認証認可基盤
andoshin11
0
220
PDF Viewer作成の今までとこれから
hunachi
0
270
リアルお遍路+SORACOM IoT
ozk009
1
120
Google CloudのLLM活用の選択肢を広げるVertex AIのパートナーモデル
nayuts
0
100
音声AIエージェントの世界とRetell AI入門 / Introduction to the World of Voice AI Agents and Retell AI
rkaga
5
910
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
518
39k
What's new in Ruby 2.0
geeforr
340
31k
4 Signs Your Business is Dying
shpigford
179
21k
Pencils Down: Stop Designing & Start Developing
hursman
119
11k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Bootstrapping a Software Product
garrettdimon
PRO
304
110k
Making the Leap to Tech Lead
cromwellryan
128
8.8k
A designer walks into a library…
pauljervisheath
201
24k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
354
29k
How to name files
jennybc
75
98k
KATA
mclloyd
27
13k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
230
17k
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で行く が吉