上海网站建设公司指南,12306网站谁做的,网站备案前置审批类型,2017年网站推广怎么做时隔差不多半个月#xff0c; 现在才来写这编博客。由于某些原因#xff0c;我一直没有写#xff0c;请大家原谅。前段时间开发了一个小模块。模块的主要功能就是有一个录音的功能。也就是说#xff0c;模仿微信发送语音的功能一样。不多说#xff0c;直接来一段代码
//自…时隔差不多半个月 现在才来写这编博客。由于某些原因我一直没有写请大家原谅。前段时间开发了一个小模块。模块的主要功能就是有一个录音的功能。也就是说模仿微信发送语音的功能一样。不多说直接来一段代码
//自定义长按事件注意 directives是跟 data ,created() 同一级的注意注意
directives: {longpress: {bind(el, binding, vnode) {let pressTimer null;let maxPressTime 60000; // 60秒 60000毫秒 let startCallback binding.value.start || Vue.noop;let endCallback binding.value.end || Vue.noop;function handlePress() {startCallback();pressTimer setTimeout(() {endCallback();clearTimeout(pressTimer);pressTimer null;}, maxPressTime);}function handleRelease() {if (pressTimer) {clearTimeout(pressTimer);pressTimer null;endCallback();}}// 确保这些函数在unbind中可用 el._handlePress handlePress;el._handleRelease handleRelease;// 添加事件监听器 el.addEventListener(mousedown, handlePress);el.addEventListener(touchstart, handlePress);el.addEventListener(mouseup, handleRelease);el.addEventListener(touchend, handleRelease);el.addEventListener(mouseleave, handleRelease);el.addEventListener(touchcancel, handleRelease);},unbind(el) {// 移除事件监听器 el.removeEventListener(mousedown, el._handlePress);el.removeEventListener(touchstart, el._handlePress);el.removeEventListener(mouseup, el._handleRelease);el.removeEventListener(touchend, el._handleRelease);el.removeEventListener(mouseleave, el._handleRelease);el.removeEventListener(touchcancel, el._handleRelease);// 清理自定义属性 el._handlePress null;el._handleRelease null;}}
},data(){return {zheZhao:false,//录音时的遮罩层isMai:false,//初始化是否支持录音luYinAttr: {isAn:false,s: 0,timer:null,audioArray:[],startTime: null,//录音开始时间endTime: null, //录音结束时间mediaRecorder: null,recording: false, //录音状态(用于录音记时)timeLength: 0,//录音时长recordedChunks: [],timer: null,longPressThreshold:800,},}
}//初始化录音对象记住录音一定得在 https里面。当然在本地开发 localhost 可以不需要但上线一定得在https里面
luYin() {//这儿先做判断判断当前设备或当前网络是否支持录音如果不支持那下面的也就不用多说了。//console.log(navigator, navigator.mediaDevices)if (!(mediaDevices in navigator)) {this.isMai false;return false;}navigator.mediaDevices.getUserMedia({ audio: true }).then(this.luYinSuccess) //支持录音继续执行下面的操作.catch(this.luYinErr) //不支持录音没下文
},
luYinSuccess(stream) {const audioContext new AudioContext();//const sourceNode audioContext.createMediaStreamSource(stream); //没用上先注释const mediaRecorder new MediaRecorder(stream);const recordedChunks [];this.luYinAttr.mediaRecorder mediaRecorderthis.luYinAttr.recordedChunks recordedChunksthis.isMai true;
},
luYinErr(err) {this.isMai false;//console.log(The following error occurred: err);
},//startRecording , stopRecording是开始计时和结束计时(由于录音的时间不能太长这儿我限制为1分分钟的时长。所以我得有一个录音计时超过1分钟录音取消)
//开始计时
startRecording() {console.log(开始计时)this.luYinAttr.isAn true;this.zheZhao true;this.luYinAttr.s 0;this.luYinAttr.recording true;this.luYinAttr.startTime Date.now();this.luYinAttr.timer setInterval(() {this.luYinAttr.s this.luYinAttr.s 1;} , 500)
},
//结束录音计时
stopRecording() {this.luYinAttr.recording false;const endTime Date.now();const startTime this.luYinAttr.startTimeconst recordDuration (endTime - startTime) / 1000; // 计算录音时长秒 if (recordDuration 60) {this.luYinAttr.timeLength 60;//结束录音}this.luYinAttr.timeLength recordDuration;/*const maxWidth 300; // 设置图标的最大宽度 const indicatorWidth Math.min(recordDuration * 20, maxWidth); // 根据录音时长计算图标宽度假设每秒对应2个像素宽度 console.log(indicatorWidth, 时长)console.log(结束计时)*/
},startLongPress() {//console.log(长按开始);let that this;clearTimeout(this.luYinAttr.timer);that.luYinAttr.timer setTimeout(function () {// 执行长按操作 //console.log(长按操作开始);that.luYinAttr.mediaRecorder.start();//console.log(that.luYinAttr.mediaRecorder.state , qqggg);//startRecord.disabled true;//stopRecord.disabled false;that.startRecording();}, that.luYinAttr.longPressThreshold);// 在这里编写长按开始时的逻辑
},
endLongPress() {//长按结束事件let that this;//console.log(取消)clearTimeout(that.luYinAttr.timer);that.luYinAttr.mediaRecorder.stop();that.stopRecording();that.luYinAttr.mediaRecorder.ondataavailable async function (e) {console.log(e)if (e.data.size 0) {const blobObj e.data;let nowTime new Date().getTime();let fileName LY_ nowTime .mp3;const file new File([blobObj], fileName, { type: audio/mpeg });//that.uplodAudio(file) //上传录音that.luYinAttr.isAn false;that.zheZhao false;clearInterval(that.luYinAttr.timer)} else {// no data to push }};
},//试听录音在苹果机上不支持
listenAudio(obj, index) {let myTimer null;this.play.listenStatus this.play.listenStatus 1;if (this.play.listenStatus 1) {clearInterval(myTimer)return false;}if (!this.playActive.isLongPressing) {let that this;let itemAudio [(that.luYinAttr.recordedChunks)[index]]//console.log(itemAudio, itemAudio, obj)let len JSON.parse(JSON.stringify(obj.timeLength));obj.timeLength 0;myTimer setInterval(() {obj.timeLength obj.timeLength 1;if (obj.timeLength len) {clearInterval(myTimer)this.play.listenStatus 0;}} , 1000)const blob new Blob(itemAudio, { type: audio/ogg; codecsopus });//const blob new Blob(that.luYinAttr.recordedChunks, { type: audio/ogg; codecsopus });//console.log(blob, blob)const audioURL window.URL.createObjectURL(blob);//console.log(audioURL, audioURL)const audio new Audio(audioURL);//console.log(audio,audio)audio.play().catch(err {console.log(Failed to play sound:, err);});}
},
template v-ifisMai truediv class stylebackground:#ffffff; padding:10px 16px;div classlist styletext-align:centertemplate v-for(audioArrayItem , audioArrayIndex) in luYinAttr.audioArrayel-tooltip placementtop :manualtrue :valueaudioArrayItem.tooltipdiv slotcontentspan clickreturnAudioArrayItem(audioArrayItem , audioArrayIndex)移除/span/divdiv stylemargin-bottom:10px; click.preventlistenAudio(audioArrayItem , audioArrayIndex)div styleoverflow:hiddendiv stylefloat:leftp stylebackground: #3975C6; color: #ffffff; padding:0 8px; display:inline-block; border-radius:4px;span classicon iconfont playIcon styledisplay:inline-block; height:20px; font-size:14px; text-align:center;#xe618;/spanspan styleposition:relative; top:-5px; margin:0 5px;template v-for(item , index) in audioArrayItem.timeLengthspan,,/span/template/spanspan{{ audioArrayItem.timeLength }}/span/p/divdiv stylefloat:rightvan-button typeinfo sizemini click.stopreturnAudioArrayItem(audioArrayItem , audioArrayIndex)移除/van-button/div/div/div/el-tooltip/template/divdiv classbyBtn :classluYinAttr.isAn true ? myIsYesAn: myIsNoAn styletext-align: center; font-size:14px; v-longpress{ start: startLongPress, end: endLongPress }p classicon iconfont stylecolor: #3975C6; font-size: 24px;#xe7a6;/pp任务详情 - 按住说话/p/div/div
/template