🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

1回答

3379閲覧

Web上での波形の類似度などの表示

father

総合スコア10

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2018/11/28 05:07

編集2018/11/28 15:17

前提・実現したいこと

mp3ファイルの音声の波形と音声認識からの波形の類似度などどれだけ似ているかっていうのをHTML上で表示できるように作りたいです。探してもそういう技術がないため見て判断するしかないのかなと結論がでそうなため そういったことができるようなサイトやどういった方法でやったらよいか教えていただけると幸いです。

発生している問題・エラーメッセージ

HTML上で波形がどれだけ似ているかの判定の手段がない

該当のソースコード

HTML

1#波形を表示する 2<!DOCTYPE html> 3<html> 4<head> 5<meta charset="utf-8" /> 6</head> 7<body> 8<script src="http://cdnjs.cloudflare.com/ajax/libs/wavesurfer.js/2.0.6/wavesurfer.min.js"></script> 9 10<div id="waveform"> </div> 11 12<div style="text-align: center"> 13 <button class="btn btn-primary" onclick="wavesurfer.playPause()"> 14 <i class="glyphicon glyphicon-play"></i>Play</button> 15 16<p class="row"> 17 <div class="col-xs-1"> 18 <i class="glyphicon glyphicon-zoom-in"></i> 19 </div> 20 21 <div class="col-xs-10"> 22 <input id="slider" type="range" min="1" max="200" value="1" style="width: 100%" /> 23 </div> 24 25 <div class="col-xs-1"> 26 <i class="glyphicon glyphicon-zoom-out"></i> 27 </div> 28 </p> 29 30</div> 31 32<script language="JavaScript"> 33 34var wavesurfer = WaveSurfer.create({ 35 container: '#waveform', 36 waveColor: 'red', 37 progressColor: 'purple' 38}); 39 40wavesurfer.load('sightseeing.mp3'); 41 42var slider = document.querySelector('#slider'); 43 44slider.oninput = function () { 45 var zoomLevel = Number(slider.value); 46 wavesurfer.zoom(zoomLevel); 47}; 48 49</script> 50</body> 51</html> 52

HTML

1#音声認識から波形 2<!DOCTYPE html> 3<html lang="ja"> 4<head> 5<meta charset="UTF-8"> 6<title>Document</title> 7<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> 8<style>*{box-sizing:border-box;margin:0;padding:0;}html,body{font-family:Meiryo;height:65%;}input,button{font-family:Meiryo;}#app{display:flex;overflow-y:hidden;flex-direction:column;min-width:320px;height:100%;}#control{color:#fff;background:#424242;display:flex;align-items:center;height:50px;max-height:50px;}#content{background:#212121;height:calc(100% - 50px);}#content .col{height:calc(100% / 2);}#content .col canvas{width:100%;height:calc(100% - 40px);}#content .head{background:#455a64;display:flex;align-items:center;justify-content:space-between;height:40px;max-height:40px;padding:0 10px;}#content .head h2{font-size:18px;font-weight:normal;color:#fff;flex:1 0 0%;margin:0;}#btn-tgl-rec,#btn-tgl-mute,.btn-play,.btn-clear,.btn-download{font-size:14px;color:#333;background:#e0e0e0;display:flex;align-items:center;justify-content:center;height:30px;margin:0 0 0 10px;padding:0 10px;cursor:pointer;border:0;text-decoration:none;}.btn-download{color:#ccc;}.btn-download[href]{color:#333;}#btn-tgl-rec::before,#btn-tgl-mute::before,.btn-play::before,.btn-clear::before,.btn-download::before{font-family:"Material Icons";font-size:24px;display:inline-block;margin:0 5px 0 0;}#btn-tgl-rec::before{color:#b71c1c;content:"\E061";}#btn-tgl-rec.is-recording::before{color:#212121;content:"\E034";}#btn-tgl-mute::before{content:"\E029";}#btn-tgl-mute.is-muted::before{content:"\E02B";}.btn-play::before{content:"\E037";}.btn-play.is-played::before{content:"\E034";}.btn-clear::before{content:"\E92b";}.btn-download::before{content:"\E2C4";}</style> 9</head> 10<body> 11<div id="app"> 12<div id="control"> 13<audio id="audio"></audio> 14<button id="btn-tgl-rec"><span>REC</span></button> 15<button id="btn-tgl-mute"><span>MUTE</span></button> 16<!-- /#control --></div> 17<div id="content"> 18<div class="col"> 19<div class="head"> 20<h2>リアルタイム入力波形</h2> 21</div> 22<canvas id="input-waveform"></canvas> 23<!-- /.col --></div> 24 25<div class="col"> 26<div class="head"> 27<h2>録音した音声の波形</h2> 28<a id="btn-rec-download" class="btn-download"><span>DOWNLOAD</span></a> 29<button id="btn-rec-clear" class="btn-clear"><span>CLEAR</span></button> 30<button id="btn-rec-play" class="btn-play"><span>PLAY</span></button> 31<audio id="rec-audio"></audio> 32</div> 33<canvas id="rec-waveform"></canvas> 34<!-- /.col --></div> 35 36<div class="col"> 37<div class="head"> 38 <a id="btn-effect-download" class="btn-download"><span>DOWNLOAD</span></a> 39 <button id="btn-effect-clear" class="btn-clear"><span>CLEAR</span></button> 40 <button id="btn-effect-play" class="btn-play"><span>PLAY</span></button> 41 <audio id="effect-audio"></audio> 42 </div> 43<canvas id="effect-waveform"></canvas> 44</div> 45<!-- /.col --></div> 46<!-- /#content --></div> 47<!-- /#app --></div> 48<script src="run.js"></script> 49</body> 50</html> 51

JavaScript

1#run.js 2!function(win,doc,AudioContext,MediaRecorder){"use strict" 3 4function resizeCanvas(){$waveformInput.width="100%",$waveformInput.style.width="100%",offsetWidth=$waveformInput.offsetWidth,offsetHeight=$waveformInput.offsetHeight, 5 6function(arr){for(var i=0;i<arr.length;i++)arr[i].style.width=offsetWidth+"px",arr[i].style.height=offsetHeight+"px",arr[i].width=offsetWidth,arr[i].height=offsetHeight}([$waveformInput,$waveformRec,$waveformEffect])} 7 8 function clearCanvas(ctx){ctx.clearRect(0,0,offsetWidth,offsetHeight),ctx.beginPath()} 9 10 function createWaveform(audioBuffer,ctx,size){var bufferFl32=new Float32Array(audioBuffer.length),leng=bufferFl32.length 11 clearCanvas(ctx),bufferFl32.set(audioBuffer.getChannelData(0)) 12 13for(var idx=0;leng>idx;idx++)if(idx%size===0){var x=offsetWidth*(idx/leng),y=(1-bufferFl32[idx])/2*offsetHeight 14 0===idx?ctx.moveTo(x,y):ctx.lineTo(x,y)}var gradient=ctx.createLinearGradient(0,0,0,offsetHeight) 15 gradient.addColorStop("0","#f44336"),gradient.addColorStop("0.5","#4caf50"),gradient.addColorStop("1","#2196f3"),ctx.strokeStyle=gradient,ctx.stroke()} 16 17 function clearSection(ctx,$btnDownload,$btnPlay,$audio){clearCanvas(ctx),$btnDownload.removeAttribute("href"),$btnPlay.classList.remove("is-played"),$audio.removeAttribute("src")} 18 19 function playAudio($btnPlay,$audio){$btnPlay.classList.value.indexOf("is-played")<0?($btnPlay.classList.add("is-played"),$audio.play()):($btnPlay.classList.remove("is-played"),$audio.pause())} 20 21 function fetchArrayBufferFromURL(blob){var url=URL.createObjectURL(blob) 22 return fetch(url).then(function(response){return response.arrayBuffer()})} 23 24 function renderCanvas(data,$audio,$btnDownload,ctx){var blob=new Blob([data],{type:"audio/webm"}) 25 $audio.src=win.URL.createObjectURL(blob), 26 $btnDownload.href=$audio.src,$btnDownload.download="rec.webm",fetchArrayBufferFromURL(blob).then(function(arrayBuffer){actx.decodeAudioData(arrayBuffer).then(function(audioBuffer){createWaveform(audioBuffer,ctx,1)})})} 27 28 var offsetWidth,offsetHeight,recorder1,recorder2,recorderStream, 29 $btnRec=doc.getElementById("btn-tgl-rec"), 30 $btnMute=doc.getElementById("btn-tgl-mute"), 31 $waveformInput=doc.getElementById("input-waveform"), 32 $waveformRec=doc.getElementById("rec-waveform"), 33 $waveformEffect=doc.getElementById("effect-waveform"), 34 $btnRecDownload=doc.getElementById("btn-rec-download"), 35 $btnRecClear=doc.getElementById("btn-rec-clear"), 36 $btnRecPlay=doc.getElementById("btn-rec-play"), 37 $btnEffectDownload=doc.getElementById("btn-effect-download"), 38 $btnEffectClear=doc.getElementById("btn-effect-clear"), 39 $btnEffectPlay=doc.getElementById("btn-effect-play"), 40 41 actx=new AudioContext,ictx=$waveformInput.getContext("2d"), 42 43rctx=$waveformRec.getContext("2d"),ectx=$waveformEffect.getContext("2d"),$raudio=doc.getElementById("rec-audio"),$eaudio=doc.getElementById("effect-audio"),fft=1024,gainNode=actx.createGain(),scriptProcessor=actx.createScriptProcessor(fft,1,1),streamDestination=actx.createMediaStreamDestination(),isMute=!1,isRecording=!1 44resizeCanvas(),win.addEventListener("resize",resizeCanvas,!1),scriptProcessor.onaudioprocess=function(event){var outputBuffer=event.outputBuffer 45outputBuffer.getChannelData(0).set(event.inputBuffer.getChannelData(0)),createWaveform(outputBuffer,ictx,1)},gainNode.gain.value=50,gainNode.connect(streamDestination),scriptProcessor.connect(actx.destination),navigator.mediaDevices.getUserMedia({video:!1,audio:!0}).then(function(stream){var input=actx.createMediaStreamSource(stream) 46recorderStream=stream,$btnMute.addEventListener("click",function(){isMute?(isMute=!1,input.connect(scriptProcessor),input.connect(gainNode), 47 $btnMute.classList.remove("is-muted")):(isMute=!0,input.disconnect(scriptProcessor),input.disconnect(gainNode),$btnMute.classList.add("is-muted"))},!1),input.connect(scriptProcessor),input.connect(gainNode)}), 48 $btnRec.addEventListener("click",function(){isRecording?(isRecording=!1,$btnRec.classList.remove("is-recording"),recorder1.stop(),recorder2.stop()):(isRecording=!0,$btnRec.classList.add("is-recording"), 49 $btnRecDownload.removeAttribute("href"),recorder1=new MediaRecorder(recorderStream),recorder2=new MediaRecorder(streamDestination.stream),recorder1.ondataavailable=function(event){renderCanvas(event.data,$raudio,$btnRecDownload,rctx)},recorder2.ondataavailable=function(event){renderCanvas(event.data,$eaudio,$btnEffectDownload,ectx)},recorder1.start(),recorder2.start())},!1), 50 $btnRecClear.addEventListener("click",function(){clearSection(rctx,$btnRecDownload,$btnRecPlay,$raudio)},!1), 51 $btnEffectClear.addEventListener("click",function(){clearSection(ectx,$btnEffectDownload,$btnEffectPlay,$eaudio)},!1), 52 $btnRecPlay.addEventListener("click",function(){playAudio($btnRecPlay,$raudio)},!1), 53 $btnEffectPlay.addEventListener("click",function(){playAudio($btnEffectPlay,$eaudio)},!1)}(window,document,window.AudioContext,window.MediaRecorder)

試したこと

色々調べたがPythonやMatlabなどならできるのですがHTML上に表示する手段がなくとても困ってます。

補足情報(FW/ツールのバージョンなど)

mp3から波形を表示するJSはwavesurferというものです。
URL https://wavesurfer-js.org/
音声認識から波形を表示
URL https://www.mitsue.co.jp/knowledge/blog/frontend/201704/05_1206.html

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

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

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

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

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

colling

2018/11/28 13:29

一致させるとは、どういうことを言ってますか?
father

2018/11/28 15:16

一致ではなかったです。波形がどれだけ似ているかの判定の手段ですね 修正しておきます
guest

回答1

0

HTML上で波形がどれだけ似ているかの判定

が、どのようなものか想像がつきませんが、重ねて表示するだけならば、CSSで、同じ位置に表示し、z-indexで重なりの上下関係を指定した上で、上になった方に透明度を指定してあげるだけでいいのではないでしょうか?

例えばこのような表示
例えばこのような表示

wavesurfer-jsを使ったサンプル

html

1<!DOCTYPE html> 2<html> 3<head> 4<meta charset="utf-8" /> 5<style> 6 7#waveform{ 8 width:100%; 9 opacity:100; 10 position:absolute; 11 top:0; 12 left:0; 13} 14#waveform2{ 15 width:100%; 16 opacity:0.7; 17 z-index:2; 18 position:absolute; 19 top:0px; 20 left:0; 21} 22 23</style> 24</head> 25<body> 26<script src="https://unpkg.com/wavesurfer.js"></script> 27 28<div id="waveform"> </div> 29 30<div id="waveform2"> </div> 31 32<script language="JavaScript"> 33 34var wavesurfer = WaveSurfer.create({ 35 container: '#waveform', 36 waveColor: 'red' 37}); 38 39wavesurfer.load('http://codesign.tips/sandbox/audio/snare_drum01.wav'); 40 41var wavesurfer = WaveSurfer.create({ 42 container: '#waveform2', 43 waveColor: 'skyblue' 44}); 45 46wavesurfer.load('http://codesign.tips/sandbox/audio/snare_drum02.wav'); 47 48</script> 49</body> 50</html>

※ 音の違いを計算して云々でしたらすいません。(意向と大きく外れています。)

投稿2018/11/29 01:19

編集2018/11/29 01:23
colling

総合スコア798

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

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

father

2018/11/29 04:37

ありがとうございます。音声認識からの波形の類似度だったのですが、重ねて表示するというアイデアは考え付かなかったので貴重なアイデアありがとうございます!
colling

2018/11/29 04:59

音声の入力ではなくて、認識ですか? wavesurferもマイク入力をリアルタイムで表示できそうですが、、。 認識の意味するところはなんでしょう?
father

2018/11/29 05:07

入力と認識… 意味的にはどういう違いがあるのでしょう? すいません勉強不足で… wavesurferでもリアルタイム表示できるんですか? そこは知らなかったです…
colling

2018/11/29 05:15

認識 = 何か音を入れたら、これは「あいうえお」って言ってる。というようなプログラム上の認識や判別が必要 なのかなと、勘ぐっていました。w
colling

2018/11/29 05:22

wavesurfer-jsのプラグインのページ https://wavesurfer-js.org/plugins/ に Microphone plugin というのがあります。 使ったことないですが、ネーミング的にはできそうな雰囲気かも?
father

2018/11/29 06:25

なるほど それだと入力でもよさそうな気がします。波形が出せればいいので! URLありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問