前端之实现讯飞语音听写(流式版)
第一次接到语音需求,用了几年的微信,你有关注过微信语音实时转文字功能吗?反正我是经常用,在这人山人海的大城市,为了解放双手又能及时回复好友,我经常用语音转文字。
没想到,一时用一时爽,自己开发火葬场。不慌不忙的我先整理思路,结合讯飞提供的文档和接口,最后实现了。
对于小白来说,着实会被吓一跳,但是自己实践后,就会发现实际很简单,因为原理讯飞那边已经给你解决了,在这里强调一下,实际开发中接口最好经过后端处理之后再给前端使用。
一、需求
1、点击开始,实现语音录入,并转换文字
2、点击关闭按钮,关闭这个界面
3、延时或转换文字慢的时候,动画切换
4、根据声音大小来显示音波图
前面两点案例已经实现,后面两点是根据需求来确定和增加
二、熟读讯飞文档
(一)点击讯飞开发平台 https://www.xfyun.cn/
(二)选择对应的功能——语音听写
官网中对功能有详细的介绍、免费使用(需要注册)、产品体验(使用之前体验一波)和技术文档参考(技术文档一定要看)
(三)熟读技术文档
技术文档可以从上图中进入,也可以进入控制台后进入
这里挑重点说明一下几点:
1、案例:必须要下载和研读,按照自己的技术选择对应的案例,我这边选择的是js
2、接口:虽然下载的案例中已经帮我们写好了接口,是便于前端测试用,实际上是需要后端处理再转手给我们。别问,问就是安全性。
3、服务接口认真信息(key):每个人申请账号之后都会拥有一个key,如下图
4、注意点:可能有些小伙伴会疑问为什么自己没有关闭,自己会断开,原因已经在下面了
三、研读案例
(一)启动项目
1、安装依赖 npm i
2、启动项目 npm run dev
和官网体验版一样
(二)重点依赖提取
在这个案例中安装了很多依赖(自己查看),实际开发中我们只需要一个crypto-js(加密解密)
(三)通过案例提取重要文件,集成到自己的项目中
1、案例中重要代码,案例中已经详细的注解了代码含义,我这里不在赘述
2、抽离整合
(1)transcode.js
将语音转化成正确格式的方法。很多小伙伴用脚手架时候可能会遇到无法引入transcode.worker.js,查找资料需要安装worker-loader,然后做配置。vue中我没有试过,react中安装会有些其他问题,其实可以微微修改一下代码,如下
const workercode = () => {let self = this;self.onmessage = function (e) {transAudioData.transcode(e.data);};let transAudioData = {transcode(audioData) {let output = transAudioData.to16kHz(audioData);output = transAudioData.to16BitPCM(output);output = Array.from(new Uint8Array(output.buffer));self.postMessage(output);// return output},to16kHz(audioData) {var data = new Float32Array(audioData);var fitCount = Math.round(data.length * (16000 / 44100));var newData = new Float32Array(fitCount);var springFactor = (data.length - 1) / (fitCount - 1);newData[0] = data[0];for (let i = 1; i < fitCount - 1; i++) {var tmp = i * springFactor;var before = Math.floor(tmp).toFixed();var after = Math.ceil(tmp).toFixed();var atPoint = tmp - before;newData[i] = data[before] + (data[after] - data[before]) * atPoint;}newData[fitCount - 1] = data[data.length - 1];return newData;},to16BitPCM(input) {var dataLength = input.length * (16 / 8);var dataBuffer = new ArrayBuffer(dataLength);var dataView = new DataView(dataBuffer);var offset = 0;for (var i = 0; i < input.length; i++, offset += 2) {var s = Math.max(-1, Math.min(1, input[i]));dataView.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);}return dataView;},};
};
let code = workercode.toString();
code = code.substring(code.indexOf('{') + 1, code.lastIndexOf('}'));
const blob = new Blob([code], { type: 'application/javascript' });
const worker_script = URL.createObjectURL(blob);
module.exports = worker_script;
(2)IatRecorder.js
const APPID = '' //在科大讯飞控制台中获取的服务接口认证信息
const API_SECRET = '' //在科大讯飞控制台中获取的服务接口认证信息
const API_KEY = '' //在科大讯飞控制台中获取的服务接口认证信息
import CryptoJS from 'crypto-js'
import worker_script from './transcode.js'const transWorker = new Worker(worker_script)
var startTime = ""
var endTime = ""
function getWebSocketUrl() {return new Promise((resolve, reject) => {// 请求地址根据语种不同变化var url = 'wss://iat-api.xfyun.cn/v2/iat'var host = 'iat-api.xfyun.cn'var apiKey = API_KEYvar apiSecret = API_SECRETvar date = new Date().toGMTString()var algorithm = 'hmac-sha256'var headers = 'host date request-line'var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret)var signature = CryptoJS.enc.Base64.stringify(signatureSha)var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`var authorization = btoa(authorizationOrigin)url = `${url}?authorization=${authorization}&date=${date}&host=${host}`resolve(url)})
}
class IatRecorder {constructor({ language, accent, appId } = {}) {let self = thisthis.status = 'null'this.language = language || 'zh_cn'this.accent = accent || 'mandarin'this.appId = appId || APPID// 记录音频数据this.audioData = []// 记录听写结果this.resultText = ''// wpgs下的听写结果需要中间状态辅助记录this.resultTextTemp = ''transWorker.onmessage = function (event) {self.audioData.push(...event.data)}}// 修改录音听写状态setStatus(status) {this.onWillStatusChange && this.status !== status && this.onWillStatusChange(this.status, status)this.status = status}setResultText({ resultText, resultTextTemp } = {}) {this.onTextChange && this.onTextChange(resultTextTemp || resultText || '')resultText !== undefined && (this.resultText = resultText)resultTextTemp !== undefined && (this.resultTextTemp = resultTextTemp)}// 修改听写参数setParams({ language, accent } = {}) {language && (this.language = language)accent && (this.accent = accent)}// 连接websocketconnectWebSocket() {return getWebSocketUrl().then(url => {let iatWSif ('WebSocket' in window) {iatWS = new WebSocket(url)} else if ('MozWebSocket' in window) {iatWS = new MozWebSocket(url)} else {alert('浏览器不支持WebSocket')return}this.webSocket = iatWSthis.setStatus('init')iatWS.onopen = e => {this.setStatus('ing')// 重新开始录音setTimeout(() => {this.webSocketSend()}, 500)}iatWS.onmessage = e => {this.result(e.data)}iatWS.onerror = e => {this.recorderStop()}iatWS.onclose = e => {this.recorderStop()}})}// 初始化浏览器录音recorderInit() {navigator.getUserMedia =navigator.getUserMedia ||navigator.webkitGetUserMedia ||navigator.mozGetUserMedia ||navigator.msGetUserMedia// 创建音频环境try {this.audioContext = new (window.AudioContext || window.webkitAudioContext)()this.audioContext.resume()if (!this.audioContext) {alert('浏览器不支持webAudioApi相关接口')return}} catch (e) {if (!this.audioContext) {alert('浏览器不支持webAudioApi相关接口')return}}// 获取浏览器录音权限if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {navigator.mediaDevices.getUserMedia({audio: true,video: false,}).then(stream => {getMediaSuccess(stream)}).catch(e => {getMediaFail(e)})} else if (navigator.getUserMedia) {navigator.getUserMedia({audio: true,video: false,},stream => {getMediaSuccess(stream)},function(e) {getMediaFail(e)})} else {if (navigator.userAgent.toLowerCase().match(/chrome/) && location.origin.indexOf('https://') < 0) {alert('chrome下获取浏览器录音功能,因为安全性问题,需要在localhost或127.0.0.1或https下才能获取权限')} else {alert('无法获取浏览器录音功能,请升级浏览器或使用chrome')}this.audioContext && this.audioContext.close()return}// 获取浏览器录音权限成功的回调let getMediaSuccess = stream => {console.log('getMediaSuccess')// 创建一个用于通过JavaScript直接处理音频this.scriptProcessor = this.audioContext.createScriptProcessor(0, 1, 1)this.scriptProcessor.onaudioprocess = e => {// 去处理音频数据if (this.status === 'ing') {transWorker.postMessage(e.inputBuffer.getChannelData(0))}}// 创建一个新的MediaStreamAudioSourceNode 对象,使来自MediaStream的音频可以被播放和操作this.mediaSource = this.audioContext.createMediaStreamSource(stream)// 连接this.mediaSource.connect(this.scriptProcessor)this.scriptProcessor.connect(this.audioContext.destination)this.connectWebSocket()}let getMediaFail = (e) => {alert('请求麦克风失败')console.log(e)this.audioContext && this.audioContext.close()this.audioContext = undefined// 关闭websocketif (this.webSocket && this.webSocket.readyState === 1) {this.webSocket.close()}}}recorderStart() {if (!this.audioContext) {this.recorderInit()} else {this.audioContext.resume()this.connectWebSocket()}}// 暂停录音recorderStop() {// safari下suspend后再次resume录音内容将是空白,设置safari下不做suspendif (!(/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgen))){this.audioContext && this.audioContext.suspend()}this.setStatus('end')}// 处理音频数据// transAudioData(audioData) {// audioData = transAudioData.transaction(audioData)// this.audioData.push(...audioData)// }// 对处理后的音频数据进行base64编码,toBase64(buffer) {var binary = ''var bytes = new Uint8Array(buffer)var len = bytes.byteLengthfor (var i = 0; i < len; i++) {binary += String.fromCharCode(bytes[i])}return window.btoa(binary)}// 向webSocket发送数据webSocketSend() {if (this.webSocket.readyState !== 1) {return}let audioData = this.audioData.splice(0, 1280)var params = {common: {app_id: this.appId,},business: {language: this.language, //小语种可在控制台--语音听写(流式)--方言/语种处添加试用domain: 'iat',accent: this.accent, //中文方言可在控制台--语音听写(流式)--方言/语种处添加试用vad_eos: 5000,dwa: 'wpgs', //为使该功能生效,需到控制台开通动态修正功能(该功能免费)},data: {status: 0,format: 'audio/L16;rate=16000',encoding: 'raw',audio: this.toBase64(audioData),},}this.webSocket.send(JSON.stringify(params))this.handlerInterval = setInterval(() => {// websocket未连接if (this.webSocket.readyState !== 1) {this.audioData = []clearInterval(this.handlerInterval)return}if (this.audioData.length === 0) {if (this.status === 'end') {this.webSocket.send(JSON.stringify({data: {status: 2,format: 'audio/L16;rate=16000',encoding: 'raw',audio: '',},}))this.audioData = []clearInterval(this.handlerInterval)}return false}audioData = this.audioData.splice(0, 1280)// 中间帧this.webSocket.send(JSON.stringify({data: {status: 1,format: 'audio/L16;rate=16000',encoding: 'raw',audio: this.toBase64(audioData),},}))}, 40)}result(resultData) {// 识别结束let jsonData = JSON.parse(resultData)if (jsonData.data && jsonData.data.result) {let data = jsonData.data.resultlet str = ''let resultStr = ''let ws = data.wsfor (let i = 0; i < ws.length; i++) {str = str + ws[i].cw[0].w}// 开启wpgs会有此字段(前提:在控制台开通动态修正功能)// 取值为 "apd"时表示该片结果是追加到前面的最终结果;取值为"rpl" 时表示替换前面的部分结果,替换范围为rg字段if (data.pgs) {if (data.pgs === 'apd') {// 将resultTextTemp同步给resultTextthis.setResultText({resultText: this.resultTextTemp,})}// 将结果存储在resultTextTemp中this.setResultText({resultTextTemp: this.resultText + str,})} else {this.setResultText({resultText: this.resultText + str,})}}if (jsonData.code === 0 && jsonData.data.status === 2) {this.webSocket.close()}if (jsonData.code !== 0) {this.webSocket.close()console.log(`${jsonData.code}:${jsonData.message}`)}}start() {this.recorderStart()this.setResultText({ resultText: '', resultTextTemp: '' })}stop() {this.recorderStop()}
}export default IatRecorder
(3)引用和调用方法
import IatRecorder from '../../../public/voice/IatRecorder.js'
const iatRecorder = new IatRecorder('en_us', 'mandarin', '9abbbfb0')//小语种-中文方言-appIdiatRecorder.start()//开始录音-----根据自己的实际情况在触发事件中调用
iatRecorder.stop()//结束录音-----根据自己的实际情况在触发事件中调用
以上css样式和整体项目这边不给出,大家可结合官网案例来实践
四、功能增加,根据声音来波动
思路:先写一个检测声音大小的函数,之后根据自己项目的需求来决定在什么时候开始检测,什么时候结束检测
音量大小获取视频演示
(一)检测声音大小的函数
// 开始检测音量大小的函数function beginDetect() {let audioContext = new (window.AudioContext || window.webkitAudioContext)();if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {// 获取用户的 media 信息navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {// 将麦克风的声音输入这个对象mediaStreamSource = audioContext.createMediaStreamSource(stream);// 创建一个音频分析对象,采样的缓冲区大小为4096,输入和输出都是单声道scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1);// 将该分析对象与麦克风音频进行连接mediaStreamSource.connect(scriptProcessor);// 解决 Chrome 自身的 bugscriptProcessor.connect(audioContext.destination);// 开始处理音频scriptProcessor.onaudioprocess = (e) => {// 获得缓冲区的输入音频,转换为包含了PCM通道数据的32位浮点数组const buffer = e.inputBuffer.getChannelData(0);// 获取缓冲区中最大的音量值const maxVal = Math.max.apply(Math, buffer);// 显示音量值,react中设置值setVolume(Math.round(maxVal * 100))};}).catch((error) => {console.log(`获取音频时好像出了点问题。${error}`);})} else {console.log('您的浏览器不支持识别声音大小');}};// 关闭检测音量大小function stopDetect() {scriptProcessor.disconnect? scriptProcessor.disconnect(): console.log('无需关闭任何');}
(二)仿讯飞语音输入发语音转文字的音波图---css
仿讯飞语音输入发语音转文字音波图视频
说明:高度和动画是由声音的大小来检测决定的,如我这里的props.volume就是又父组件传过来的声音大小,而父组件的声音大小是由上面检测声音大小的函数中获取。通过声音大小的范围来指定样式,从而达到声音大小不一样,动画不一样的效果
1、html结构
这里大家可以借鉴优化,毕竟结构太繁琐了,可以通过用js来控制动态生成,我这里就不再做优化了
<div className="container_head"><div className="container" ><div className='spanBox' style={{// height: (props.volume == 0 ? 2 : props.volume / 25) + "rem",height: (props.volume / 25 > 0.5 ? 1 : (props.volume / 25)) + "rem",}}>{props.volume > 0 && props.volume <= 10 ? <><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 25) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 24) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 23) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 22) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 21) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 19) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 18) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 17) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 16) + 's', minHeight: '0.05rem', maxHeight: '14%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 15) + 's', minHeight: '0.05rem', maxHeight: '12%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 14) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 13) + 's', minHeight: '0.05rem', maxHeight: '8%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 12) + 's', minHeight: '0.05rem', maxHeight: '7%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 11) + 's', minHeight: '0.05rem', maxHeight: '7%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 10) + 's', minHeight: '0.05rem', maxHeight: '7%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 9) + 's', minHeight: '0.05rem', maxHeight: '7%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 8) + 's', minHeight: '0.05rem', maxHeight: '8%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 7) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 6) + 's', minHeight: '0.05rem', maxHeight: '12%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 5) + 's', minHeight: '0.05rem', maxHeight: '14%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 4) + 's', minHeight: '0.05rem', maxHeight: '16%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 3) + 's', minHeight: '0.05rem', maxHeight: '18%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 2) + 's', minHeight: '0.05rem', maxHeight: '19%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 1) + 's', minHeight: '0.05rem', maxHeight: '20%' }}></span></> : props.volume > 10 && props.volume <= 40 ? <><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 25) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 24) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 23) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 22) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 21) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 19) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 18) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 17) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 16) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 15) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 14) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 13) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 12) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 11) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 10) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 9) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 8) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 7) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 6) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 5) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 4) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 3) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 2) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 1) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span></> : props.volume > 40 ? <><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 25) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 24) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 23) + 's', minHeight: '0.05rem', maxHeight: '60%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 22) + 's', minHeight: '0.05rem', maxHeight: '80%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 21) + 's', minHeight: '0.05rem', maxHeight: '90%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 19) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 18) + 's', minHeight: '0.05rem', maxHeight: '60%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 17) + 's', minHeight: '0.05rem', maxHeight: '80%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 16) + 's', minHeight: '0.05rem', maxHeight: '90%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 15) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 14) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 13) + 's', minHeight: '0.05rem', maxHeight: '60%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 12) + 's', minHeight: '0.05rem', maxHeight: '80%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 11) + 's', minHeight: '0.05rem', maxHeight: '90%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 10) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 9) + 's', minHeight: '0.05rem', maxHeight: '8%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 8) + 's', minHeight: '0.05rem', maxHeight: '6%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 7) + 's', minHeight: '0.05rem', maxHeight: '8%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 6) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 5) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 4) + 's', minHeight: '0.05rem', maxHeight: '60%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 3) + 's', minHeight: '0.05rem', maxHeight: '80%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 2) + 's', minHeight: '0.05rem', maxHeight: '90%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 1) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span></> : props.volume == 0 ? <><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span></> : null}</div><span className='microphone' onClick={startVoice1}><Microphone /></span><div className='spanBox' style={{// height: (props.volume == 0 ? 2 : props.volume / 25) + "rem",height: (props.volume / 25 > 0.5 ? 1 : (props.volume / 25)) + "rem",}}>{props.volume > 0 && props.volume <= 10 ? <><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 1) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 2) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 3) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 4) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 5) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 6) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 7) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 8) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 9) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 10) + 's', minHeight: '0.05rem', maxHeight: '14%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 11) + 's', minHeight: '0.05rem', maxHeight: '12%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 12) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 13) + 's', minHeight: '0.05rem', maxHeight: '8%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 15) + 's', minHeight: '0.05rem', maxHeight: '7%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 16) + 's', minHeight: '0.05rem', maxHeight: '7%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 17) + 's', minHeight: '0.05rem', maxHeight: '7%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 18) + 's', minHeight: '0.05rem', maxHeight: '7%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 19) + 's', minHeight: '0.05rem', maxHeight: '8%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 21) + 's', minHeight: '0.05rem', maxHeight: '12%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 22) + 's', minHeight: '0.05rem', maxHeight: '14%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 23) + 's', minHeight: '0.05rem', maxHeight: '16%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 24) + 's', minHeight: '0.05rem', maxHeight: '18%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 25) + 's', minHeight: '0.05rem', maxHeight: '19%' }}></span></> : props.volume > 10 && props.volume <= 40 ? <><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 1) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 2) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 3) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 4) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 5) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 6) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 7) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 8) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 9) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 10) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 11) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 12) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 13) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 14) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 15) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 16) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 17) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 18) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 19) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 21) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 22) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 23) + 's', minHeight: '0.05rem', maxHeight: '40%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 24) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 25) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span></> : props.volume > 40 ? <><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 1) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 2) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 3) + 's', minHeight: '0.05rem', maxHeight: '60%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 4) + 's', minHeight: '0.05rem', maxHeight: '80%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 5) + 's', minHeight: '0.05rem', maxHeight: '90%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 6) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 7) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 8) + 's', minHeight: '0.05rem', maxHeight: '60%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 9) + 's', minHeight: '0.05rem', maxHeight: '80%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 10) + 's', minHeight: '0.05rem', maxHeight: '90%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 11) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 12) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 13) + 's', minHeight: '0.05rem', maxHeight: '60%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 14) + 's', minHeight: '0.05rem', maxHeight: '80%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 15) + 's', minHeight: '0.05rem', maxHeight: '90%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 16) + 's', minHeight: '0.05rem', maxHeight: '100%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 17) + 's', minHeight: '0.05rem', maxHeight: '90%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 18) + 's', minHeight: '0.05rem', maxHeight: '60%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 19) + 's', minHeight: '0.05rem', maxHeight: '80%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '70%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 21) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 22) + 's', minHeight: '0.05rem', maxHeight: '8%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 23) + 's', minHeight: '0.05rem', maxHeight: '6%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 24) + 's', minHeight: '0.05rem', maxHeight: '8%' }}></span><span className='loadings' style={{ borderRadius: (props.volume / 18 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 25) + 's', minHeight: '0.05rem', maxHeight: '10%' }}></span></> : props.volume == 0 ? <><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span><span className='loading' style={{ borderRadius: (2 * 0.2 * 0.5 + 'rem'), animationDelay: (0.2 * 20) + 's', minHeight: '0.05rem', maxHeight: '2%' }}></span></> : null}</div></div></div>
2、css样式
.container_head{position: fixed;bottom: 0rem;left: 50%;transform: translate(-50%,-60%);height: 1rem;display: flex;align-items: center;justify-content: center;
}
.container {display: flex;align-items: center;justify-content: center;max-height: 1rem;min-height: .2rem;}
.spanBox{display: flex;align-items: center;justify-content: center;width: 6rem;max-height: 1rem;min-height: .2rem;
}.container .spanBox .loading {background: #3370FF;width: 0.06rem;height: 20%;margin-right: 0.12rem
}.container .spanBox .loadings {background: #3370FF;width: 0.06rem;height: 20%;margin-right: 0.12rem;animation: loading 2.5s infinite linear;
}
.container span:last-child {margin-right: 0px;
}@keyframes loading {0% {background-image: linear-gradient(to right, #3370FF 0%, #33C2FF 100%);height: 20%;border-radius: calc(80px * 0.2 * 0.5);}50% {background-image: linear-gradient(to top, #33C2FF 0%, #33C2FF 100%);height: 100%;border-radius: calc(80px * 1 * 0.5);}100% {background-image: linear-gradient(to top, #a8edea 0%, #7CF7FF 100%);height: 20%;border-radius: calc(80px * 0.2 * 0.5);}
}
网上有很多vue的案例,但是在react中的还很少,但是弄懂原理之后就很简单
前端之实现讯飞语音听写(流式版)相关推荐
- html5语音听写流式,iOS 讯飞语音听写(流式版)
最近项目中用到了讯飞的语音识别,然后稍微看了一下,里面有几个值得注意的点,记录一下,先说语音听写(流式版),实时语音转写后期会附上 ,文末有 demo //语音听写(流式版) 语音听写流式版其实没设么 ...
- 测试迅飞语音听写流式版 (by quqi99)
作者:张华 发表于:2019-10-09 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 (https://zhhuabj.blog.csdn.net) 刚花了 ...
- 关于讯飞语音听写RecognizerDialog 去除这个弹框view中的任何控件 更改其中内容
| | | 上面这是讯飞语音听写sdk的听写弹框下面两张是自己项目中改的 我发现他sdk的assets下的iflytek 中的recognize.xml 里面虽然是乱码 但是可以看到的一些东西是此倾听 ...
- android 讯飞语音 提示组件未安装,讯飞语音听写API 未安装组件 错误码21001
在使用讯飞语音听写时,使用云端听写而不是使用本地出现这个未安装组件错误那可能就是so文件没有成功导入.文档中都是ADT环境的配置,在AndroidStudio中jar包等都和ADT差别不大,但是SO文 ...
- 讯飞语音听写常见问题
最近,项目中要用讯飞语音听写的功能,于是在官网学习了一下,并尝试做个小Demo,期间遇到了一些问题,列举一下: (1)常报错误码11201,是未经授权的语音应用,意思是官方每天允许你使用的次数你已经用 ...
- AndroidStudio快速开发讯飞语音听写
好久没更新了,差点就忘记这个东东了,不过好在一闲下来就赶紧更新一波 哈哈^_^ **此博客主要针对将要进行语音开发的小白,如有不对的地方,请指正 到科大讯飞官网注册账号并登陆,选择单个服务SDK下载 ...
- Unity2021接入讯飞语音听写(Android)
使用的引擎工具: Unity2021.3.19 android-studio-2021.1.21 第一步: 新建一个Android项目(工程名字随便啦) 然后新建一个library (同上,库名自己命 ...
- 讯飞语音转写php版demo
是转写,不是听写!!! 是转写,不是听写!!! 是转写,不是听写!!! 讯飞开放平台提供的api里面,demo只提供了py3和java的版本!!! github包括码云我也没有找到现成的代码(不一定没 ...
- python调用讯飞语音听写(流式版)
目录 一.引入所需要的包 二.定义相关常量 三.生成请求url 四.音频相关 1. 首先使用pyaudio获取音频流 2. 从音频流中获取音频并上传到接口 五.语音识别接口调用 六.返回结果处理 七. ...
最新文章
- 谈谈你对集成学习的见解与认识,描述一下它们的优势所在?
- 深度学习巨头Yoshua Bengio清华演讲: 深度学习通往人类水平人工智能的挑战
- 终于写完了!PyCharm操作手册 V1.0版本
- [Unity] GameFramework 学习记录 3
- shell简单的交互式脚本
- android fragment面试,Android fragment之间传递数据的方式?
- android 静态_Google静态地图Android
- Trello:轻量级团队流程协作和列表管理平台[转自http://www.36kr.com/p/46852.html]
- Struts 2的基石——拦截器(Interceptor)详细讲解
- Linux.2- shell命令(部分)
- 什么是胖客户端和瘦客户端?什么是哑终端?
- android电视安装app
- 数据结构1 - 向量
- ファイルダウンロード
- 机器视觉的相机标定到底是什么?
- 如何做好大数据监测和舆情案例分析工作的办法
- in-pet流浪动物远程救助领养平台
- 为什么学编程?如何学习编程?
- 08年A题数码相机定位学习笔记
- 移动硬盘无法读取怎么修复?
热门文章
- pid控制中p、i、d各自作用
- PS色彩平衡工具修复偏蓝风景照片色彩
- STM32F103C8T6下载时读芯片信息失败常见问题
- 图像处理中Normalization的应用
- 考研c语言入门自学书籍推荐,【每周一点】2020计算机考研:参考书及复习重点...
- 单片机与计算机串行通信原理图,PC与51单片机之间RS232串行通信电路原理图/源码等...
- 关于芯片功耗那些事(一)
- Unity 把向量归一化的normalized和Normalized
- 从零搭建自己的SpringBoot后台框架(一)
- 开源软件与我国的基础教育