Enviar búsqueda
Cargar
we are javascript LTの資料
•
1 recomendación
•
899 vistas
Yuuta Moriyama
Seguir
ブラウザからサーバにstreamして録音する
Leer menos
Leer más
Software
Denunciar
Compartir
Denunciar
Compartir
1 de 18
Descargar ahora
Descargar para leer sin conexión
Recomendados
TV連動サービスのリアルタイム通知を支える技術
TV連動サービスのリアルタイム通知を支える技術
Tsuyoshi Torii
【InfraCommunityCafe小話】Zoomの使用感
【InfraCommunityCafe小話】Zoomの使用感
uniyama
2018年12月15日 AITCシニア成果発表会 無用な争い回避システム
2018年12月15日 AITCシニア成果発表会 無用な争い回避システム
aitc_jp
HLSについて知っていることを話します
HLSについて知っていることを話します
Moriyoshi Koizumi
ITRON仕様のOSで組み込みにトライしてみた
ITRON仕様のOSで組み込みにトライしてみた
boropon
よくわかる?KotonoSyncの使い方!
よくわかる?KotonoSyncの使い方!
u Suzumof
わんくま同盟 名古屋勉強会 #43 ライトニングトーク「Firefoxがver.57~(Quantum)にアップグレードされて困ったこと・やったこと」
わんくま同盟 名古屋勉強会 #43 ライトニングトーク「Firefoxがver.57~(Quantum)にアップグレードされて困ったこと・やったこと」
Hiro H.
「音声再生遅延推測機能」正式リリース! ズレない!待たせない!快適なスマホゲームを実現する技術紹介
「音声再生遅延推測機能」正式リリース! ズレない!待たせない!快適なスマホゲームを実現する技術紹介
CRI Middleware
Recomendados
TV連動サービスのリアルタイム通知を支える技術
TV連動サービスのリアルタイム通知を支える技術
Tsuyoshi Torii
【InfraCommunityCafe小話】Zoomの使用感
【InfraCommunityCafe小話】Zoomの使用感
uniyama
2018年12月15日 AITCシニア成果発表会 無用な争い回避システム
2018年12月15日 AITCシニア成果発表会 無用な争い回避システム
aitc_jp
HLSについて知っていることを話します
HLSについて知っていることを話します
Moriyoshi Koizumi
ITRON仕様のOSで組み込みにトライしてみた
ITRON仕様のOSで組み込みにトライしてみた
boropon
よくわかる?KotonoSyncの使い方!
よくわかる?KotonoSyncの使い方!
u Suzumof
わんくま同盟 名古屋勉強会 #43 ライトニングトーク「Firefoxがver.57~(Quantum)にアップグレードされて困ったこと・やったこと」
わんくま同盟 名古屋勉強会 #43 ライトニングトーク「Firefoxがver.57~(Quantum)にアップグレードされて困ったこと・やったこと」
Hiro H.
「音声再生遅延推測機能」正式リリース! ズレない!待たせない!快適なスマホゲームを実現する技術紹介
「音声再生遅延推測機能」正式リリース! ズレない!待たせない!快適なスマホゲームを実現する技術紹介
CRI Middleware
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
Yukiko Tamiya
Dexiejs
Dexiejs
Ryota Suzuki
Angular2 change Detectionの動作チェック
Angular2 change Detectionの動作チェック
Yuuta Moriyama
Angularfire でのSNS構築
Angularfire でのSNS構築
Yuuta Moriyama
Tetris 3D Modeler / テトリス3Dモデラ
Tetris 3D Modeler / テトリス3Dモデラ
Kazutaka Kurihara
ベルトガジェットにチャレンジしてみる
ベルトガジェットにチャレンジしてみる
Shigeo Ueda
あのアプリの動きをUIKitのみでDIYしてみる(part2)
あのアプリの動きをUIKitのみでDIYしてみる(part2)
Fumiya Sakai
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
Yukiko Tamiya
脆弱性スキャナVulsを使ってDevSecOpsを実践!
脆弱性スキャナVulsを使ってDevSecOpsを実践!
Takayuki Ushida
Dell technologies と cto室 technology evangelist のご紹介 for-devrel
Dell technologies と cto室 technology evangelist のご紹介 for-devrel
Shotaro Suzuki
全脳アーキテクチャ若手の会 強化学習
全脳アーキテクチャ若手の会 強化学習
kwp_george
nfcpy 0.10.0 でハマった話
nfcpy 0.10.0 でハマった話
Masaki Yamamoto
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Yoshito Tabuchi
強化学習入門
強化学習入門
Shunta Saito
今からでも遅くない! React事始め
今からでも遅くない! React事始め
ynaruta
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
Hirofumi Ota
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
Kentaro Matsumae
日本Androidの会発表スライド androidのメディア機能の話
日本Androidの会発表スライド androidのメディア機能の話
Tatsuya Matsumoto
Voicyを支える技術
Voicyを支える技術
Yuji Kubota
ライブストリーミングの基礎知識その2
ライブストリーミングの基礎知識その2
kumaryu
学会・研究会の情報保障におけるソーシャルネットワークの役割
学会・研究会の情報保障におけるソーシャルネットワークの役割
Takuya Nishimoto
ライブストリーミングの基礎知識
ライブストリーミングの基礎知識
kumaryu
Más contenido relacionado
Destacado
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
Yukiko Tamiya
Dexiejs
Dexiejs
Ryota Suzuki
Angular2 change Detectionの動作チェック
Angular2 change Detectionの動作チェック
Yuuta Moriyama
Angularfire でのSNS構築
Angularfire でのSNS構築
Yuuta Moriyama
Tetris 3D Modeler / テトリス3Dモデラ
Tetris 3D Modeler / テトリス3Dモデラ
Kazutaka Kurihara
ベルトガジェットにチャレンジしてみる
ベルトガジェットにチャレンジしてみる
Shigeo Ueda
あのアプリの動きをUIKitのみでDIYしてみる(part2)
あのアプリの動きをUIKitのみでDIYしてみる(part2)
Fumiya Sakai
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
Yukiko Tamiya
脆弱性スキャナVulsを使ってDevSecOpsを実践!
脆弱性スキャナVulsを使ってDevSecOpsを実践!
Takayuki Ushida
Dell technologies と cto室 technology evangelist のご紹介 for-devrel
Dell technologies と cto室 technology evangelist のご紹介 for-devrel
Shotaro Suzuki
全脳アーキテクチャ若手の会 強化学習
全脳アーキテクチャ若手の会 強化学習
kwp_george
nfcpy 0.10.0 でハマった話
nfcpy 0.10.0 でハマった話
Masaki Yamamoto
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Yoshito Tabuchi
強化学習入門
強化学習入門
Shunta Saito
今からでも遅くない! React事始め
今からでも遅くない! React事始め
ynaruta
Destacado
(15)
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter02. 〜 デバッグ編 〜
Dexiejs
Dexiejs
Angular2 change Detectionの動作チェック
Angular2 change Detectionの動作チェック
Angularfire でのSNS構築
Angularfire でのSNS構築
Tetris 3D Modeler / テトリス3Dモデラ
Tetris 3D Modeler / テトリス3Dモデラ
ベルトガジェットにチャレンジしてみる
ベルトガジェットにチャレンジしてみる
あのアプリの動きをUIKitのみでDIYしてみる(part2)
あのアプリの動きをUIKitのみでDIYしてみる(part2)
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter03. 〜 prototype?編 〜
脆弱性スキャナVulsを使ってDevSecOpsを実践!
脆弱性スキャナVulsを使ってDevSecOpsを実践!
Dell technologies と cto室 technology evangelist のご紹介 for-devrel
Dell technologies と cto室 technology evangelist のご紹介 for-devrel
全脳アーキテクチャ若手の会 強化学習
全脳アーキテクチャ若手の会 強化学習
nfcpy 0.10.0 でハマった話
nfcpy 0.10.0 でハマった話
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
強化学習入門
強化学習入門
今からでも遅くない! React事始め
今からでも遅くない! React事始め
Similar a we are javascript LTの資料
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
Hirofumi Ota
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
Kentaro Matsumae
日本Androidの会発表スライド androidのメディア機能の話
日本Androidの会発表スライド androidのメディア機能の話
Tatsuya Matsumoto
Voicyを支える技術
Voicyを支える技術
Yuji Kubota
ライブストリーミングの基礎知識その2
ライブストリーミングの基礎知識その2
kumaryu
学会・研究会の情報保障におけるソーシャルネットワークの役割
学会・研究会の情報保障におけるソーシャルネットワークの役割
Takuya Nishimoto
ライブストリーミングの基礎知識
ライブストリーミングの基礎知識
kumaryu
Web Audio APIの初歩
Web Audio APIの初歩
Shota Kubota
大規模発話ログデータを活用した音声対話処理
大規模発話ログデータを活用した音声対話処理
Yahoo!デベロッパーネットワーク
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]
Trainocate Japan, Ltd.
Firefox で快適 WordPress 生活
Firefox で快適 WordPress 生活
dynamis
CBA様_全通話録音の新基準VoIP Trek
CBA様_全通話録音の新基準VoIP Trek
FUSION COMMUNICATIONS CORPORATION
Firefox と Mozilla のテクノロジー
Firefox と Mozilla のテクノロジー
dynamis
Movie Format in a Nutshell 2013
Movie Format in a Nutshell 2013
Ryo Amano
Similar a we are javascript LTの資料
(14)
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
Microsoft Teams で行う失敗できない Web 会議やセミナー配信で使える快適な環境を極力お金をかけずに手に入れよう
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
ニコニコ動画iPhoneアプリの作り方@スマートフォン2011講演資料
日本Androidの会発表スライド androidのメディア機能の話
日本Androidの会発表スライド androidのメディア機能の話
Voicyを支える技術
Voicyを支える技術
ライブストリーミングの基礎知識その2
ライブストリーミングの基礎知識その2
学会・研究会の情報保障におけるソーシャルネットワークの役割
学会・研究会の情報保障におけるソーシャルネットワークの役割
ライブストリーミングの基礎知識
ライブストリーミングの基礎知識
Web Audio APIの初歩
Web Audio APIの初歩
大規模発話ログデータを活用した音声対話処理
大規模発話ログデータを活用した音声対話処理
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]
Microsoft Lyncをスムーズに導入するための5つのポイント [グローバルナレッジセミナー資料]
Firefox で快適 WordPress 生活
Firefox で快適 WordPress 生活
CBA様_全通話録音の新基準VoIP Trek
CBA様_全通話録音の新基準VoIP Trek
Firefox と Mozilla のテクノロジー
Firefox と Mozilla のテクノロジー
Movie Format in a Nutshell 2013
Movie Format in a Nutshell 2013
we are javascript LTの資料
1.
汎用的なオンラインビデオ会議 システムを作る 森山雄太
2.
DEMO
3.
ビデオ会議システム+メディア で必要な機能 • ビデオで通話を行う – ビデオ、音声のみ、snapshotコマ送りの切り替え •
録音 • 会話の文字起こし • チャット • ユーザ間同期 • 部屋への入室
4.
今日は録音にFOCUS
5.
もっと良いやり方があったら 教えてもらいたいから
6.
録音ユースケース • ユーザがクリックしたら録音開始 • 終了で録音終了 •
複数のユーザが順番に喋るので結合する。 – 同時にはしゃべらない • 録音ファイルはS3に保存し、後ほど聞 くことができるようにする。
7.
Socket.io- stream (1)AudioAPI (2)Binary変換 (3)wav.file writerで保存 (4)Sample Rate統一 (5)複数ユーザの音声ファイル結合 (6)
mp3化 (7)S3アップロード (8)Firebaseへ登録
8.
音声データ 音声データ波形 音声データ波形の簡略化図 16 bit
stereo sample data 44khz マイクから取得した32bit stereoデータを16bitモノラルデータにして サーバに送信して格納保存したい。 ステレオ 左右別々の音 モノラル 一つの音
9.
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);
10.
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);
11.
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);
12.
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
13.
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',);
14.
サーバでの処理 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保存時の情報を格納
15.
サーバでの処理 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をそろえる。
16.
サーバでの処理 複数の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 変数から、保存されている ファイルの情報取得
17.
サーバでの処理 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)=>{
18.
知りたいこと • 各ユーザ間のデータ共有に、global変数を用いているが、この 方法は適切だろうか? • Filewriter
にStreamとしてデータがpipeでつなげるが、一時停 止や、処理を終了せずに放置された場合、サーバ側ではメモ リリークなどがおきているのか? • 同時に何人くらいの録音が可能だろうか?
Descargar ahora