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
其他可以参考屏幕共享
相关文章:
JavaScript实现视频共享
1.视频共享webrtc-master index.html <!DOCTYPE html> <html> <head><script typetext/javascript srchttps://cdn.scaledrone.com/scaledrone.min.js></script><meta charset"utf-8"><meta name"viewport" cont…...
uniapp框架——vue3+uniFilePicker+fastapi实现文件上传(搭建ai项目第二步)
文章目录 ⭐前言💖 小程序系列文章 ⭐uni-file-picker 组件💖 绑定事件💖 uploadFile api💖 自定义上传 ⭐后端fastapi定义上传接口⭐uniapp开启本地请求代理devServer⭐前后端联调⭐总结⭐结束 ⭐前言 大家好,我是ym…...
一篇文章带你入门PHP魔术方法
PHP魔术方法 PHP 中的"魔术方法"是一组特殊的方法,它们在特定情况下自动被调用。这些方法的名称都是以两个下划线(__)开头。魔术方法提供了一种方式来执行各种高级编程技巧,使得对象的行为可以更加灵活和强大。以下是一…...
【数据库系统概论】第6章-关系数据库理论
真别看吧,抄ppt而已啊 文章目录 6.1 引言6.2 规范化6.2.1 函数依赖6.2.2 码6.2.3 范式(Normal Form)6.2.4 BC范式6.2.5 规范化小结 6.1 引言 我们有这样一张表: but 为啥这样设计呢?由此引出怎样设计一个关系数据库…...
算法设计与分析实验报告-贪心算法
校课程的简单实验报告。 算法设计与分析实验报告-递归与分治策略 算法设计与分析实验报告-动态规划算法 算法设计与分析实验报告-贪心算法 dijkstra迪杰斯特拉算法(邻接表法) 算法设计与分析实验报告-回溯法 算法设计与分析实验报告-分支限界法 …...
Unity读取服务器声音文件
Unity读取服务器声音文件 功能1.在网站的根目录放置一个声音文件Alarm01.wav(这个是window系统自带的找不到这个格式的可以直接在C盘搜索)2.在WebManager.cs脚本中添加clipPath、audio、m_downloadClip属性和DownloadSound()函数&…...
掌握ElasticSearch(一):Elasticsearch安装与配置、Kibana安装
文章目录 〇、简介1.Elasticsearch简介2.典型业务场景3.数据采集工具4.名词解释 一、安装1.使用docker(1)创建虚拟网络(2)Elasticsearch安装步骤 2.使用压缩包 二、配置1.目录介绍2.配置文件介绍3.elasticsearch.yml节点配置4.jvm.options堆配置 二、可视化工具Kibana1.介绍2.安…...
《剑指offer》Java版--13.机器人的运动范围(BFS)
剑指offer原题13:机器人的运动范围 地上有一个m行n列的方格。一个机器人从坐标(0,0)的格子开始移动,它每次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格(35,37),因为353…...
基于流程挖掘的保险理赔优化策略实践
引言 在当今日益竞争的商业环境中,保险公司面临着日益增长的业务量和客户期望的挑战。特别是在理赔领域,理赔是保险行业的重要环节,也是保险公司和客户之间最直接的联系点。然而,长周期和繁琐的理赔流程常常给保险公司和投保人带来困扰。因此,如何提供准确且高效的理赔处…...
Docker五 | DockerFile
目录 DockerFile 常用保留字 FROM MAINTAINER RUN EXPOSE WORKDIR USER ENV VOLUME ADD COPY CMD ENTRYPOINT DockerFile案例 前期准备 编写DockerFile文件 运行DockerFile 运行镜像 DockerFile是用来构建Docker镜像的文本文件,是由一条条构建…...
2023年度总结:技术旅程的杨帆远航⛵
文章目录 职业规划与心灵成长 ❤️🔥我的最大收获与成长 💪新年Flag 🚩我的技术发展规划 ⌛对技术行业的深度思考 🤔祝愿 🌇 2023 年对我来说是一个充实而令人难以忘怀的一年。这一年,我在CSDN上发表了 1…...
SpringBoot+AOP+Redis 防止重复请求提交
本文项目基于以下教程的代码版本: https://javaxbfs.blog.csdn.net/article/details/135224261 代码仓库: springboot一些案例的整合_1: springboot一些案例的整合 1、实现步骤 2.引入依赖 我们需要redis、aop的依赖。 <dependency><groupId>org.spr…...
偷流量、端口占用、网络负载高、socket创建释放异常等Android高阶TCP/IP网络问题定位思路
一,背景 通常一些偷流量、端口占用、网络负载高、socket创建释放异常等Android网络相关问题,可以通过使用tcpdump抓tcp/ip报文,来定位。但是tcpdump无进程信息,也没有APK包名信息,无法确认异常的报文来自哪些Apk或者n…...
《人人都能用英语》学习笔记
https://github.com/xiaolai/everyone-can-use-english 核心: 用 What──它究竟是什么?Why──为什么它是那个样子?How──要掌握它、应用它,必须得遵循什么样的步骤? 在运行程序之前,要反复浏览代码&a…...
NFC与ZigBee技术在智慧农业物联网监测系统中的应用
近年来,我国农业物联网技术飞速发展,基于物联网技术的智能农业监测系统有望得到较大规模的推广应用。但传统的物联网农业监测系统其网络结构层次单一,多采用基于有线或无线结构的节点-上位机数据采集模式,节点数据访问模式缺乏灵活…...
k8s-cni网络 10
Flannel vxlan模式跨主机通信原理 在同一个节点上的pod 流量通过cni网桥可以直接进行转发; 在需要跨主机访问时,数据包通过flannel(隧道) 知道另一边的mac地址,就可以拿到另一边的ip地址,然后构建常规的以太网数据包,…...
听GPT 讲Rust源代码--src/tools(27)
File: rust/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs 文件rust/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs的作用是实施Clippy lint规则,检测产生潜在性能问题的字符转换代码,并给出相关建议。 在Rus…...
经济危机下,我们普通人如何翻身?2024创业新风口,适合普通人的创业项目
明年的商业环境会比今年更残酷,不是贩卖危机。旅游行业还在刺激性消费,再过几个月大家就没钱了,估计慢慢也消停。中小微企业资金链断裂,大部分公司倒闭,大批人失业,所以经济恢复需要一个周期。 30年河东&am…...
深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第五节 引用类型复制问题及用克隆接口ICloneable修复
深入浅出图解C#堆与栈 C# Heaping VS Stacking 第五节 引用类型复制问题及用克隆接口ICloneable修复 [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈](https://mp.csdn.net/mdeditor/101021023)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节…...
python中基本元素的pop函数
python中基本元素的pop函数 一、列表List二、元组Tuple三、字典dict四、集合set 一、列表List pop() 根据索引删除并返回被删除的元素,索引默认为-1 a [1, 2, 3, 2, 5] b a.pop() # b5,默认返回最后一个值 print(b) b a.pop(2) # b3,返回a[2] pri…...
小波分解选型指南:如何为你的数据选择最合适的pywt小波函数(db4/haar/symlets对比)
小波分解选型指南:如何为你的数据选择最合适的pywt小波函数(db4/haar/symlets对比) 在信号处理领域,小波分解就像一把瑞士军刀,能够同时提供时域和频域的信息。但面对pywt库中琳琅满目的小波函数——从经典的Haar到复杂…...
工业质检新突破:如何用GLAD扩散模型实现高精度无监督异常检测(附MVTec-AD实测)
工业质检革命:GLAD扩散模型如何重塑无监督缺陷检测 在制造业智能化转型浪潮中,工业质检环节正经历着从人工目检到AI视觉的范式转移。传统基于规则或监督学习的检测系统面临标注成本高、泛化能力弱等痛点,而无监督异常检测技术凭借"零样本…...
从“三次握手”到文件落地:用Wireshark抓包带你彻底搞懂C++ Socket文件传输全过程
从“三次握手”到文件落地:用Wireshark抓包带你彻底搞懂C Socket文件传输全过程 当你在浏览器下载文件时,是否好奇过数据是如何跨越网络准确无误地到达你的电脑?本文将带你用C实现一个完整的TCP文件传输程序,并通过Wireshark抓包工…...
nanobot实操手册:Qwen3-4B模型温度(temperature)、top_p、max_tokens参数详解
nanobot实操手册:Qwen3-4B模型温度(temperature)、top_p、max_tokens参数详解 1. nanobot简介与快速上手 nanobot是一款超轻量级的个人人工智能助手,灵感来源于OpenClaw项目。它最大的特点是代码量极小,仅需约4000行…...
UniHacker:跨平台支持的开源工具快速部署方案
UniHacker:跨平台支持的开源工具快速部署方案 【免费下载链接】UniHacker 为Windows、MacOS、Linux和Docker修补所有版本的Unity3D和UnityHub 项目地址: https://gitcode.com/GitHub_Trending/un/UniHacker UniHacker作为一款专业的开源工具,凭借…...
提升效率:用快马一键生成网络应用用户认证api模块
最近在开发一个网络应用时,遇到了用户认证模块的重复开发问题。每次新建项目都要从头写注册登录逻辑,不仅耗时还容易出错。后来发现了InsCode(快马)平台的智能生成功能,帮我快速解决了这个问题。 用户认证模块的核心需求 网络应用中ÿ…...
AI赋能Spring开发:借助快马平台快速集成Spring AI,打造智能应用
AI赋能Spring开发:借助快马平台快速集成Spring AI,打造智能应用 Spring生态庞大,新技术集成往往需要查阅大量文档。最近我在尝试将Spring AI集成到项目中,发现这个过程比想象中要复杂得多。好在发现了InsCode(快马)平台ÿ…...
LEDPatternLib:非阻塞LED动画库设计与嵌入式实践
1. 项目概述LEDPatternLib 是一款面向嵌入式 LED 动画控制的轻量级、模块化 Arduino 库,专为资源受限的微控制器平台设计。其核心目标并非替代底层驱动,而是构建在成熟硬件抽象层之上的非阻塞(non-blocking)模式动画调度框架。该库…...
图结构AI Agent记忆机制深度解析:小白/程序员必备,收藏学习大模型前沿技术!
图结构AI Agent记忆机制深度解析:小白/程序员必备,收藏学习大模型前沿技术! 本文深入解析了基于图结构的AI Agent记忆机制,揭示了LLM驱动AI Agent面临的三大局限:知识截断、工具 incompetence 和性能饱和。文章强调记…...
【LAMMPS实战】从文献到模拟:精准定位与获取ReaxFF反应力场参数文件
1. 初识ReaxFF反应力场:为什么我们需要它? 第一次接触分子动力学模拟时,我完全被各种力场搞晕了。直到遇到需要模拟化学反应的情况,才发现普通的力场根本不够用。这时候ReaxFF反应力场就像救命稻草一样出现了。简单来说࿰…...
