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

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

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

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

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

WebRTC

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

受付中

iOS for SafariのブラウザアプリでRecordRTCのgetUserMediaが認識しない

poipoi
poipoi

総合スコア0

Node.js

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

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

WebRTC

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

0回答

0評価

0クリップ

416閲覧

投稿2022/01/24 08:41

前提・実現したいこと

iOS15.2 for Safariで開発中のブラウザアプリにおいてwebRTCを活用したマイク入力&録音を行い、その後webSocket経由でサーバへ送ったのち、自然言語処理の外部APIにデータを渡そうとしています。
(サーバ&クライアントはNodeJSにて開発 / 初心者ベースとお考えください)

下記RecordRTCのaudio-recording.htmlを参考にすべく、まずiPhone8側SafariにてTestLiveにおけるdemoを開き、ボタン押下できちんと録音&プレビューまで正常稼働できているのを確認しています。
https://github.com/muaz-khan/RecordRTC/blob/master/simple-demos/README.md

※現在、手元にiPhone8 しかないため、Android等の他端末では挙動確認できていません

audio-recording.htmlのエラー

まずサーバからwebsocketにてコマンドを受け取ったタイミングで、上記リンクのsourceをスマホ側のJSコード上にhtml表示させて音声入力ボタン(Start Recording)を押下すると、mediaDevices.getUserMediaが認識エラーとなるようです。
demoではボタン押下後にマイク許可の表示と、Safariの場合、さらに念押しの確認画面が出るはずなのですが、こちらのブラウザソースではマイク認識の時点でエラーとなってしまいます。
('This browser does not supports WebRTC getUserMedia API.')

なぜ同じソースコードでもdemoでできていて、JSで側のhtml表示ではエラーとなるか、初歩的な部分かもしれませんがよろしくご教示ください。

そもそもの音声入力はweb Speech APIにて行っていましたが、iOS14→15アップデート後に1秒尺くらいしか認識しなくなってしまい、急遽webRTCのボタン押下によって長尺の音声データを取得する方法へと変更しようといます。

html

//htmlソースを変数HTML_webRTC02に設定したものを、サーバからのトリガー受信後に表示させようとしている const HTML_webRTC02 = '<html> <style> html, body { margin: 0 !important; padding: 0 !important; } </style> <title>Audio Recording | RecordRTC</title> <h1>Simple Audio Recording using RecordRTC</h1> <meta charset="utf-8" /> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"> <br> <button id="btn-start-recording">Start Recording</button> <button id="btn-stop-recording" disabled>Stop Recording</button> <button id="btn-release-microphone" disabled>Release Microphone</button> <button id="btn-download-recording" disabled>Download</button> <hr> <div><audio controls autoplay playsinline="true"></audio></div> <script src="https://www.WebRTC-Experiment.com/RecordRTC.js"></script> <script> var audio = document.querySelector('audio'); function captureMicrophone(callback) { btnReleaseMicrophone.disabled = false; if (microphone) { callback(microphone); return; } //!!最初の時点でデバイス認識エラーがでています // 'This browser does not supports WebRTC getUserMedia API. if (typeof navigator.mediaDevices === 'undefined' || !navigator.mediaDevices.getUserMedia) { alert('This browser does not supports WebRTC getUserMedia API.'); if (!!navigator.getUserMedia) { alert('This browser seems supporting deprecated getUserMedia API.'); } } navigator.mediaDevices.getUserMedia({ audio: isEdge ? true : { echoCancellation: false } }).then(function (mic) { callback(mic); }).catch(function (error) { alert('Unable to capture your microphone. Please check console logs.'); console.error(error); }); } function replaceAudio(src) { var newAudio = document.createElement('audio'); newAudio.controls = true; newAudio.autoplay = true; if (src) { newAudio.src = src; } var parentNode = audio.parentNode; parentNode.innerHTML = ''; parentNode.appendChild(newAudio); audio = newAudio; } function stopRecordingCallback() { //replaceAudio(URL.createObjectURL(recorder.getBlob())); if (!recorder || !recorder.getBlob()) return; recorder.getDataURL(function (audioDataURL) { //8) var files = { audio: { type: recorder.getBlob().type || 'audio/wav', dataURL: audioDataURL } }; // submit the audio file to the server //socketio.emit('message', files); //(2022.01.11)socketioは使わず、websocketをそのまま利用 sock.send(JSON.stringify({ msg: scene14, audio: { type: recorder.getBlob().type || 'audio/wav', dataURL: audioDataURL } })); }); btnStartRecording.disabled = false; /* setTimeout(function () { if (!audio.paused) return; setTimeout(function () { if (!audio.paused) return; audio.play(); }, 1000); audio.play(); }, 300); audio.play(); */ btnDownloadRecording.disabled = false; if (isSafari) { click(btnReleaseMicrophone); } } var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob); var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); var recorder; // globally accessible var microphone; var btnStartRecording = document.getElementById('btn-start-recording'); var btnStopRecording = document.getElementById('btn-stop-recording'); var btnReleaseMicrophone = document.querySelector('#btn-release-microphone'); var btnDownloadRecording = document.getElementById('btn-download-recording'); btnStartRecording.onclick = function () { this.disabled = true; this.style.border = ''; this.style.fontSize = ''; if (!microphone) { captureMicrophone(function (mic) { microphone = mic; if (isSafari) { replaceAudio(); audio.muted = true; audio.srcObject = microphone; btnStartRecording.disabled = false; btnStartRecording.style.border = '1px solid red'; btnStartRecording.style.fontSize = '150%'; alert('Please click startRecording button again. First time we tried to access your microphone. Now we will record it.'); return; } click(btnStartRecording); }); return; } replaceAudio(); audio.muted = true; audio.srcObject = microphone; var options = { type: 'audio', numberOfAudioChannels: isEdge ? 1 : 2, checkForInactiveTracks: true, bufferSize: 16384 }; if (isSafari || isEdge) { options.recorderType = StereoAudioRecorder; } if (navigator.platform && navigator.platform.toString().toLowerCase().indexOf('win') === -1) { options.sampleRate = 48000; // or 44100 or remove this line for default } if (isSafari) { options.sampleRate = 44100; options.bufferSize = 4096; options.numberOfAudioChannels = 2; } if (recorder) { recorder.destroy(); recorder = null; } recorder = RecordRTC(microphone, options); recorder.startRecording(); btnStopRecording.disabled = false; btnDownloadRecording.disabled = true; }; btnStopRecording.onclick = function () { this.disabled = true; recorder.stopRecording(stopRecordingCallback); }; btnReleaseMicrophone.onclick = function () { this.disabled = true; btnStartRecording.disabled = false; if (microphone) { microphone.stop(); microphone = null; } if (recorder) { // click(btnStopRecording); } }; btnDownloadRecording.onclick = function () { this.disabled = true; if (!recorder || !recorder.getBlob()) return; if (isSafari) { recorder.getDataURL(function (dataURL) { SaveToDisk(dataURL, getFileName('mp3')); }); return; } var blob = recorder.getBlob(); var file = new File([blob], getFileName('mp3'), { type: 'audio/mp3' }); invokeSaveAsDialog(file); }; </script> <footer style="margin-top: 20px;"><small id="send-message"></small></footer> <script src="https://www.webrtc-experiment.com/common.js"></script> </html>'

以下はブラウザ側で表示させるエリア

html

$('#phoneMain').html(HTML_webRTC02)

スマホブラウザ側のpug

html

doctype html html(lang="jp") head meta(charset="utf-8") meta(name="viewport" content="width=300") link(rel='stylesheet', href='/css/style.css') link(rel='stylesheet', href='/css/phone.css') script(src="https://code.jquery.com/jquery-3.4.1.min.js", integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=", crossorigin="anonymous") script(src="https://rawgit.com/kimmobrunfeldt/progressbar.js/master/dist/progressbar.min.js") script(src="/js/howler.min.js") script(src="/js/config.js") script(src="/js/phone.js") //webRTCのhtmlとJSをphoneJSのhtmlに追加 script(src="https://www.WebRTC-Experiment.com/RecordRTC.js") body // div.phoneSpacer &nbsp; div#phoneMain div.phoneSpacer &nbsp; h2.phoneTitle #{msg} // div.phoneSpacer &nbsp; .phoneBtns button.joinBtn#joinBtn 参加 div.phoneSpacer &nbsp; div.phoneSpacer &nbsp; div.ringTone audio#ringTone(src="/mp4/office_phone.mp3", preload="auto") div#status

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

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

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Node.js

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

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

WebRTC

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