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

JavaScript实现视频共享

1.视频共享webrtc-master

index.html

<!DOCTYPE html>
<html>
<head><script type='text/javascript' src='https://cdn.scaledrone.com/scaledrone.min.js'></script><meta charset="utf-8"><meta name="viewport" content="width=device-width"><style>body {display: flex;height: 100vh;margin: 0;align-items: center;justify-content: center;padding: 0 50px;font-family: -apple-system, BlinkMacSystemFont, sans-serif;}video {max-width: calc(50% - 100px);margin: 0 50px;box-sizing: border-box;border-radius: 2px;padding: 0;box-shadow: rgba(156, 172, 172, 0.2) 0px 2px 2px, rgba(156, 172, 172, 0.2) 0px 4px 4px, rgba(156, 172, 172, 0.2) 0px 8px 8px, rgba(156, 172, 172, 0.2) 0px 16px 16px, rgba(156, 172, 172, 0.2) 0px 32px 32px, rgba(156, 172, 172, 0.2) 0px 64px 64px;}.copy {position: fixed;top: 10px;left: 50%;transform: translateX(-50%);font-size: 16px;color: rgba(0, 0, 0, 0.5);}</style>
</head>
<body><div class="copy">Send your URL to a friend to start a video call</div><video id="localVideo" autoplay muted></video><video id="remoteVideo" autoplay></video><script src="script.js"></script>
</body>
</html>

script.js

// Generate random room name if needed
if (!location.hash) {location.hash = Math.floor(Math.random() * 0xFFFFFF).toString(16);
}
const roomHash = location.hash.substring(1);// TODO: Replace with your own channel ID
const drone = new ScaleDrone('yiS12Ts5RdNhebyM');
// Room name needs to be prefixed with 'observable-'
const roomName = 'observable-' + roomHash;
const configuration = {iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
};
let room;
let pc;function onSuccess() {};
function onError(error) {console.error(error);
};drone.on('open', error => {if (error) {return console.error(error);}room = drone.subscribe(roomName);room.on('open', error => {if (error) {onError(error);}});// We're connected to the room and received an array of 'members'// connected to the room (including us). Signaling server is ready.room.on('members', members => {console.log('MEMBERS', members);// If we are the second user to connect to the room we will be creating the offerconst isOfferer = members.length === 2;startWebRTC(isOfferer);});
});// Send signaling data via Scaledrone
function sendMessage(message) {drone.publish({room: roomName,message});
}function startWebRTC(isOfferer) {pc = new RTCPeerConnection(configuration);// 'onicecandidate' notifies us whenever an ICE agent needs to deliver a// message to the other peer through the signaling serverpc.onicecandidate = event => {if (event.candidate) {sendMessage({'candidate': event.candidate});}};// If user is offerer let the 'negotiationneeded' event create the offerif (isOfferer) {pc.onnegotiationneeded = () => {pc.createOffer().then(localDescCreated).catch(onError);}}// When a remote stream arrives display it in the #remoteVideo elementpc.ontrack = event => {const stream = event.streams[0];if (!remoteVideo.srcObject || remoteVideo.srcObject.id !== stream.id) {remoteVideo.srcObject = stream;}};navigator.mediaDevices.getUserMedia({audio: true,video: true,}).then(stream => {// Display your local video in #localVideo elementlocalVideo.srcObject = stream;// Add your stream to be sent to the conneting peerstream.getTracks().forEach(track => pc.addTrack(track, stream));}, onError);// Listen to signaling data from Scaledroneroom.on('data', (message, client) => {// Message was sent by usif (client.id === drone.clientId) {return;}if (message.sdp) {// This is called after receiving an offer or answer from another peerpc.setRemoteDescription(new RTCSessionDescription(message.sdp), () => {// When receiving an offer lets answer itif (pc.remoteDescription.type === 'offer') {pc.createAnswer().then(localDescCreated).catch(onError);}}, onError);} else if (message.candidate) {// Add the new ICE candidate to our connections remote descriptionpc.addIceCandidate(new RTCIceCandidate(message.candidate), onSuccess, onError);}});
}function localDescCreated(desc) {pc.setLocalDescription(desc,() => sendMessage({'sdp': pc.localDescription}),onError);
}

See more:

  • Live demo

  • Tutorial

其他可以参考屏幕共享 

http://www.lryc.cn/news/269266.html

相关文章:

  • uniapp框架——vue3+uniFilePicker+fastapi实现文件上传(搭建ai项目第二步)
  • 一篇文章带你入门PHP魔术方法
  • 【数据库系统概论】第6章-关系数据库理论
  • 算法设计与分析实验报告-贪心算法
  • Unity读取服务器声音文件
  • 掌握ElasticSearch(一):Elasticsearch安装与配置、Kibana安装
  • 《剑指offer》Java版--13.机器人的运动范围(BFS)
  • 基于流程挖掘的保险理赔优化策略实践
  • Docker五 | DockerFile
  • 2023年度总结:技术旅程的杨帆远航⛵
  • SpringBoot+AOP+Redis 防止重复请求提交
  • 偷流量、端口占用、网络负载高、socket创建释放异常等Android高阶TCP/IP网络问题定位思路
  • 《人人都能用英语》学习笔记
  • NFC与ZigBee技术在智慧农业物联网监测系统中的应用
  • k8s-cni网络 10
  • 听GPT 讲Rust源代码--src/tools(27)
  • 经济危机下,我们普通人如何翻身?2024创业新风口,适合普通人的创业项目
  • 深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第五节 引用类型复制问题及用克隆接口ICloneable修复
  • python中基本元素的pop函数
  • MPLS动态协议LDP配置示例
  • JS调用栈:为何会栈溢出
  • 代码随想Day52 | 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组
  • 使用 pytest 相关特性重构 appium_helloworld
  • 猪目标检测数据集VOC格式600张
  • Pandas中concat的用法
  • 【C++】引用详解
  • 平时的一些思考内容
  • AIGC时代下,结合ChatGPT谈谈儿童教育
  • Java中的锁(一)
  • CSS-SVG-环形进度条