質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

WebRTC

WebRTC(Web Real-Time Communication)とは、プラグイン無しでウェブブラウザ間の音声通話・ビデオチャットなどリアルタイムコミュニケーションができるオープンフレームワークです。W3CがAPIレベルで、IETFがプロトコルレベルでそれぞれ標準化が進められています。

Q&A

0回答

1294閲覧

webRTCを使用した録音データをNodeサーバで処理時録音時間がおかしくなる

wolf2

総合スコア19

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

WebRTC

WebRTC(Web Real-Time Communication)とは、プラグイン無しでウェブブラウザ間の音声通話・ビデオチャットなどリアルタイムコミュニケーションができるオープンフレームワークです。W3CがAPIレベルで、IETFがプロトコルレベルでそれぞれ標準化が進められています。

0グッド

1クリップ

投稿2020/02/19 07:34

編集2020/02/19 08:27

お世話になります。

現在webRTCとNodeを利用した開発を行っておりまして、
ブラウザから録音(setTimeoutで4秒だけ録音)したデータをNodeにsocketでemitしNodeで受け取り、
受け取ったデータをとあるAPIに投げてそのレスポンスをブラウザにsocketのemitで返す。。。
という想定の処理を作っており、録音からAPIレスポンスまでの実装は出来動いてはいるのですが、
なぜか録音データが4秒だけの録音のはずなのに15秒の音声データとなってしまいます。。。
setTimeoutが原因かと思い手動で録音を停止する処理をかましても変わらず録音時間が膨れる状況です。。。
ソースは以下の通りですが何が原因でしょうか。。。※一部情報は伏せております。
webRTCは初めて利用しますので困っています。
ご教示頂けますと大変助かります。
宜しくお願い致します。

ejs

1<!-- クライアント側 --> 2<!DOCTYPE html> 3<html lang="ja"> 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <script type="text/javascript" src="/socket.io/socket.io.js"></script> 8 <link rel="stylesheet" href="css/index.css"> 9 <title>webRTC録音テスト</title> 10</head> 11<body> 12 <div id="containt"> 13 <ul> 14 <li><img id="greeting" src='<%= img %>'></li> 15 <li><input type="image" id="start" src="img/mic.png" /></li> 16 </ul> 17 </div> 18 <div id="result"> 19 </div> 20 <script> 21  var socket = io.connect(); 22 socket.on('respons', function(body) { 23 console.log(body); 24 }); 25 26 // for DOM 27 const downloadLink = document.getElementById('download'); 28 const startButton = document.getElementById('start'); 29 30 let buffer = 2048; 31 let context; 32 let processor; 33 let input; 34 let globalStream; 35 var audioData = []; 36 const property = { 37 audio: true, 38 video: false 39 }; 40 41 function record() { 42 context = new AudioContext(); 43 processor = context.createScriptProcessor(buffer, 1, 1); 44 processor.connect(context.destination); 45 context.resume(); 46 47 var recording = function(stream) { 48 globalStream = stream; 49 input = context.createMediaStreamSource(stream); 50 input.connect(processor); 51 processor.onaudioprocess = function(audio) { 52 audioStream(audio); 53 }; 54 setTimeout(function() { stop() }, 4000); 55 }; 56 navigator.mediaDevices.getUserMedia(property).then(recording); 57 } 58 59 function audioStream(audio) { 60 var input = audio.inputBuffer.getChannelData(0); 61 var bufferData = new Float32Array(buffer); 62 63 for (var i = 0; i < buffer; i++) { 64 bufferData[i] = input[i]; 65 } 66 audioData.push(bufferData); 67 } 68 69 function stop() { 70 startButton.disabled = false; 71 socket.emit('stop', audioData); 72 let track = globalStream.getTracks()[0]; 73 track.stop(); 74 audioData = []; 75 input.disconnect(processor); 76 processor.disconnect(context.destination); 77 context.close().then(function() { 78 input = null; 79 processor = null; 80 context = null; 81 startButton.disabled = false; 82 }); 83 alert('録音終了'); 84 } 85 86 // スタートボタン処理 87 startButton.addEventListener('click', function () { 88 record(); 89 }); 90 91 </script> 92</body> 93</html>

js

1// サーバ側 2var fs = require('fs'); 3var WavEncoder = require('wav-encoder'); 4var webclient = require("request"); 5var express = require("express"); 6var app = express(); 7 8// ejs 各種設定 9app.set("view engine", "ejs"); 10app.use(express.static('views')); 11 12app.get("/", function (req, res) { 13 const img = GreetingTime(); 14 15 // レンダリングを行う 16 res.render("./index.ejs", {img: img}); 17}); 18 19var io = require('socket.io').listen(app.listen(3000, () => console.log('app listening on port 3000!'))); 20// 録音終了を検知して処理を開始 21io.on('connection', function(socket) { 22 socket.on('stop', function(data) { 23 console.log('Socket Catch'); 24 25 var mergeBuffers = function(data) { 26 var sampleLength = 0; 27 for(var i = 0; i < data.length; i++) { 28 sampleLength += Objlen(data[i]); 29 } 30 31 var samples = new Float32Array(sampleLength); 32 var sampleIndex = 0; 33 34 for(var i = 0; i < data.length; i++) { 35 for(var j = 0; j < Objlen(data[i]); j++) { 36 samples[sampleIndex] = data[i][j] 37 sampleIndex++; 38 } 39 } 40 return samples; 41 }; 42 43 // サンプルレート調整 44 var audioData = { 45 sampleRate: 11025, 46 channelData: [mergeBuffers(data)] 47 }; 48 49 // WAVエンコード~APIにデータを投げる 50 WavEncoder.encode(audioData).then((buffer) => { 51 52 fs.writeFile('demo.wav', Buffer.from(buffer), function(e) { 53 if (e) { 54 console.log(e) 55 } else { 56 console.log("Success") 57 } 58 }); 59 60 let url = '※※※'; 61 let formData = { 62 'apikey' : '※※※', 63 'wav': Buffer.from(buffer), 64 'timeout': '100000' //milliseconds 65 }; 66 67 // API へ投げる 68 webclient.post({url:url, formData:formData}, function (error, response, body){ 69 socket.emit('respons',body); 70 console.log(body); 71 }); 72 }); 73 }); 74}); 75 76// jsonの要素数 77function Objlen(data) { 78 return Object.keys(data).length; 79} 80 81// 時間帯別に画像urlを返す 82function GreetingTime() { 83 require('date-utils'); 84 85 let dt = new Date(); 86 let time = dt.toFormat('HH24'); 87 if (time > 0 && time < 12 ) { 88 greeting = 'img/ohayou.png'; 89 } else if (time > 12 && time < 18) { 90 greeting = 'img/konnitiha.png'; 91 } else if(time > 18 || (time > 0 && time < 7)) { 92 greeting = 'img/konbanha.png'; 93 } 94 95 return greeting; 96} 97

◆追記
要件として、音声仕様は 16bit wavファイル 11025hz である事が必須です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問