123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- <template>
- <div :class="sizeClass" >
- <div class="mic" @mousedown="mouseDownHandle" @mouseup="mouseUpHandle" :title="isRecording?'录音中...':'开始录音'">
- <i :class="`el-icon-${isRecording?'microphone':'turn-off-microphone'}`"></i>
- </div>
- </div>
- </template>
- <script>
- import handle from "@/until/handle";
- import {sleep} from "@/until/time";
- import ZLMRTCClient from "@/assets/ZLMRTCClient";
- import CryptoJS from "crypto-js"
- export default {
- name: "microphone.vue",
- props:{
- size: {default:"medium"},
- deviceId: {required:true},
- channelId: {required:true},
- httpsHook: {default:""},
- httpHook: {default:""},
- pushKey: {default:""},
- enableDebug: {default: false}
- },
- data(){
- return {
- iconStyle: "",
- // 音频流
- audioStream: null,
- // record
- mediaRecord: null,
- isRecording: false,
- player: null,
- mediaStream: null,
- audioConnected: false,
- }
- },
- computed: {
- sizeClass() {
- return {
- 'microPhone':true,
- 'large': this.size === 'large', 'medium': this.size === 'medium', 'small': this.size === 'small'}
- }
- },
- beforeMount() {
- this.initAudioApplications();
- },
- beforeDestroy() {
- if(this.player){
- this.player.close();
- this.player = null;
- this.mediaStream = null;
- }
- },
- methods: {
- /**
- * 初始化app应用
- */
- initAudioApplications(){
- this.player = null;
- this.mediaStream = null;
- this.audioConnected = false;
- },
- // 录音按钮按下
- mouseDownHandle() {
- if (this.audioConnected) {
- // 取消静音音频轨道
- if(this.mediaStream){
- let audioStream = this.mediaStream.getAudioTracks();
- audioStream.forEach(track=>{
- track.enabled = false;
- });
- }else{
- this.$message.error("无法获取音频流!");
- }
- }else{
- // 未创建webrtc 连接
- this.startRecordAudio();
- }
- },
- // 录音按钮抬起
- mouseUpHandle() {
- this.isRecording = false;
- // 静音音频轨道
- if (this.audioConnected && this.mediaStream) {
- let audioStream = this.mediaStream.getAudioTracks();
- audioStream.forEach(track => {
- track.enabled = false;
- });
- }
- },
- async startRecordAudio() {
- let err, stream, res;
- if (!this.mediaStream) {
- let httpsHook = this.httpsHook;
- let pushKey = this.pushKey;
- pushKey = CryptoJS.MD5(pushKey);
- let serverHost = `${httpsHook}`
- let app = "rtc";
- let stream = `audio${this.deviceId}`
- // webrtc 请求推流 url
- let zlmSdpUrl = `${serverHost}/index/api/webrtc?app=${app}&stream=${stream}&type=push&sign=${pushKey}`;
- // webrtc 拉流地址
- let playAudioStreamUrl = `${serverHost}/index/api/webrtc?app=${app}&stream=${stream}&type=play`;
- console.log(playAudioStreamUrl);
- let player = new ZLMRTCClient.Endpoint(
- {
- // element: document.getElementById('video'),// video 标签
- debug: true,// 是否打印日志
- zlmsdpUrl: zlmSdpUrl,//流地址
- simulcast: false,
- useCamera: false,
- audioEnable: true,
- videoEnable: false,
- recvOnly: false,
- resolution: {w: 0, h: 0},
- usedatachannel: false,
- }
- );
- this.player = player;
- // console.log(player);
- player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE, async (state) => {// RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
- console.log('当前状态==>', state);
- if (state === 'connected') {
- // 等待1秒
- await sleep(1000);
- [err, res] = await handle(this.sendBroaderCast(stream));
- if (err) {
- this.audioStartFailed(err,`与设备交互错误信息失败${err.message}`)
- this.mediaStream = null;
- return player.close();
- }
- this.audioConnected = true;
- console.log('创建音视频通道成功');
- } else if(state === 'close'){
- this.$message.warning("webrtc连接断开");
- this.audioConnected = false;
- }
- });
- player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR, (e)=> {
- this.audioStartFailed(e,"ICE 协商出错");
- });
- // player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS, function (e) {//获取到了远端流,可以播放
- // console.log('播放成功', e.streams)
- // });
- player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, (e)=> {
- this.audioStartFailed(e,"offer anwser 交换失败");
- });
- player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM, (s)=> {
- console.log("获取到了本地流");
- this.mediaStream = s;
- });
- player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED, (s)=> {
- this.audioStartFailed(s,"获取音频信息失败,请检查是否有麦克风");
- });
- }
- this.isRecording = true;
- },
- async stopRecordAudio() {
- // todo 停止录音
- },
- audioStartFailed(e,msg){
- if(this.enableDebug){
- console.log(msg);
- console.log(e);
- console.log("-------");
- }
- this.$message.error(msg);
- },
- // 通知设备开启推流
- sendBroaderCast(stream) {
- let url = `/api/play/broadcast`
- url += `?deviceId=${this.deviceId}&stream=${stream}`;
- return this.$axios({
- method: 'get',
- url: url
- });
- }
- }
- }
- </script>
- <style scoped>
- .microPhone{
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .microPhone .mic{
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .small{width: 25px;height:25px;font-size: 1.8rem;}
- .medium{width: 40px;height:40px;font-size: 2.2rem;}
- .large{width: 60px;height:60px;font-size: 2.6rem;}
- .huge{width: 80px;height:80px;font-size: 2.8rem;}
- </style>
|