当前位置: 首页 > news >正文

哪个网站可以做免费宣传医院网站怎么做

哪个网站可以做免费宣传,医院网站怎么做,息县网站建设公司,电子商务网站是电子商务企业WebRTC#xff08;Web Real-Time Communication#xff09;协议 WebRTC#xff08;Web Real-Time Communication#xff09;是一种支持浏览器和移动应用程序之间进行 实时音频、视频和数据通信 的协议。它使得开发者能够在浏览器中实现高质量的 P2P#xff08;点对点Web Real-Time Communication协议 WebRTCWeb Real-Time Communication是一种支持浏览器和移动应用程序之间进行 实时音频、视频和数据通信 的协议。它使得开发者能够在浏览器中实现高质量的 P2P点对点实时通信而无需安装插件或第三方软件。WebRTC 主要用于视频通话、语音聊天、在线协作和数据传输等应用场景。 核心功能 WebRTC 提供了以下几个关键功能 音视频通信WebRTC 支持通过浏览器进行音频和视频的实时传输用户之间可以进行高质量的语音和视频通话。P2P 数据传输WebRTC 不仅支持音视频流还支持点对点的数据通道Data Channel传输适合进行文件传输、屏幕共享和实时协作。低延迟WebRTC 专门优化了数据传输过程以减少通信中的延迟使得实时通信更加顺畅。 工作原理 WebRTC 使用了一系列底层协议和技术来实现点对点通信。WebRTC 的工作流程通常包括以下几个关键步骤 建立连接Signaling 在 WebRTC 中信令Signaling 是客户端用于交换通信所需的元数据如网络信息、音视频编解码信息、媒体能力等的一种过程。信令不是 WebRTC 协议的一部分但它是 WebRTC 通信的必要步骤。信令的内容包括协商媒体音视频格式、网络路径、设备信息等。通常信令使用 WebSockets、HTTP 或其他协议进行实现。信令过程包括 Offer提议发起方创建会话请求发送给接收方。Answer应答接收方回应发起方的请求确认会话设置。ICE candidatesICE 候选者每个端点通过收集网络候选地址来交换以帮助建立最佳的 P2P 连接。 网络连接ICE、STUN 和 TURN ICEInteractive Connectivity Establishment用于在 NAT 后的网络环境中建立端到端的连接。ICE 是 WebRTC 连接的关键组成部分它帮助客户端发现并连接到彼此。STUNSession Traversal Utilities for NATSTUN 服务器帮助客户端了解自己在 NAT 后的公网 IP 地址。TURNTraversal Using Relays around NATTURN 服务器在 P2P 连接无法直接建立时提供数据转发服务确保通信的可靠性。TURN 作为最后的解决方案通常会导致更高的延迟因此只有在需要时才使用。 媒体流传输RTP/RTCP RTPReal-Time Transport ProtocolRTP 是 WebRTC 用于音频和视频流的传输协议。它允许在网络中实时地传输数据包并为这些数据包添加时间戳确保音视频数据的正确顺序。RTCPReal-Time Control ProtocolRTCP 用于监控 RTP 会话的质量并提供流控制和同步。 数据传输DataChannel RTCDataChannelWebRTC 支持数据通道DataChannel使得浏览器间可以通过 P2P 传输任意数据包括文本、文件、图像等。数据通道提供了低延迟的点对点数据传输能力常用于文件传输、屏幕共享等应用。 关键技术 WebRTC 由多种技术组成其中最重要的包括 getUserMedia用于获取用户的音频和视频输入设备如麦克风和摄像头的权限。它会返回一个包含音视频流的对象。 navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream {// 显示视频流const videoElement document.getElementById(my-video);videoElement.srcObject stream;}).catch(error console.log(Error accessing media devices: , error));RTCPeerConnection用于建立、维护和管理 P2P 连接。它负责处理网络连接、音视频编解码、带宽管理等任务。 const peerConnection new RTCPeerConnection(configuration); peerConnection.addStream(localStream); // 添加本地音视频流// 建立连接后发送媒体流 peerConnection.createOffer().then(offer peerConnection.setLocalDescription(offer)).then(() {// 将 offer 发送给接收方});RTCDataChannel用于建立点对点的数据传输通道可以传输任意类型的数据。 javascript复制编辑const dataChannel peerConnection.createDataChannel(chat); dataChannel.onopen () console.log(Data channel open); dataChannel.onmessage (event) console.log(Received message: , event.data);// 发送数据 dataChannel.send(Hello, WebRTC!);应用场景 视频通话WebRTC 可以用于构建视频会议应用如 Zoom、Google Meet 等。语音通话WebRTC 支持语音通话广泛应用于 IP 电话、语音助手等。文件传输通过 RTCDataChannelWebRTC 可以用于点对点的文件传输。实时协作WebRTC 用于多人在线编辑、白板共享等实时协作工具。直播WebRTC 可以支持低延迟的视频直播适用于游戏直播、网络教学等领域。 实现过程 1. 获取音视频流getUserMedia getUserMedia 是 WebRTC 中用于访问用户音频和视频设备的 API。通过它你可以获取麦克风和摄像头的权限从而获取用户的音视频流。 示例获取视频和音频流 navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream {// 获取视频流后可以将其显示在视频标签上const videoElement document.getElementById(localVideo);videoElement.srcObject stream;// 创建 RTCPeerConnection 实例将在后面讨论const peerConnection new RTCPeerConnection();// 将本地流添加到连接stream.getTracks().forEach(track peerConnection.addTrack(track, stream));}).catch(error {console.error(Error accessing media devices., error);});getUserMedia请求用户设备的音视频流。返回的 MediaStream 可以用于显示、录制或传输。 2. 创建点对点连接RTCPeerConnection WebRTC 使用 RTCPeerConnection 来管理媒体流的传输。它代表了与另一个客户端的点对点连接。 示例创建 RTCPeerConnection 并添加本地流 const peerConnection new RTCPeerConnection({iceServers: [{ urls: stun:stun.l.google.com:19302 } // 使用 STUN 服务器] });// 添加本地流到连接 navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream {const localVideo document.getElementById(localVideo);localVideo.srcObject stream;stream.getTracks().forEach(track peerConnection.addTrack(track, stream));});STUN 服务器STUNSession Traversal Utilities for NAT帮助客户端发现自己的公共 IP 地址用于 NAT 穿透。 3. 信令交换Signal WebRTC 协议并不直接定义信令交换的方式因此你需要自己实现信令交换。信令过程用于交换连接的元数据如会话描述SDP和 ICE 候选者等。 创建 Offer发起方 peerConnection.createOffer().then(offer {return peerConnection.setLocalDescription(offer); // 设置本地 SDP}).then(() {// 将 offer 发送给对方通过信令服务器signalingServer.send({ type: offer, offer: peerConnection.localDescription });});SDPSession Description Protocol描述了音视频流的编码、传输等信息。 设置 Answer接收方 接收方收到 Offer 后创建 Answer 并回复 signalingServer.on(offer, offer {peerConnection.setRemoteDescription(new RTCSessionDescription(offer)).then(() peerConnection.createAnswer()).then(answer {return peerConnection.setLocalDescription(answer); // 设置本地 SDP}).then(() {// 将 answer 发送给发起方signalingServer.send({ type: answer, answer: peerConnection.localDescription });}); });交换 ICE 候选者 在连接过程中客户端会收集并交换 ICE 候选者候选网络路径。这些候选者用于寻找最佳的连接路径。 peerConnection.onicecandidate event {if (event.candidate) {// 发送 ICE 候选者到对方signalingServer.send({ type: ice-candidate, candidate: event.candidate });} };// 接收对方的 ICE 候选者 signalingServer.on(ice-candidate, candidate {peerConnection.addIceCandidate(new RTCIceCandidate(candidate)); });建立连接并处理媒体流 当信令交换完成并且 ICE 候选者交换完毕后WebRTC 将会建立一个完整的点对点连接音视频流会开始传输。 示例显示远端视频流 peerConnection.ontrack event {const remoteVideo document.getElementById(remoteVideo);remoteVideo.srcObject event.streams[0]; // 获取远程流并显示 };5. 数据通道RTCDataChannel WebRTC 还支持 RTCDataChannel用于在两个客户端之间进行低延迟的点对点数据传输例如文件传输、聊天信息等。 示例创建并使用数据通道 const dataChannel peerConnection.createDataChannel(chat);// 监听数据通道的消息 dataChannel.onmessage event {console.log(Received message:, event.data); };// 发送数据 dataChannel.send(Hello from WebRTC!);6. 断开连接 当通信结束时你可以通过关闭 PeerConnection 来断开连接并释放资源。 peerConnection.close();WebRTC-Streamer开源项目 项目介绍 WebRTC-Streamer 是一个开源工具集旨在简化实时音视频数据流的传输与集成主要通过 WebRTC 技术实现低延迟的音视频流传输。开发者无需深入理解复杂的底层协议即可轻松将实时音视频功能集成到自己的应用中。该项目特别设计了高效的音视频流处理功能支持多种数据来源如 V4L2 捕获设备、RTSP 流、屏幕捕捉 等适用于多种实时传输场景。 快速启动 WebRTC-Streamer 提供了简便的集成方式。以下是一个通过 HTML 和 JavaScript 快速搭建基本实时音视频流服务的示例代码 html headscript srclibs/adapter.min.js/scriptscript srcwebrtcstreamer.js/script /head body script var webRtcServer; window.onload function() {webRtcServer new WebRtcStreamer(document.getElementById(video), location.protocol// location.hostname :8000);webRtcServer.connect(rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov); } window.onbeforeunload function() {if (webRtcServer ! null) {webRtcServer.disconnect();} } /script video idvideo controls autoplay muted/video /body /html代码解析 引入了 adapter.min.js 和 webrtcstreamer.js 两个必要的 JavaScript 库。创建一个 WebRtcStreamer 实例指定本地服务器地址及目标 RTSP 视频流地址。页面加载时自动连接至 RTSP 流播放视频。页面卸载时断开连接释放资源。 应用案例与最佳实践 示例 1直播演示 使用 WebRTC-Streamer 可以通过简化的 Web 组件方式轻松展示来自 RTSP 源的实时视频流。 webrtc-streamer urlrtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov示例 2地图上的直播流 配合 Google Map APIWebRTC-Streamer 可以在地图上显示多个实时视频流适用于 监控、交通管理 等领域。 其它生态项目 WebRTC-Streamer 还支持一系列相关生态项目以扩展其功能和适用范围 webrtc-streamer-card为 Home Assistant 提供的卡片插件允许从 WebRTC-Streamer 服务中拉取零延迟视频流适用于智能家居。rpi-webrtc-streamer面向 树莓派 系列微控制器的 WebRTC 流媒体软件包支持在边缘设备上实现高效的音视频处理。Live555 Integration通过整合 Live555 Media Server增强 WebRTC-Streamer 在处理非标准音视频格式方面的能力扩展其应用场景。 附录WebRTC-Streamer项目地址 https://gitcode.com/gh_mirrors/we/webrtc-streamer/?utm_sourceartical_gitcodeindexbottomtypecardwebUrlisLogin1 附录webrtcstreamer.js源码 // webrtcstreamer.js var WebRtcStreamer (function() {/** * Interface with WebRTC-streamer API* constructor* param {string} videoElement - id of the video element tag* param {string} srvurl - url of webrtc-streamer (default is current location)*/var WebRtcStreamer function WebRtcStreamer (videoElement, srvurl) {if (typeof videoElement string) {this.videoElement document.getElementById(videoElement);} else {this.videoElement videoElement;}this.srvurl srvurl || location.protocol//window.location.hostname:window.location.port;this.pc null; this.mediaConstraints { offerToReceiveAudio: true, offerToReceiveVideo: true };this.iceServers null;this.earlyCandidates [];}WebRtcStreamer.prototype._handleHttpErrors function (response) {if (!response.ok) {throw Error(response.statusText);}return response;}/** * Connect a WebRTC Stream to videoElement * param {string} videourl - id of WebRTC video stream* param {string} audiourl - id of WebRTC audio stream* param {string} options - options of WebRTC call* param {string} stream - local stream to send*/WebRtcStreamer.prototype.connect function(videourl, audiourl, options, localstream) {this.disconnect();// getIceServers is not already receivedif (!this.iceServers) {console.log(Get IceServers);fetch(this.srvurl /api/getIceServers).then(this._handleHttpErrors).then( (response) (response.json()) ).then( (response) this.onReceiveGetIceServers(response, videourl, audiourl, options, localstream)).catch( (error) this.onError(getIceServers error ))} else {this.onReceiveGetIceServers(this.iceServers, videourl, audiourl, options, localstream);}}/** * Disconnect a WebRTC Stream and clear videoElement source*/WebRtcStreamer.prototype.disconnect function() { 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.pc null;}} /** GetIceServers callback*/WebRtcStreamer.prototype.onReceiveGetIceServers function(iceServers, videourl, audiourl, options, stream) {this.iceServers iceServers;this.pcConfig iceServers || {iceServers: [] };try { this.createPeerConnection();var callurl this.srvurl /api/call?peerid this.pc.peerid url encodeURIComponent(videourl);if (audiourl) {callurl audiourlencodeURIComponent(audiourl);}if (options) {callurl optionsencodeURIComponent(options);}if (stream) {this.pc.addStream(stream);}// clear early candidatesthis.earlyCandidates.length 0;// create Offerthis.pc.createOffer(this.mediaConstraints).then((sessionDescription) {console.log(Create offer: JSON.stringify(sessionDescription));this.pc.setLocalDescription(sessionDescription).then(() {fetch(callurl, { method: POST, body: JSON.stringify(sessionDescription) }).then(this._handleHttpErrors).then( (response) (response.json()) ).catch( (error) this.onError(call error )).then( (response) this.onReceiveCall(response) ).catch( (error) this.onError(call error ))}, (error) {console.log (setLocalDescription error: JSON.stringify(error)); });}, (error) { alert(Create offer error: JSON.stringify(error));});} catch (e) {this.disconnect();alert(connect error: e);} }WebRtcStreamer.prototype.getIceCandidate function() {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 ))}/** create RTCPeerConnection */WebRtcStreamer.prototype.createPeerConnection function() {console.log(createPeerConnection config: JSON.stringify(this.pcConfig));this.pc new RTCPeerConnection(this.pcConfig);var pc this.pc;pc.peerid Math.random(); pc.onicecandidate (evt) this.onIceCandidate(evt);pc.onaddstream (evt) this.onAddStream(evt);pc.oniceconnectionstatechange (evt) { console.log(oniceconnectionstatechange state: pc.iceConnectionState);if (this.videoElement) {if (pc.iceConnectionState connected) {this.videoElement.style.opacity 1.0;} else if (pc.iceConnectionState disconnected) {this.videoElement.style.opacity 0.25;} else if ( (pc.iceConnectionState failed) || (pc.iceConnectionState closed) ) {this.videoElement.style.opacity 0.5;} else if (pc.iceConnectionState new) {this.getIceCandidate();}}}pc.ondatachannel function(evt) { console.log(remote datachannel created:JSON.stringify(evt));evt.channel.onopen function () {console.log(remote datachannel open);this.send(remote channel openned);}evt.channel.onmessage function (event) {console.log(remote datachannel recv:JSON.stringify(event.data));}}pc.onicegatheringstatechange function() {if (pc.iceGatheringState complete) {const recvs pc.getReceivers();recvs.forEach((recv) {if (recv.track recv.track.kind video) {console.log(codecs: JSON.stringify(recv.getParameters().codecs))}});}}try {var dataChannel pc.createDataChannel(ClientDataChannel);dataChannel.onopen function() {console.log(local datachannel open);this.send(local channel openned);}dataChannel.onmessage function(evt) {console.log(local datachannel recv:JSON.stringify(evt.data));}} catch (e) {console.log(Cannor create datachannel error: e);} console.log(Created RTCPeerConnnection with config: JSON.stringify(this.pcConfig) );return pc;}/** RTCPeerConnection IceCandidate callback*/WebRtcStreamer.prototype.onIceCandidate function (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.);}}WebRtcStreamer.prototype.addIceCandidate function(peerid, candidate) {fetch(this.srvurl /api/addIceCandidate?peeridpeerid, { method: POST, body: JSON.stringify(candidate) }).then(this._handleHttpErrors).then( (response) (response.json()) ).then( (response) {console.log(addIceCandidate ok: response)}).catch( (error) this.onError(addIceCandidate error ))}/** RTCPeerConnection AddTrack callback*/WebRtcStreamer.prototype.onAddStream function(event) {console.log(Remote track added: JSON.stringify(event));this.videoElement.srcObject event.stream;var promise this.videoElement.play();if (promise ! undefined) {promise.catch((error) {console.warn(error:error);this.videoElement.setAttribute(controls, true);});}}/** AJAX /call callback*/WebRtcStreamer.prototype.onReceiveCall function(dataJson) {console.log(offer: JSON.stringify(dataJson));var descr new RTCSessionDescription(dataJson);this.pc.setRemoteDescription(descr).then(() { console.log (setRemoteDescription ok);while (this.earlyCandidates.length) {var candidate this.earlyCandidates.shift();this.addIceCandidate(this.pc.peerid, candidate); }this.getIceCandidate()}, (error) { console.log (setRemoteDescription error: JSON.stringify(error)); });} /** AJAX /getIceCandidate callback*/WebRtcStreamer.prototype.onReceiveCandidate function(dataJson) {console.log(candidate: JSON.stringify(dataJson));if (dataJson) {for (var i0; idataJson.length; i) {var candidate new RTCIceCandidate(dataJson[i]);console.log(Adding ICE candidate : JSON.stringify(candidate) );this.pc.addIceCandidate(candidate).then( () { console.log (addIceCandidate OK); }, (error) { console.log (addIceCandidate error: JSON.stringify(error)); } );}this.pc.addIceCandidate();}}/** AJAX callback for Error*/WebRtcStreamer.prototype.onError function(status) {console.log(onError: status);}return WebRtcStreamer;})();if (typeof window ! undefined typeof window.document ! undefined) {window.WebRtcStreamer WebRtcStreamer;}if (typeof module ! undefined typeof module.exports ! undefined) {module.exports WebRtcStreamer;}
http://www.pierceye.com/news/679665/

相关文章:

  • 公司网站运营维护单位温州h5建站
  • 做网站想注册商标是哪一类网站上线具体流程
  • 如何让网站自适应屏幕北京做网站哪个公司好
  • 个人网站建设简历网站路径怎么做
  • 学做面包到什么网站企业网站都没的百度快照咋办
  • 手机网站建设视频教程安徽建站之星
  • 做网站专题页的字大小是多少购物商城排名
  • 门窗东莞网站建设技术支持海口快速建站模板
  • 公司网站制作第三方网站浮窗制作
  • 网站需要服务器吗?万州网站建设
  • 网站关键词可以修改吗做响应式网站字体需要响应么
  • 公司网站设计怎么做农家乐联盟网站
  • 普通网站报价多少扬中论坛网
  • 提供邢台做wap网站网站开发怎么进行数据库连接
  • 足球网站网站建设东莞网上销售网站建设
  • 响应式网站手机蓝翔老师做的网站
  • 公司网站建设维护合同中德生态园网站定制
  • 网站建设实训结论站长查询工具
  • 做电影网站要很大的主机空间吗苏州网站推广如何
  • 网站维护内容及费用网站详细设计
  • 国产手机做系统下载网站七牛云做wordpress图床
  • 营销型网站建设网站百度文库账号登录入口
  • 医疗网站建设资讯国内十大游戏公司排名
  • 江苏网站建设网络公司男做基视频网站
  • 网站建设培训公司排名客户管理软件免费版
  • 甘肃省建设工程网上投标网站好玩的网游
  • 大学生网站建设课程总结唐四薪php网站开发答案
  • 郑州的网站建设公司有哪些企业策划案
  • 查询域名网站苏州专业网站seo推广
  • 游戏网站建设计划书梦织做网站