SlideShare una empresa de Scribd logo
1 de 18
Descargar para leer sin conexión
汎用的なオンラインビデオ会議
システムを作る
森山雄太
DEMO
ビデオ会議システム+メディア
で必要な機能
• ビデオで通話を行う
– ビデオ、音声のみ、snapshotコマ送りの切り替え
• 録音
• 会話の文字起こし
• チャット
• ユーザ間同期
• 部屋への入室
今日は録音にFOCUS
もっと良いやり方があったら
教えてもらいたいから
録音ユースケース
• ユーザがクリックしたら録音開始
• 終了で録音終了
• 複数のユーザが順番に喋るので結合する。
– 同時にはしゃべらない
• 録音ファイルはS3に保存し、後ほど聞
くことができるようにする。
Socket.io-
stream
(1)AudioAPI
(2)Binary変換
(3)wav.file writerで保存
(4)Sample Rate統一
(5)複数ユーザの音声ファイル結合
(6) mp3化
(7)S3アップロード
(8)Firebaseへ登録
音声データ
音声データ波形 音声データ波形の簡略化図
16 bit stereo sample data 44khz
マイクから取得した32bit stereoデータを16bitモノラルデータにして
サーバに送信して格納保存したい。
ステレオ
左右別々の音
モノラル
一つの音
Browserでの処理
const promise = navigator.mediaDevices.getUserMedia
({ audio:true,video: false});
promise.then( (audio_stream)=>{
Streamの取得
音声binaryデータの取得
const audio_context = new AudioContext();
this.sample_rate_value = audio_context.sampleRate;
const audioInput = audio_context.createMediaStreamSource(audio_stream);
const bufferSize = 4096;
const scriptNode = audio_context.createScriptProcessor(bufferSize, 1, 1);
audioInput.connect(scriptNode);
scriptNode.connect(audio_context.destination);
scriptNode.onaudioprocess = (audioProcessingEvent)=>{
var left = audioProcessingEvent.inputBuffer.getChannelData(0);
var audio_array_buffer = this.convertoFloat32ToInt16(left);
Browserでの処理
convertoFloat32ToInt16 = (buffer)=>{
const len = buffer.length;
const double_len = len*2;
const unit8_buf = new Uint8Array(double_len);
const int16_variable =ç new Int16Array(1);
for (let i=0; i< len; i++) {
int16_variable[0] = buffer[i]*0x7FFF; //convert to 16 bit PCM
unit8_buf[2*i] = int16_variable[0] & 0x00FF; //convert to uint8 for
stream buffer
unit8_buf[2*i+1] = (int16_variable[0] & 0xFF00) >> 8;
}
return unit8_buf.buffer;
}
Float32ArrayのAudioデータを 16bit PCMデータに変換し、Uint8Array型で返す
Socket.streamでサーバへ送信
var audio_array_buffer = this.convertoFloat32ToInt16(left);
this.socket_stream.stream_record_process(audio_array_buffer);
Browserでの処理
convertoFloat32ToInt16 = (buffer)=>{
const len = buffer.length;
const double_len = len*2;
const unit8_buf = new Uint8Array(double_len);
const int16_variable = new Int16Array(1);
for (let i=0; i< len; i++) {
int16_variable[0] = buffer[i]*0x7FFF; //convert to 16 bit PCM
unit8_buf[2*i] = int16_variable[0] & 0x00FF; //convert to uint8 for
stream buffer
unit8_buf[2*i+1] = (int16_variable[0] & 0xFF00) >> 8;
}
return unit8_buf.buffer;
}
Float32ArrayのAudioデータを 16bit PCMデータに変換し、Uint8Array型で返す
Socket.streamでサーバへ送信
var audio_array_buffer = this.convertoFloat32ToInt16(left);
this.socket_stream.stream_record_process(audio_array_buffer);
Binary変換の詳細
ScriptNodeからは、
Float32Arrayで
音声データを受け取る。
-0.999… 〰 0.9999…
の浮動小数点データ
uint8Arrayに変換し、
サーバになげる。
int16_variable[0]
= buffer[i]*0x7FFF;
-32766〰
32766の16byte
PCM16データ
に変換
http://webdemo.dac.co.jp/mixidea/prestudy/convertoFloat32ToInt16.html
http://webdemo.dac.co.jp/mixidea/prestudy/typed_array_invest.html
Socket stream送信
this.socket_io = io.connect(this.socket_url)
this.stream = ss.createStream();
ss(this.socket_io).emit('audio_record_start', this.stream, start_emit_obj );z
Connectionおよび、strem送信の開始
送信終了
this.stream.end();
this.socket_io.emit('audio_record_end', stop_emit_obj);
stream_record_process(audio_array_buffer){
const stream_buffer = new ss.Buffer(audio_array_buffer);
this.stream.write(stream_buffer, 'buffer');
}
Binaryデータの送信
送信一時中断
this.stream.end();
this.socket_io.emit('audio_record_suspend',);
サーバでの処理
mixidea_io.on('connection',(socket)=>{
ss(socket).on('audio_record_start', (stream, data)=>{
eval("GlobalInfo.file_writer_count_" + outfile_name + "=1");
var file_writer = new wav.FileWriter(
outfile_name_wav,
{channels:1,
sampleRate:sample_rate,
bitDepth:16
}
);
stream.pipe(file_writer);
GlobalInfo = {}
ユーザ間での情報交換のためのGlobal変数定義
Audioデータの取得とfileへの書き込み
Streamをfile writerにつなげる。
Global 変数に、
File保存時の情報を格納
サーバでの処理
Streamの一時停止
socket.on('audio_record_suspend', function(data){
Streamの終了
socket.on('audio_record_end', function(data){
setTimeout(function(){
next_func();
}, record_duration);
SamplilngRateの変更
var command =
SoxCommand().output(wstream).outputFileType('wav').outputSampleRate(44100);
command.input(existing_file_name);
command.on('end', function() {
何もせず
Audio_recordが終わったという通知が
きても、
File_writerの処理はしばらく続くので、
一定時間待ってから次の処理へいく
各ユーザの録音環境により、
Sample rateが異なるため、結合する前
に
Sample rateをそろえる。
サーバでの処理
複数のAudioファイルの合成
eval(" file_list_len = GlobalInfo.file_writer_count_" + outfile_name );
for(var i=0; i< file_list_len; i++){
var each_file_name = './' + file_name + "_"+ String(i+1) + ".wav";
command.input(each_file_name);
}
command.on('end')
mp3への変換
const wstream = fs.createWriteStream(dest_file);
const command = SoxCommand().output(wstream).outputFileType('mp3');
command.on('end', function() {
各ユーザの録音環境により、
Sample rateが異なるため、結合す
る前に
Sample rateをそろえる。
Global 変数から、保存されている
ファイルの情報取得
サーバでの処理
S3へのアップロード
fs.readFile(dest_file, function (err, data) {
s3.putObject(
{Key: file_name_on_s3, ContentType: "audio/mp3", Body: data, ACL: "public-read"},
function(error, data){
firebaseへの登録
const database = firebase_admin.database();
database.ref(child_path).set(file_path, (error)=>{
知りたいこと
• 各ユーザ間のデータ共有に、global変数を用いているが、この
方法は適切だろうか?
• Filewriter にStreamとしてデータがpipeでつなげるが、一時停
止や、処理を終了せずに放置された場合、サーバ側ではメモ
リリークなどがおきているのか?
• 同時に何人くらいの録音が可能だろうか?

Más contenido relacionado

Destacado

JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜Yukiko Tamiya
 
Angular2 change Detectionの動作チェック
Angular2 change Detectionの動作チェックAngular2 change Detectionの動作チェック
Angular2 change Detectionの動作チェックYuuta Moriyama
 
Angularfire でのSNS構築
Angularfire でのSNS構築Angularfire でのSNS構築
Angularfire でのSNS構築Yuuta Moriyama
 
Tetris 3D Modeler / テトリス3Dモデラ
Tetris 3D Modeler / テトリス3DモデラTetris 3D Modeler / テトリス3Dモデラ
Tetris 3D Modeler / テトリス3DモデラKazutaka Kurihara
 
ベルトガジェットにチャレンジしてみる
ベルトガジェットにチャレンジしてみるベルトガジェットにチャレンジしてみる
ベルトガジェットにチャレンジしてみるShigeo Ueda
 
あのアプリの動きをUIKitのみでDIYしてみる(part2)
あのアプリの動きをUIKitのみでDIYしてみる(part2)あのアプリの動きをUIKitのみでDIYしてみる(part2)
あのアプリの動きをUIKitのみでDIYしてみる(part2)Fumiya Sakai
 
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜Yukiko Tamiya
 
脆弱性スキャナVulsを使ってDevSecOpsを実践!
脆弱性スキャナVulsを使ってDevSecOpsを実践!脆弱性スキャナVulsを使ってDevSecOpsを実践!
脆弱性スキャナVulsを使ってDevSecOpsを実践!Takayuki Ushida
 
Dell technologies と cto室 technology evangelist のご紹介 for-devrel
Dell technologies と cto室 technology evangelist のご紹介 for-devrelDell technologies と cto室 technology evangelist のご紹介 for-devrel
Dell technologies と cto室 technology evangelist のご紹介 for-devrelShotaro Suzuki
 
全脳アーキテクチャ若手の会 強化学習
全脳アーキテクチャ若手の会 強化学習全脳アーキテクチャ若手の会 強化学習
全脳アーキテクチャ若手の会 強化学習kwp_george
 
nfcpy 0.10.0 でハマった話
nfcpy 0.10.0 でハマった話nfcpy 0.10.0 でハマった話
nfcpy 0.10.0 でハマった話Masaki Yamamoto
 
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2Yoshito Tabuchi
 
強化学習入門
強化学習入門強化学習入門
強化学習入門Shunta Saito
 
今からでも遅くない! React事始め
今からでも遅くない! React事始め今からでも遅くない! React事始め
今からでも遅くない! React事始めynaruta
 

Destacado (15)

JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
 
Dexiejs
DexiejsDexiejs
Dexiejs
 
Angular2 change Detectionの動作チェック
Angular2 change Detectionの動作チェックAngular2 change Detectionの動作チェック
Angular2 change Detectionの動作チェック
 
Angularfire でのSNS構築
Angularfire でのSNS構築Angularfire でのSNS構築
Angularfire でのSNS構築
 
Tetris 3D Modeler / テトリス3Dモデラ
Tetris 3D Modeler / テトリス3DモデラTetris 3D Modeler / テトリス3Dモデラ
Tetris 3D Modeler / テトリス3Dモデラ
 
ベルトガジェットにチャレンジしてみる
ベルトガジェットにチャレンジしてみるベルトガジェットにチャレンジしてみる
ベルトガジェットにチャレンジしてみる
 
あのアプリの動きをUIKitのみでDIYしてみる(part2)
あのアプリの動きをUIKitのみでDIYしてみる(part2)あのアプリの動きをUIKitのみでDIYしてみる(part2)
あのアプリの動きをUIKitのみでDIYしてみる(part2)
 
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
 
脆弱性スキャナVulsを使ってDevSecOpsを実践!
脆弱性スキャナVulsを使ってDevSecOpsを実践!脆弱性スキャナVulsを使ってDevSecOpsを実践!
脆弱性スキャナVulsを使ってDevSecOpsを実践!
 
Dell technologies と cto室 technology evangelist のご紹介 for-devrel
Dell technologies と cto室 technology evangelist のご紹介 for-devrelDell technologies と cto室 technology evangelist のご紹介 for-devrel
Dell technologies と cto室 technology evangelist のご紹介 for-devrel
 
全脳アーキテクチャ若手の会 強化学習
全脳アーキテクチャ若手の会 強化学習全脳アーキテクチャ若手の会 強化学習
全脳アーキテクチャ若手の会 強化学習
 
nfcpy 0.10.0 でハマった話
nfcpy 0.10.0 でハマった話nfcpy 0.10.0 でハマった話
nfcpy 0.10.0 でハマった話
 
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
 
強化学習入門
強化学習入門強化学習入門
強化学習入門
 
今からでも遅くない! React事始め
今からでも遅くない! React事始め今からでも遅くない! React事始め
今からでも遅くない! React事始め
 

Similar a we are javascript LTの資料

Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れようMicrosoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れようHirofumi Ota
 
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料Kentaro Matsumae
 
日本Androidの会発表スライド androidのメディア機能の話
日本Androidの会発表スライド androidのメディア機能の話日本Androidの会発表スライド androidのメディア機能の話
日本Androidの会発表スライド androidのメディア機能の話Tatsuya Matsumoto
 
Voicyを支える技術
Voicyを支える技術Voicyを支える技術
Voicyを支える技術Yuji Kubota
 
ライブストリーミングの基礎知識その2
ライブストリーミングの基礎知識その2ライブストリーミングの基礎知識その2
ライブストリーミングの基礎知識その2kumaryu
 
学会・研究会の情報保障におけるソーシャルネットワークの役割
学会・研究会の情報保障におけるソーシャルネットワークの役割学会・研究会の情報保障におけるソーシャルネットワークの役割
学会・研究会の情報保障におけるソーシャルネットワークの役割Takuya Nishimoto
 
ライブストリーミングの基礎知識
ライブストリーミングの基礎知識ライブストリーミングの基礎知識
ライブストリーミングの基礎知識kumaryu
 
Web Audio APIの初歩
Web Audio APIの初歩Web Audio APIの初歩
Web Audio APIの初歩Shota Kubota
 
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]Trainocate Japan, Ltd.
 
Firefox で快適 WordPress 生活
Firefox で快適 WordPress 生活Firefox で快適 WordPress 生活
Firefox で快適 WordPress 生活dynamis
 
Firefox と Mozilla のテクノロジー
Firefox と Mozilla のテクノロジーFirefox と Mozilla のテクノロジー
Firefox と Mozilla のテクノロジーdynamis
 
Movie Format in a Nutshell 2013
Movie Format in a Nutshell 2013Movie Format in a Nutshell 2013
Movie Format in a Nutshell 2013Ryo Amano
 

Similar a we are javascript LTの資料 (14)

Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れようMicrosoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
 
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
 
日本Androidの会発表スライド androidのメディア機能の話
日本Androidの会発表スライド androidのメディア機能の話日本Androidの会発表スライド androidのメディア機能の話
日本Androidの会発表スライド androidのメディア機能の話
 
Voicyを支える技術
Voicyを支える技術Voicyを支える技術
Voicyを支える技術
 
ライブストリーミングの基礎知識その2
ライブストリーミングの基礎知識その2ライブストリーミングの基礎知識その2
ライブストリーミングの基礎知識その2
 
学会・研究会の情報保障におけるソーシャルネットワークの役割
学会・研究会の情報保障におけるソーシャルネットワークの役割学会・研究会の情報保障におけるソーシャルネットワークの役割
学会・研究会の情報保障におけるソーシャルネットワークの役割
 
ライブストリーミングの基礎知識
ライブストリーミングの基礎知識ライブストリーミングの基礎知識
ライブストリーミングの基礎知識
 
Web Audio APIの初歩
Web Audio APIの初歩Web Audio APIの初歩
Web Audio APIの初歩
 
大規模発話ログデータを活用した音声対話処理
大規模発話ログデータを活用した音声対話処理大規模発話ログデータを活用した音声対話処理
大規模発話ログデータを活用した音声対話処理
 
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]
 
Firefox で快適 WordPress 生活
Firefox で快適 WordPress 生活Firefox で快適 WordPress 生活
Firefox で快適 WordPress 生活
 
CBA様_全通話録音の新基準VoIP Trek
CBA様_全通話録音の新基準VoIP TrekCBA様_全通話録音の新基準VoIP Trek
CBA様_全通話録音の新基準VoIP Trek
 
Firefox と Mozilla のテクノロジー
Firefox と Mozilla のテクノロジーFirefox と Mozilla のテクノロジー
Firefox と Mozilla のテクノロジー
 
Movie Format in a Nutshell 2013
Movie Format in a Nutshell 2013Movie Format in a Nutshell 2013
Movie Format in a Nutshell 2013
 

we are javascript LTの資料