当前位置:   article > 正文

vue视频直接播放rtsp流;vue视频延迟问题解决;webRTC占cpu太大卡死问题解决;解决webRTC播放卡花屏问题:_webrtcstreamer.prototype.onerror设置

webrtcstreamer.prototype.onerror设置

播放多个视频

  1. <div class="video-box">
  2. <div class="video">
  3. <iframe style="width:100%;height:100%;" name="ddddd" id="iframes" scrolling="auto" :src="videoLeftUrl"></iframe>
  4. </div>
  5. <div class="video">
  6. <iframe style="width:100%;height:100%;" name="ddddd" id="iframes" scrolling="auto" :src="videoRightUrl"></iframe>
  7. </div>
  8. <div class="video">
  9. <iframe style="width:100%;height:100%;" name="ddddd" id="iframes" scrolling="auto" :src="videoRtspUrl"></iframe>
  10. </div>
  11. </div>

js部分其中的item就是rtsp视频流

  1. getShareVideoLeftUrl(item) {
  2. this.videoLeftUrl = `/static/test.html?data=${item}`
  3. },
  4. getShareVideoRightUrl(item) {
  5. this.videoRightUrl = `/static/test.html?data=${item}`
  6. },
  7. getShareVideoRtspUrl(item) {
  8. this.videoRtspUrl = `/static/test.html?data=${item}`
  9. },

public/static/test.html内容

  1. <html>
  2. <head>
  3. <script src="js/webrtcstreamer.js"></script>
  4. <script>
  5. // 接受从vue组件中传过来的参数
  6. let url = location.search; //这一条语句获取了包括问号开始到参数的最后,不包括前面的路径
  7. let params = url.substr(1); //去掉问号
  8. let pa = params.split("&");
  9. let s = new Object();
  10. // 设置后端服务地址
  11. let VIDEOURL = "http://172.18.127.7:8000" //服务视频webrtc
  12. for (let i = 0; i < pa.length; i++) {
  13. s[pa[i].split("=")[0]] = unescape(pa[i].split("=")[1]);
  14. }
  15. console.log(s.data)
  16. window.onload = function() {
  17. webRtcServer = new WebRtcStreamer("video", VIDEOURL);
  18. webRtcServer.connect(s.data);
  19. }
  20. window.onbeforeunload = function() {
  21. webRtcServer.disconnect();
  22. }
  23. </script>
  24. </head>
  25. <body>
  26. <h1 value="da3"></h1>
  27. <video id="video" style="width: 100%;height: 100%;" controls autoplay muted />
  28. </body>
  29. </html>

其中public/static/js/webrtcstreamer.js文件内容如下

  1. var WebRtcStreamer = (function() {
  2. /**
  3. * Interface with WebRTC-streamer API
  4. * @constructor
  5. * @param {string} videoElement - id of the video element tag
  6. * @param {string} srvurl - url of webrtc-streamer (default is current location)
  7. */
  8. var WebRtcStreamer = function WebRtcStreamer (videoElement, srvurl) {
  9. if (typeof videoElement === "string") {
  10. this.videoElement = document.getElementById(videoElement);
  11. } else {
  12. this.videoElement = videoElement;
  13. }
  14. this.srvurl = srvurl || location.protocol+"//"+window.location.hostname+":"+window.location.port;
  15. this.pc = null;
  16. this.pcOptions = { "optional": [{"DtlsSrtpKeyAgreement": true} ] };
  17. this.mediaConstraints = { offerToReceiveAudio: true, offerToReceiveVideo: true };
  18. this.iceServers = null;
  19. this.earlyCandidates = [];
  20. }
  21. WebRtcStreamer.prototype._handleHttpErrors = function (response) {
  22. if (!response.ok) {
  23. throw Error(response.statusText);
  24. }
  25. return response;
  26. }
  27. /**
  28. * Connect a WebRTC Stream to videoElement
  29. * @param {string} videourl - id of WebRTC video stream
  30. * @param {string} audiourl - id of WebRTC audio stream
  31. * @param {string} options - options of WebRTC call
  32. * @param {string} stream - local stream to send
  33. */
  34. WebRtcStreamer.prototype.connect = function(videourl, audiourl, options, localstream) {
  35. this.disconnect();
  36. // getIceServers is not already received
  37. if (!this.iceServers) {
  38. console.log("Get IceServers");
  39. fetch(this.srvurl + "/api/getIceServers")
  40. .then(this._handleHttpErrors)
  41. .then( (response) => (response.json()) )
  42. .then( (response) => this.onReceiveGetIceServers.call(this,response, videourl, audiourl, options, localstream))
  43. .catch( (error) => this.onError("getIceServers " + error ))
  44. } else {
  45. this.onReceiveGetIceServers(this.iceServers, videourl, audiourl, options, localstream);
  46. }
  47. }
  48. /**
  49. * Disconnect a WebRTC Stream and clear videoElement source
  50. */
  51. WebRtcStreamer.prototype.disconnect = function() {
  52. if (this.videoElement) {
  53. this.videoElement.src = "";
  54. }
  55. if (this.pc) {
  56. fetch(this.srvurl + "/api/hangup?peerid="+this.pc.peerid)
  57. .then(this._handleHttpErrors)
  58. .catch( (error) => this.onError("hangup " + error ))
  59. try {
  60. this.pc.close();
  61. }
  62. catch (e) {
  63. console.log ("Failure close peer connection:" + e);
  64. }
  65. this.pc = null;
  66. }
  67. }
  68. /*
  69. * GetIceServers callback
  70. */
  71. WebRtcStreamer.prototype.onReceiveGetIceServers = function(iceServers, videourl, audiourl, options, stream) {
  72. this.iceServers = iceServers;
  73. this.pcConfig = iceServers || {"iceServers": [] };
  74. try {
  75. this.createPeerConnection();
  76. var callurl = this.srvurl + "/api/call?peerid="+ this.pc.peerid+"&url="+encodeURIComponent(videourl);
  77. if (audiourl) {
  78. callurl += "&audiourl="+encodeURIComponent(audiourl);
  79. }
  80. if (options) {
  81. callurl += "&options="+encodeURIComponent(options);
  82. }
  83. if (stream) {
  84. this.pc.addStream(stream);
  85. }
  86. // clear early candidates
  87. this.earlyCandidates.length = 0;
  88. // create Offer
  89. var bind = this;
  90. this.pc.createOffer(this.mediaConstraints).then(function(sessionDescription) {
  91. console.log("Create offer:" + JSON.stringify(sessionDescription));
  92. bind.pc.setLocalDescription(sessionDescription
  93. , function() {
  94. fetch(callurl, { method: "POST", body: JSON.stringify(sessionDescription) })
  95. .then(bind._handleHttpErrors)
  96. .then( (response) => (response.json()) )
  97. .catch( (error) => bind.onError("call " + error ))
  98. .then( (response) => bind.onReceiveCall.call(bind,response) )
  99. .catch( (error) => bind.onError("call " + error ))
  100. }
  101. , function(error) {
  102. console.log ("setLocalDescription error:" + JSON.stringify(error));
  103. } );
  104. }, function(error) {
  105. alert("Create offer error:" + JSON.stringify(error));
  106. });
  107. } catch (e) {
  108. this.disconnect();
  109. alert("connect error: " + e);
  110. }
  111. }
  112. WebRtcStreamer.prototype.getIceCandidate = function() {
  113. fetch(this.srvurl + "/api/getIceCandidate?peerid=" + this.pc.peerid)
  114. .then(this._handleHttpErrors)
  115. .then( (response) => (response.json()) )
  116. .then( (response) => this.onReceiveCandidate.call(this, response))
  117. .catch( (error) => bind.onError("getIceCandidate " + error ))
  118. }
  119. /*
  120. * create RTCPeerConnection
  121. */
  122. WebRtcStreamer.prototype.createPeerConnection = function() {
  123. console.log("createPeerConnection config: " + JSON.stringify(this.pcConfig) + " option:"+ JSON.stringify(this.pcOptions));
  124. this.pc = new RTCPeerConnection(this.pcConfig, this.pcOptions);
  125. var pc = this.pc;
  126. pc.peerid = Math.random();
  127. var bind = this;
  128. pc.onicecandidate = function(evt) { bind.onIceCandidate.call(bind, evt); };
  129. pc.onaddstream = function(evt) { bind.onAddStream.call(bind,evt); };
  130. pc.oniceconnectionstatechange = function(evt) {
  131. console.log("oniceconnectionstatechange state: " + pc.iceConnectionState);
  132. if (bind.videoElement) {
  133. if (pc.iceConnectionState === "connected") {
  134. bind.videoElement.style.opacity = "1.0";
  135. }
  136. else if (pc.iceConnectionState === "disconnected") {
  137. bind.videoElement.style.opacity = "0.25";
  138. }
  139. else if ( (pc.iceConnectionState === "failed") || (pc.iceConnectionState === "closed") ) {
  140. bind.videoElement.style.opacity = "0.5";
  141. } else if (pc.iceConnectionState === "new") {
  142. bind.getIceCandidate.call(bind)
  143. }
  144. }
  145. }
  146. pc.ondatachannel = function(evt) {
  147. console.log("remote datachannel created:"+JSON.stringify(evt));
  148. evt.channel.onopen = function () {
  149. console.log("remote datachannel open");
  150. this.send("remote channel openned");
  151. }
  152. evt.channel.onmessage = function (event) {
  153. console.log("remote datachannel recv:"+JSON.stringify(event.data));
  154. }
  155. }
  156. pc.onicegatheringstatechange = function() {
  157. if (pc.iceGatheringState === "complete") {
  158. const recvs = pc.getReceivers();
  159. recvs.forEach((recv) => {
  160. if (recv.track && recv.track.kind === "video") {
  161. console.log("codecs:" + JSON.stringify(recv.getParameters().codecs))
  162. }
  163. });
  164. }
  165. }
  166. try {
  167. var dataChannel = pc.createDataChannel("ClientDataChannel");
  168. dataChannel.onopen = function() {
  169. console.log("local datachannel open");
  170. this.send("local channel openned");
  171. }
  172. dataChannel.onmessage = function(evt) {
  173. console.log("local datachannel recv:"+JSON.stringify(evt.data));
  174. }
  175. } catch (e) {
  176. console.log("Cannor create datachannel error: " + e);
  177. }
  178. console.log("Created RTCPeerConnnection with config: " + JSON.stringify(this.pcConfig) + "option:"+ JSON.stringify(this.pcOptions) );
  179. return pc;
  180. }
  181. /*
  182. * RTCPeerConnection IceCandidate callback
  183. */
  184. WebRtcStreamer.prototype.onIceCandidate = function (event) {
  185. if (event.candidate) {
  186. if (this.pc.currentRemoteDescription) {
  187. this.addIceCandidate(this.pc.peerid, event.candidate);
  188. } else {
  189. this.earlyCandidates.push(event.candidate);
  190. }
  191. }
  192. else {
  193. console.log("End of candidates.");
  194. }
  195. }
  196. WebRtcStreamer.prototype.addIceCandidate = function(peerid, candidate) {
  197. fetch(this.srvurl + "/api/addIceCandidate?peerid="+peerid, { method: "POST", body: JSON.stringify(candidate) })
  198. .then(this._handleHttpErrors)
  199. .then( (response) => (response.json()) )
  200. .then( (response) => {console.log("addIceCandidate ok:" + response)})
  201. .catch( (error) => this.onError("addIceCandidate " + error ))
  202. }
  203. /*
  204. * RTCPeerConnection AddTrack callback
  205. */
  206. WebRtcStreamer.prototype.onAddStream = function(event) {
  207. console.log("Remote track added:" + JSON.stringify(event));
  208. this.videoElement.srcObject = event.stream;
  209. var promise = this.videoElement.play();
  210. if (promise !== undefined) {
  211. var bind = this;
  212. promise.catch(function(error) {
  213. console.warn("error:"+error);
  214. bind.videoElement.setAttribute("controls", true);
  215. });
  216. }
  217. }
  218. /*
  219. * AJAX /call callback
  220. */
  221. WebRtcStreamer.prototype.onReceiveCall = function(dataJson) {
  222. var bind = this;
  223. console.log("offer: " + JSON.stringify(dataJson));
  224. var descr = new RTCSessionDescription(dataJson);
  225. this.pc.setRemoteDescription(descr
  226. , function() {
  227. console.log ("setRemoteDescription ok");
  228. while (bind.earlyCandidates.length) {
  229. var candidate = bind.earlyCandidates.shift();
  230. bind.addIceCandidate.call(bind, bind.pc.peerid, candidate);
  231. }
  232. bind.getIceCandidate.call(bind)
  233. }
  234. , function(error) {
  235. console.log ("setRemoteDescription error:" + JSON.stringify(error));
  236. });
  237. }
  238. /*
  239. * AJAX /getIceCandidate callback
  240. */
  241. WebRtcStreamer.prototype.onReceiveCandidate = function(dataJson) {
  242. console.log("candidate: " + JSON.stringify(dataJson));
  243. if (dataJson) {
  244. for (var i=0; i<dataJson.length; i++) {
  245. var candidate = new RTCIceCandidate(dataJson[i]);
  246. console.log("Adding ICE candidate :" + JSON.stringify(candidate) );
  247. this.pc.addIceCandidate(candidate
  248. , function() { console.log ("addIceCandidate OK"); }
  249. , function(error) { console.log ("addIceCandidate error:" + JSON.stringify(error)); } );
  250. }
  251. this.pc.addIceCandidate();
  252. }
  253. }
  254. /*
  255. * AJAX callback for Error
  256. */
  257. WebRtcStreamer.prototype.onError = function(status) {
  258. console.log("onError:" + status);
  259. }
  260. return WebRtcStreamer;
  261. })();
  262. if (typeof module !== 'undefined' && typeof module.exports !== 'undefined')
  263. module.exports = WebRtcStreamer;
  264. else
  265. window.WebRtcStreamer = WebRtcStreamer;

这里启用需要下载webRTC

  https://github.com/mpromonet/webrtc-streamer/releases

需要注意的是这里启动不要直接双击而是使用cmd命令启动

 

start 应用名 -o 

一定加上-o否则webRTC占cpu太大 容易卡死


解决卡花屏问题:
在html页面中的webRtcServer.connect(s.data,"","rtptransport=tcp");加上"","rtptransport=tcp"就搞定
  1. <html>
  2. <head>
  3. <script src="js/webrtcstreamer.js"></script>
  4. <script>
  5. // 接受从vue组件中传过来的参数
  6. let url = location.search; //这一条语句获取了包括问号开始到参数的最后,不包括前面的路径
  7. let params = url.substr(1); //去掉问号
  8. let pa = params.split("&");
  9. let s = new Object();
  10. // 设置后端服务地址
  11. let VIDEOURL = "http://172.18.127.7:8000" //服务视频webrtc
  12. for (let i = 0; i < pa.length; i++) {
  13. s[pa[i].split("=")[0]] = unescape(pa[i].split("=")[1]);
  14. }
  15. console.log(s.data)
  16. window.onload = function() {
  17. webRtcServer = new WebRtcStreamer("video", VIDEOURL);
  18. webRtcServer.connect(s.data,"","rtptransport=tcp");
  19. }
  20. window.onbeforeunload = function() {
  21. webRtcServer.disconnect();
  22. }
  23. </script>
  24. </head>
  25. <body>
  26. <h1 value="da3"></h1>
  27. <video id="video" style="width: 100%;height: 100%;" controls autoplay muted />
  28. </body>
  29. </html>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/735493
推荐阅读
相关标签
  

闽ICP备14008679号