日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

js實(shí)現(xiàn)mp3錄音通過(guò)websocket實(shí)時(shí)傳送+簡(jiǎn)易波形圖效果

瀏覽:222日期:2024-05-04 15:07:02

波形圖:https://www.jb51.net/article/188545.htm

廢話:想不到我的第一篇博客是關(guān)于前端,作為一名后端的小菜,前端方面肯定還有很多不足之處,如果文章有任何問(wèn)題歡迎指正。感謝大家。好了!廢話不多說(shuō)下面講一下需求。

需求:公司要求實(shí)現(xiàn)web端的錄音并通過(guò)websocket實(shí)時(shí)上傳至java后臺(tái),而且能通過(guò)vlc實(shí)時(shí)播放,簡(jiǎn)單一點(diǎn)講就是我用網(wǎng)頁(yè)在那一邊講話,一個(gè)大喇叭就能實(shí)時(shí)把我的話播出去,這樣是不是通俗易懂呀,而且呢公司要求用mp3格式。當(dāng)然啦!為了知道自己在講話需要一個(gè)波形圖,這里主要實(shí)現(xiàn)前半部分功能,后半部分臣妾也做不到呀!后半部分的vlc播放呢如果大家想知道,可以留言,屆時(shí)可以給大家指條明路

前端實(shí)現(xiàn):

引入:

<script type='text/javascript' src='https://rkxy.com.cn/js/recorder/recordmp3.js'></script>

這個(gè)跟大佬的js有點(diǎn)不一樣,我在里面加了一點(diǎn)東西,而且在這個(gè)js里面引入了兩個(gè)另外的js,lame.min.js和worker-realtime.js,這倆在大佬的代碼里有

頁(yè)面:

<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head> <meta http-equiv='Content-Type' content='text/html; charset=gb2312'/> <title>測(cè)試</title></head><body><button id='intercomBegin'>開始對(duì)講</button><button id='intercomEnd'>關(guān)閉對(duì)講</button><canvas style='width: 400px;height: 100px'></canvas></body><script type='text/javascript' src='https://rkxy.com.cn/js/jquery-3.3.1.js'></script><script type='text/javascript' src='https://rkxy.com.cn/js/recorder/recordmp3.js'></script><script type='text/javascript'> var begin = document.getElementById(’intercomBegin’); var end = document.getElementById(’intercomEnd’); var canvas = document.getElementById('casvased'); var canvasCtx = canvas.getContext('2d'); var ws = null; //實(shí)現(xiàn)WebSocket var recorder; /* * WebSocket */ function useWebSocket() { ws = new WebSocket('ws://127.0.0.1:8089/send/voice'); ws.binaryType = ’arraybuffer’; //傳輸?shù)氖?ArrayBuffer 類型的數(shù)據(jù) ws.onopen = function () { console.log(’握手成功’); if (ws.readyState == 1) { //ws進(jìn)入連接狀態(tài),則每隔500毫秒發(fā)送一包數(shù)據(jù) recorder.start(); } }; ws.onmessage = function (msg) { console.info(msg) } ws.onerror = function (err) { console.info(err) } } /* * 開始對(duì)講 */ begin.onclick = function () { recorder = new MP3Recorder({ debug: true, funOk: function () { console.log(’點(diǎn)擊錄制,開始錄音! ’); }, funCancel: function (msg) { console.log(msg); recorder = null; } }); } /* * 關(guān)閉對(duì)講 */ end.onclick = function () { if (ws) { ws.close(); recorder.stop(); console.log(’關(guān)閉對(duì)講以及WebSocket’); } } var sendData = function() { //對(duì)以獲取的數(shù)據(jù)進(jìn)行處理(分包) var reader = new FileReader(); reader.onload = e => { var outbuffer = e.target.result; var arr = new Int8Array(outbuffer); if (arr.length > 0) { var tmparr = new Int8Array(1024); var j = 0; for (var i = 0; i < arr.byteLength; i++) { tmparr[j++] = arr[i]; if (((i + 1) % 1024) == 0) { ws.send(tmparr); if (arr.byteLength - i - 1 >= 1024) { tmparr = new Int8Array(1024); } else { tmparr = new Int8Array(arr.byteLength - i - 1); } j = 0; } if ((i + 1 == arr.byteLength) && ((i + 1) % 1024) != 0) { ws.send(tmparr); } } } }; recorder.getMp3Blob(function (blob) { reader.readAsArrayBuffer(blob);//這里拿到mp3格式的音頻流寫入到reader中 }) }; </script> </html>recordmp3.js(function (exports) { var MP3Recorder = function (config) { var recorder = this; config = config || {}; config.sampleRate = config.sampleRate || 44100; config.bitRate = config.bitRate || 128; navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; if (navigator.getUserMedia) { navigator.getUserMedia({ audio: true }, function (stream) { var context = new AudioContext(), microphone = context.createMediaStreamSource(stream), processor = context.createScriptProcessor(16384, 1, 1),//bufferSize大小,輸入channel數(shù),輸出channel數(shù) mp3ReceiveSuccess, currentErrorCallback; var height = 100; var width = 400; const analyser = context.createAnalyser() analyser.fftSize = 1024 //連接到音頻源 microphone.connect(analyser); analyser.connect(context.destination); const bufferLength = analyser.frequencyBinCount // 返回的是 analyser的fftsize的一半 const dataArray = new Uint8Array(bufferLength); function draw() { canvasCtx.clearRect(0, 0, width, height); //清除畫布 analyser.getByteFrequencyData(dataArray); // 將當(dāng)前頻率數(shù)據(jù)復(fù)制到傳入其中的Uint8Array const requestAnimFrame = window.requestAnimationFrame(draw) || window.webkitRequestAnimationFrame(draw); canvasCtx.fillStyle = ’#000130’; canvasCtx.fillRect(0, 0, width, height); let barWidth = (width / bufferLength) * 2; let barHeight; let x = 0; let c = 2 for (let i = 0; i < bufferLength; i++) { barHeight = c+(dataArray[i]/400)*height; canvasCtx.fillStyle = ’rgb(0, 255, 30)’; canvasCtx.fillRect(x, height / 2 - barHeight / 2, barWidth, barHeight); x += barWidth + 1; } } draw(); useWebSocket(); config.sampleRate = context.sampleRate; processor.onaudioprocess = function (event) { //邊錄音邊轉(zhuǎn)換 var array = event.inputBuffer.getChannelData(0); realTimeWorker.postMessage({cmd: ’encode’, buf: array}); sendData(); }; var realTimeWorker = new Worker(’/js/recorder/worker-realtime.js’); realTimeWorker.onmessage = function (e) { switch (e.data.cmd) { case ’init’:log(’初始化成功’);if (config.funOk) { config.funOk();}break; case ’end’:log(’MP3大小:’, e.data.buf.length);if (mp3ReceiveSuccess) { mp3ReceiveSuccess(new Blob(e.data.buf, {type: ’audio/mp3’}));}break; case ’error’:log(’錯(cuò)誤信息:’ + e.data.error);if (currentErrorCallback) { currentErrorCallback(e.data.error);}break; default:log(’未知信息:’, e.data); } }; recorder.getMp3Blob = function (onSuccess, onError) { currentErrorCallback = onError; mp3ReceiveSuccess = onSuccess; realTimeWorker.postMessage({cmd: ’finish’}); }; recorder.start = function () { if (processor && microphone) { microphone.connect(processor); processor.connect(context.destination); log(’開始錄音’); } } recorder.stop = function () { if (processor && microphone) { microphone.disconnect(); processor.disconnect(); log(’錄音結(jié)束’); } } realTimeWorker.postMessage({ cmd: ’init’, config: { sampleRate: config.sampleRate, bitRate: config.bitRate } }); }, function (error) { var msg; switch (error.code || error.name) { case ’PERMISSION_DENIED’: case ’PermissionDeniedError’: msg = ’用戶拒絕訪問(wèn)麥客風(fēng)’; break; case ’NOT_SUPPORTED_ERROR’: case ’NotSupportedError’: msg = ’瀏覽器不支持麥客風(fēng)’; break; case ’MANDATORY_UNSATISFIED_ERROR’: case ’MandatoryUnsatisfiedError’: msg = ’找不到麥客風(fēng)設(shè)備’; break; default: msg = ’無(wú)法打開麥克風(fēng),異常信息:’ + (error.code || error.name); break; } if (config.funCancel) { config.funCancel(msg); } }); } else { if (config.funCancel) { config.funCancel(’當(dāng)前瀏覽器不支持錄音功能’); } } function log(str) { if (config.debug) { console.log(str); } } } exports.MP3Recorder = MP3Recorder;})(window);

后端websocket:這里實(shí)現(xiàn)的是保存為mp3文件

package com.jetosend.common.socket;import com.jetosend.common.utils.Utils;import org.springframework.stereotype.Component;import javax.websocket.*;import javax.websocket.server.PathParam;import javax.websocket.server.ServerEndpoint;import java.io.*;import java.nio.ByteBuffer;import java.util.Hashtable;import java.util.Map;@ServerEndpoint('/send/{key}')@Componentpublic class ServerSocket { private static final Map<String, Session> connections = new Hashtable<>(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); /*** * @Description:打開連接 * @Param: [id, 保存對(duì)方平臺(tái)的資源編碼 * session] * @Return: void * @Author: Liting * @Date: 2019-10-10 09:22 */ @OnOpen public void onOpen(@PathParam('key') String id, Session session) { System.out.println(id + '連上了'); connections.put(id, session); } /** * 接收消息 */ @OnMessage public void onMessage(@PathParam('key') String id, InputStream inputStream) { System.out.println('來(lái)自' + id); try { int rc = 0; byte[] buff = new byte[100]; while ((rc = inputStream.read(buff, 0, 100)) > 0) { byteArrayOutputStream.write(buff, 0, rc); } } catch (Exception e) { e.printStackTrace(); } } /** * 異常處理 * * @param throwable */ @OnError public void onError(Throwable throwable) { throwable.printStackTrace(); //TODO 日志打印異常 } /** * 關(guān)閉連接 */ @OnClose public void onClose(@PathParam('key') String id) { System.out.println(id + '斷開'); BufferedOutputStream bos = null; FileOutputStream fos = null; File file = null; try { file = new File('D:testtest.mp3'); //輸出流 fos = new FileOutputStream(file); //緩沖流 bos = new BufferedOutputStream(fos); //將字節(jié)數(shù)組寫出 bos.write(byteArrayOutputStream.toByteArray()); } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } connections.remove(id); }

實(shí)現(xiàn)效果:

js實(shí)現(xiàn)mp3錄音通過(guò)websocket實(shí)時(shí)傳送+簡(jiǎn)易波形圖效果

總結(jié)

到此這篇關(guān)于js實(shí)現(xiàn)mp3錄音通過(guò)websocket實(shí)時(shí)傳送+簡(jiǎn)易波形圖效果的文章就介紹到這了,更多相關(guān)js實(shí)現(xiàn)mp3錄音內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲激情社区| 99国产精品久久久久久久| 精品国产精品国产偷麻豆| 亚洲精品一区二区在线看| 久久九九电影| 久久久精品久久久久久96| 日韩av在线中文字幕| 精品午夜视频| 国产精东传媒成人av电影| 国产精品毛片一区二区在线看| 国产精品sm| 色偷偷色偷偷色偷偷在线视频| 日本久久成人网| 日韩国产一区二区三区| 欧美日韩在线观看首页| 99re国产精品| 日本精品在线播放| 国产一区二区三区久久| 97久久亚洲| 国产欧美一区二区三区精品观看| 久久精品国产一区二区| 蜜桃av在线播放| 亚洲精品女人| 麻豆国产欧美一区二区三区| 成人午夜网址| 婷婷久久一区| 欧美国产先锋| 亚洲深爱激情| 亚洲精品麻豆| 国产高清日韩| 激情欧美亚洲| 国产精品白浆| 免费人成精品欧美精品| 91精品国产经典在线观看| 国产高清不卡| 综合激情一区| 精品国产第一福利网站| 黄色亚洲免费| 91综合视频| 国产精品mm| 婷婷国产精品| 色综合五月天| 国产专区精品| 日本欧美大码aⅴ在线播放| 99pao成人国产永久免费视频 | 国产成人精品亚洲线观看| 久久久久久久久丰满| 亚洲欧美日韩国产| 九色porny丨国产首页在线| 国产精品亚洲四区在线观看| 夜夜嗨网站十八久久| 日韩深夜视频| 福利在线一区| 美女在线视频一区| 亚洲精品免费观看| 日韩中文字幕不卡| 亚洲激情av| 久久久久久黄| av在线资源| 免费观看亚洲| 成人国产精品久久| 久久一区欧美| 亚洲小说春色综合另类电影| 亚洲性色视频| 99久久精品网站| 99精品美女| 电影亚洲精品噜噜在线观看| а√天堂8资源中文在线| 国产成人精品一区二区三区在线| 日韩二区三区在线观看| 亚洲永久精品唐人导航网址| 亚洲精品中文字幕乱码| 国产一区二区三区自拍| 欧美天堂视频| 欧美午夜精彩| 免费观看在线综合色| 亚洲tv在线| 日本三级亚洲精品| 欧美日韩99| 久久精品国产99| 精品一区二区三区四区五区| 波多视频一区| 久久精品电影| 亚洲欧美日本国产| 国产精品美女久久久久久不卡| 精品国产欧美日韩| 伊人成人在线视频| 久久国产生活片100| 国产成人精品一区二区三区视频| 日韩欧美精品| 免费在线看一区| 国产经典一区| 伊人久久av| 蘑菇福利视频一区播放| 国产欧美日韩一区二区三区在线| 国产精品久久久久久模特| 999国产精品视频| 18国产精品| 亚洲福利国产| 日韩不卡一区二区| 黄在线观看免费网站ktv| 伊人久久一区| 中文在线免费视频| 日本在线观看不卡视频| 激情中国色综合| 亚洲一区国产一区| 久久精品国内一区二区三区| 麻豆视频在线观看免费网站黄 | 日韩综合一区二区三区| 国产探花一区| 蜜桃久久av| 国产精品99一区二区三| 91嫩草精品| 久久久夜夜夜| 国产精品日韩精品中文字幕| 亚洲国产专区校园欧美| 国产精区一区二区| 美女毛片一区二区三区四区| 久久男人av| 久久亚洲图片| 一区在线免费观看| 亚洲91久久| 成人国产精选| 久久激情五月激情| 日韩精品一二三区| 日韩欧美午夜| 国产精品毛片久久| 国产欧美自拍| 一区二区国产精品| 一区在线免费观看| 国产高清一区| 久久久亚洲一区| 久久毛片亚洲| 免费一二一二在线视频| 丁香婷婷久久| 久久精品天堂| 国产精品三级| 麻豆91在线播放| 久久精品系列| 亚洲综合电影| 美女一区网站| 欧美日韩一二三四| 成人精品亚洲| 久久久成人网| 美女av在线免费看| 久久一区二区三区喷水| 成人综合一区| 91精品高清| 国产精品女主播一区二区三区| 男女性色大片免费观看一区二区| 免费在线观看视频一区| 视频一区日韩| 精品国内亚洲2022精品成人| 电影91久久久| 久久精品亚洲欧美日韩精品中文字幕| 午夜av成人| 亚洲一级大片| 久久精品国产成人一区二区三区| 快播电影网址老女人久久| 一区二区三区网站| 欧美激情五月| 国产精品99精品一区二区三区∴| 高清日韩欧美| 亚洲免费毛片| 国产一区不卡| 99视频精品全国免费| 男女激情视频一区| 老司机精品视频在线播放| 久久精品av| 日韩**一区毛片| 视频小说一区二区| 久久亚洲一区| 日本高清不卡一区二区三区视频| 亚洲欧美日韩精品一区二区 | 91精品啪在线观看国产18| 中文字幕在线看片| 日本午夜免费一区二区| 亚洲午夜电影| 国产精品成人国产| 999精品一区| 亚洲国产成人二区| 国产日韩欧美中文在线| 女人天堂亚洲aⅴ在线观看| 国产精品一区二区三区av麻| 黄色日韩精品| 欧美一区二区性| 日韩在线成人| 999精品色在线播放| 国产一区二区久久久久| 一区二区三区四区日韩| 手机在线电影一区| 国产精品网址| 日韩av资源网| 日韩不卡一二三区| 午夜在线精品偷拍| 激情偷拍久久| 亚洲h色精品| 国产一区国产二区国产三区| 亚洲综合婷婷| 中文久久精品|