More Related Content Similar to ブラウザでWebRTC - iOSゲートウェイ作ってみた (20) ブラウザでWebRTC - iOSゲートウェイ作ってみた1. WebRTC Meetup Tokyo #14
ブラウザでiOSゲートウェイ作ってみた
Build WebRTC - iOS Gateway on Browser
2017.03.23
インフォコム株式会社
がねこまさし
@massie_g
1
2. 自己紹介
• がねこまさし / @massie_g
• インフォコム株式会社 に所属
– 技術調査と社内での利用を推進するチーム
• WebRTC Meetup Tokyo スタッフの一人
• WebRTC Beginners Tokyo 講師の一人
• WebRTC入門2016を HTML5Experts.jpに連載してました
– https://html5experts.jp/series/webrtc2016/
2
3. 今日のお題
• iOS のブラウザでは、まだWebRTCが使えない
– WebkitではWebRTC対応が進んでいる様子。が、Safariに入るかはApple次第
• でも、今ある技術を使って、無理やりコミュニケーションできる!
– Canvas, Web Audio, WebSocket を利用
• 先行している試みを パクって 手本にして実現
– 音声: @leader22 「WebAudioでなんちゃってWebRTC」
• http://leader22.github.io/slides/webaudio_tokyo-1/
– 画像: @voluntas 「WebRTC SFU Sora ノススメ」のスナップショット機能
• https://gist.github.com/voluntas/0d6621d15947a24e710b0610093a5d20
3
4. DEMO
• PC Chrome iOS Safari
– ぱくたそ の写真を使わせていただいています
– https://www.pakutaso.com
• ソースコード
– https://github.com/mganeko/webrtcexpjp/tree/master/gateway
• ちょっと残念な部分もありますが…
– 縦の写真が上手く扱えない
4
5. PC Chrome iOS Safari (1) Video
5
getUserMedia()
MediaStream
<video>
<canvas>
Blob JPEB
setInterval()
drawImage()
toBlob()
Worker
WebSocket
(socket.io)
Blob
JPEB
socket.io
Server
postMessage()
Worker
WebSocket
(socket.io)
ArrayBuffer
postMessage()
ArrayBuffer
<img>
Blob
createObjectURL()
PC Chrome iOS Safari
6. PC Chrome iOS Safari (2) Audio
6
getUserMedia()
MediaStream
Worker
WebSocket
(socket.io)
socket.io
Server
Worker a
WebSocket
(socket.io)
PC Chrome iOS Safari
WebAudio
ScriptProcessor [Float32Array]
MediaStreamAudioSourceNode
[Uint8Array]
compress
postMessage()
ArrayBuffer
(decompress)
WebAudio
6
AudioBufferSource
ArrayBuffer
decoceAudioData()
AudioDestinationNode
postMessage()
7. PC Chrome iOS Safari : Image
7
<img>
toDataURL ()
Worker
WebSocket
(socket.io)
DataURL
socket.io Server
postMessage()
<img>
<img>
<img>
<canvas>
drawImage()
DataURL
toBlob ()
<img>
DataURL
img.src
Worker
WebSocket
(socket.io)
postMessage()
DataURL
iOS SafariPC Chrome
10. 通信データ量の削減:音声
10
• サンプリング周波数はプラットフォーム依存(※ブラウザ依存ではない)
– 44.1kHz (Mac) ← こちらの例で計算
– 48kHz (Windows, Linux, iOS)
• 圧縮
– WebAudio 元データ…44.1kHz × 32bit実数 = 1411 kbps
– 16bit リニアPCM 化 … 44.1kHz × 16bit整数 = 705 kbps
• ※CDは44.1kHz ×16bit × 2ch(Stereo) = 1411 kbps
– サンプリング周波数を半分の22 kHz に … 350 kbps
– μ-law 圧縮 22kHz, 8bit整数 … 175 kbps
• ※G.711 は 8kHz, 8bit整数 … 64kbps
– mp3 圧縮 … 36 kbps を指定
12. μ-law アルゴリズム
• 音声圧縮アルゴリズム、非可逆
• サンプル当たりのビット数を削減 … 今回は 8bit
• IP電話の G.711 規格で使われるアルゴリズム
– G.711では、サンプリング周波数は 8kHz → 64kbps
• Wikipedia
• https://ja.wikipedia.org/wiki/%CE%9C-law%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
– 北アメリカと日本のデジタル通信システムでμ-law使用 … PCMU
– ヨーロッパでは類似のA-lawアルゴリズムを使用 … PCMA
• WiFiでは使えなくはないが、LTEではまだキツイ(圧縮不足)
• 参考:WebAudioで原始的な音声圧縮をやってみた
– http://qiita.com/massie_g/items/49183a03b015b9ea27eb
– ソース: https://github.com/mganeko/webrtcexpjp/blob/master/tool/mulow.html 12
16. オマケ:G.722
• サンプリング周波数 16kHz、48, 56, 64kbps
• ADPCM (adaptive differential pulse code modulation)
• 圧縮のアルゴリズム(たぶんこんな感じ)
– 前のサンプルとの差分
• 小さい値になりやすい
– 差分を対数的に表現
• 小さい差分は細かく
• 大きい差分はおおざっぱに
16
リニアPCM ADPCM
ケータイWatch ケータイ用語の基礎知識より
http://k-tai.watch.impress.co.jp/cda/article/keyword/2936.html
17. lamejsによるMP3圧縮
• より音声データを圧縮するためにMP3を利用
• lamejs
– https://github.com/zhuker/lamejs
• ストリーミングではなく、細切れのMP3データを生成
• 入力は 16bit 整数の配列
– チャネル(ステレオ/モノ)、サンプルレート を指定可能
• 圧縮後は8bit整数の配列
– ビットレート(kbps)を指定可能
– 下限あり: 22kHz の場合 >= 32kbps 、 24kHzの場合 >= 36kbpsぐらい
17
18. Sample from GitHub
var channels = 1, sampleRate = 44100, kbps = 128; // mono, 44.1kHz, 128kbps
var mp3encoder = new lamejs.Mp3Encoder(channels, sampleRate, kbps);
var sampleBlockSize = 1152; // better to use 576 * n
var samples = new Int16Array(44100); // 1sec sample
var mp3Data = [];
for (var i = 0; i < samples.length; i += sampleBlockSize) {
sampleChunk = samples.subarray(i, i + sampleBlockSize);
var mp3buf = mp3encoder.encodeBuffer(sampleChunk);
if (mp3buf.length > 0) { mp3Data.push(mp3buf); }
}
var mp3buf = mp3encoder.flush(); //finish writing mp3
if (mp3buf.length > 0) { mp3Data.push(new Int8Array(mp3buf)); }
18
19. lamejs 利用にあたっての工夫
• MP3データのオーバーヘッドの抑制
– ヘッダ+タグ = 132byte
– 一度に変換する音声ブロックを、なるべく長く
– WebAudioのScriptProcessorの上限(16384 サンプル/回)で取得
• 370 ms (44.1kHz), 340 ms (48kHz)
19
ヘッダ 圧縮後データ MP3タグ
4byte 128byte1500~2000 byte
• 圧縮前のサンプルの半減: 44.1kHz→22.05kHz, 48kHz→24kHzに
• ビットレート下限の調整
– 下限あり: 22kHz の場合 >= 32kbps 、 24kHzの場合 >= 36kbpsぐらい
• WebWorkerで圧縮 … 1ブロックあたり 50ms ~ 100ms
26. まとめ
• iOS ブラウザで WebRTCが動かない… それがどうした!
– やりたいのはWebRTCではなく、コミュニケーション
• 今使えるもので、無理やりやってみよう!
– ブラウザの要素を自由に組み合わせられるのが「Web」RTC
– Canvas, WebAudio, WebSocket
• なぜか音声コーデックの歴史をたどる旅に
26