使用 WebRtcStreame 播放 实时流rtsp 录像机视频

📅 发布时间:2026/7/4 5:04:59 👁️ 浏览次数:
使用 WebRtcStreame 播放 实时流rtsp 录像机视频
WebRtcStreamer 是一个基于 WebRTC 协议的轻量级开源工具可以在浏览器中直接播放 RTSP 视频流。它利用 WebRTC 的强大功能提供低延迟的视频流播放体验非常适合实时监控和其他视频流应用场景。下载地址这是我csdn的资源webrtc-streamer-v0.7.1双击启动启动后集成到 vue 项目在项目的 public文件夹下创建 webrtcstreamer.js/** * constructor * param {string} videoElement - dom ID * param {string} srvurl - WebRTC 流媒体服务器的 URL默认为当前页面地址 */classWebRtcStreamer{constructor(videoElement,srvurl){if(typeofvideoElementstring){this.videoElementdocument.getElementById(videoElement);}else{this.videoElementvideoElement;}this.srvurlsrvurl||${location.protocol}//${window.location.hostname}:${window.location.port};this.pcnull;// PeerConnection 实例// 媒体约束条件this.mediaConstraints{offerToReceiveAudio:true,offerToReceiveVideo:true,};this.iceServersnull;// ICE 服务器配置this.earlyCandidates[];// 提前收集的候选者}/** * HTTP 错误处理器 * param {Response} response - HTTP 响应 * throws {Error} 当响应不成功时抛出错误 */_handleHttpErrors(response){if(!response.ok){throwError(response.statusText);}returnresponse;}/** * 连接 WebRTC 视频流到指定的 videoElement * param {string} videourl - 视频流 URL * param {string} audiourl - 音频流 URL * param {string} options - WebRTC 通话的选项 * param {MediaStream} localstream - 本地流 * param {string} prefmime - 优先的 MIME 类型 */connect(videourl,audiourl,options,localstream,prefmime){this.disconnect();if(!this.iceServers){console.log(获取 ICE 服务器配置...);fetch(${this.srvurl}/api/getIceServers).then(this._handleHttpErrors).then((response)response.json()).then((response)this.onReceiveGetIceServers(response,videourl,audiourl,options,localstream,prefmime),).catch((error)this.onError(获取 ICE 服务器错误:${error}));}else{this.onReceiveGetIceServers(this.iceServers,videourl,audiourl,options,localstream,prefmime,);}}/** * 断开 WebRTC 视频流并清空 videoElement 的视频源 */disconnect(){if(this.videoElement?.srcObject){this.videoElement.srcObject.getTracks().forEach((track){track.stop();this.videoElement.srcObject.removeTrack(track);});}if(this.pc){fetch(${this.srvurl}/api/hangup?peerid${this.pc.peerid}).then(this._handleHttpErrors).catch((error)this.onError(hangup${error}));try{this.pc.close();}catch(e){console.log(Failure close peer connection:${e});}this.pcnull;}}/** * 获取 ICE 服务器配置的回调 * param {Object} iceServers - ICE 服务器配置 * param {string} videourl - 视频流 URL * param {string} audiourl - 音频流 URL * param {string} options - WebRTC 通话的选项 * param {MediaStream} stream - 本地流 * param {string} prefmime - 优先的 MIME 类型 */onReceiveGetIceServers(iceServers,videourl,audiourl,options,stream,prefmime){this.iceServersiceServers;this.pcConfigiceServers||{iceServers:[]};try{this.createPeerConnection();letcallurl${this.srvurl}/api/call?peerid${this.pc.peerid}url${encodeURIComponent(videourl,)};if(audiourl){callurlaudiourl${encodeURIComponent(audiourl)};}if(options){callurloptions${encodeURIComponent(options)};}if(stream){this.pc.addStream(stream);}this.earlyCandidates.length0;this.pc.createOffer(this.mediaConstraints).then((sessionDescription){// console.log(创建 Offer: ${JSON.stringify(sessionDescription)});if(prefmime!undefined){const[prefkind]prefmime.split(/);constcodecsRTCRtpReceiver.getCapabilities(prefkind).codecs;constpreferredCodecscodecs.filter((codec)codec.mimeTypeprefmime);this.pc.getTransceivers().filter((transceiver)transceiver.receiver.track.kindprefkind).forEach((tcvr){if(tcvr.setCodecPreferences){tcvr.setCodecPreferences(preferredCodecs);}});}this.pc.setLocalDescription(sessionDescription).then((){fetch(callurl,{method:POST,body:JSON.stringify(sessionDescription),}).then(this._handleHttpErrors).then((response)response.json()).then((response)this.onReceiveCall(response)).catch((error)this.onError(调用错误:${error}));}).catch((error)console.log(setLocalDescription error:${JSON.stringify(error)}));}).catch((error)console.log(创建 Offer 失败:${JSON.stringify(error)}));}catch(e){this.disconnect();alert(连接错误:${e});}}/** * 创建 PeerConnection 实例 */createPeerConnection(){console.log(创建 PeerConnection...);this.pcnewRTCPeerConnection(this.pcConfig);this.pc.peeridMath.random();// 生成唯一的 peerid// 监听 ICE 候选者事件this.pc.onicecandidate(evt)this.onIceCandidate(evt);this.pc.onaddstream(evt)this.onAddStream(evt);this.pc.oniceconnectionstatechange(){if(this.videoElement){if(this.pc.iceConnectionStateconnected){this.videoElement.style.opacity1.0;}elseif(this.pc.iceConnectionStatedisconnected){this.videoElement.style.opacity0.25;}elseif([failed,closed].includes(this.pc.iceConnectionState)){this.videoElement.style.opacity0.5;}elseif(this.pc.iceConnectionStatenew){this.getIceCandidate();}}};returnthis.pc;}onAddStream(event){console.log(Remote track added:${JSON.stringify(event)});this.videoElement.srcObjectevent.stream;constpromisethis.videoElement.play();if(promise!undefined){promise.catch((error){console.warn(error:${error});this.videoElement.setAttribute(controls,true);});}}onIceCandidate(event){if(event.candidate){if(this.pc.currentRemoteDescription){this.addIceCandidate(this.pc.peerid,event.candidate);}else{this.earlyCandidates.push(event.candidate);}}else{console.log(End of candidates.);}}/** * 添加 ICE 候选者到 PeerConnection * param {RTCIceCandidate} candidate - ICE 候选者 */addIceCandidate(peerid,candidate){fetch(${this.srvurl}/api/addIceCandidate?peerid${peerid},{method:POST,body:JSON.stringify(candidate),}).then(this._handleHttpErrors).catch((error)this.onError(addIceCandidate${error}));}/** * 处理 WebRTC 通话的响应 * param {Object} message - 来自服务器的响应消息 */onReceiveCall(dataJson){constdescrnewRTCSessionDescription(dataJson);this.pc.setRemoteDescription(descr).then((){while(this.earlyCandidates.length){constcandidatethis.earlyCandidates.shift();this.addIceCandidate(this.pc.peerid,candidate);}this.getIceCandidate();}).catch((error)console.log(设置描述文件失败:${JSON.stringify(error)}));}getIceCandidate(){fetch(${this.srvurl}/api/getIceCandidate?peerid${this.pc.peerid}).then(this._handleHttpErrors).then((response)response.json()).then((response)this.onReceiveCandidate(response)).catch((error)this.onError(getIceCandidate${error}));}onReceiveCandidate(dataJson){if(dataJson){dataJson.forEach((candidateData){constcandidatenewRTCIceCandidate(candidateData);this.pc.addIceCandidate(candidate).catch((error)console.log(addIceCandidate error:${JSON.stringify(error)}));});}}/** * 错误处理器 * param {string} message - 错误信息 */onError(status){console.error(WebRTC 错误:${status});}}exportdefaultWebRtcStreamer;组件中使用templatedivvideo idvideocontrols muted autoplay/videobutton clickstartStream开始播放/buttonbutton clickstopStream停止播放/button/div/templatescriptimportWebRtcStreamerfrom../../../public/webrtcstreamer;exportdefault{name:VideoStreamer,data(){return{webRtcServer:null,};},methods:{startStream(){constsrvurl127.0.0.1:8000;this.webRtcServernewWebRtcStreamer(video,${location.protocol}//${srvurl});【 替换为你的流地址 】constvideoPathrtsp://aabcdefghigklmnopqrstuvwxyzm;this.webRtcServer.connect(videoPath);},stopStream(){if(this.webRtcServer){this.webRtcServer.disconnect();// 销毁}},},};/scriptstylevideo{width:100%;height:100%;object-fit:fill;}/style效果图