站在巨人的肩膀上,总是简单一些,但是看文档还有写这些demo还是用了1天的时间

电脑端:

本地窗口

远程窗口切换

手机端:

       

源码:server部分用了php,换成 java 或  python 都是可以的

<?phpheader("Content-type:text/html;charset=utf8");//获取room 和 title$room = @$_GET["room"];$title = @$_GET["title"];$uid = time(); //访问时间设置为uid//获取roomtokenif(empty($room)||empty($title)){echo "failure";exit;}$room = "zt".$room;$uid = "ztu".$uid;$expireTime = time()+60*60*24; //1天后过期//test$appid = "七牛appid"; //申请地址:https://doc.qnsdk.com/rtn$secretKey = "七牛sk";$accessKey = "七牛ak";//base64  以下为php版校验keyfunction base64_urlSafeEncode($data) {$find = array('+', '/');$replace = array('-', '_');return str_replace($find, $replace, base64_encode($data));}  //data$tokenDesc = array('appId' => $appid,'roomName' => $room,'userId' => $uid,'expireAt' => $expireTime,'permission' => "user");$tokenDescJson = json_encode($tokenDesc);$encodedTokenDesc = base64_urlSafeEncode($tokenDescJson);$sign = hash_hmac('sha1', $encodedTokenDesc, $secretKey, TRUE);$encodedSign = base64_urlSafeEncode($sign);$roomToken = $accessKey.":".$encodedSign.":".$encodedTokenDesc;
?>
<html>
<head><title><?php echo $title; ?>-视频会议</title><meta name="decorator" content="default"/><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"><style type="text/css">body{position: relative;margin:0;padding:0;overflow:hidden;background-color:#212121;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*{box-sizing:border-box;margin: 0px;padding: 0px;}html,body{width: 100%;height: 100%;}.bigd{width: 100%;height: 100%}.title{position: absolute;left: 0px; top: 10px; color: #fff; font-size: 14px; width:100%; text-align:center; }.fqr{position: absolute;right: 10px; top: 10px; color: #fff; font-size: 14px;}.wjt{outline: none;width: 50px; height:50px; border-radius: 50px; border: none; background: url("./wjt.png")  no-repeat; background-size: 50px 50px;position: absolute;bottom: 10px; left: 48%;}.gd{outline: none;width: 50px; height:50px; border-radius: 50px; border: none; background: url("./gd.png")  no-repeat; background-size: 50px 50px;position: absolute;bottom: 10px; left: 48%;}.mylist{width: 100%;height: 5rem;position: absolute;left: 0px;bottom: 70px;}.list{display: block; height: 5rem;}.list .one{width: 100px;height: 100%; margin-left: 10px; float: left; position: relative;background-color: #4a4a4a; cursor: pointer}.one_video{width: 100%; height: 100%;}.one_text{position: absolute; left: 0px; width: 100%;bottom: 5px;width: 100%; text-align: center; color: #fff;font-size: 12px;}#share-2{position: absolute;left: 10px; bottom: 10px;}video{width:100%; height:100%};audio{visibility:hidden}.max{position: fixed!important; z-index: -1!important;left: 0px!important; top: 0px!important; width: 100%!important; height: 100%!important;bottom: auto!important;background-color:#212121!important;}.max .one_text{display:none;}</style>
</head>
<body onbeforeunload="checkLeave()"><!--房间标题-->
<div class="title"><?php echo $title; ?></div>
<!--挂断按钮-->
<button class="wjt" onclick="myleave(this)"></button>
<!--已在线人-->
<div class="mylist"><div class="list"><div class="one max" onclick="swithDialog('local')"><div class="one_video" id="videolocal" ></div><div class="one_text">本机</div></div></div>
</div>
<!--分享-->
<script type="text/javascript" src="./jquery-1.10.2.js"></script>
<link rel="stylesheet" href="./share.min.css" />
<script type="text/javascript" src="./jquery.share.min.js?V4"></script>
<div id="share-2"></div>
<script type="text/javascript">
if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) { } else {$('#share-2').share({sites: ['qq', 'weibo','wechat']});
}
</script>
<script type="text/javascript" src="./scrollBar.js"></script>
<script type="text/javascript" src="./pili-rtc-web.js"></script>
<script>var RoomToken = '<?php echo $roomToken; ?>';// 确认引入成功console.log("current version", QNRTC.version);var myRoom_this = null;// 这里采用的是 async/await 的异步方案,您也可以根据需要或者习惯替换成 Promise 的写法async function joinRoom() {$(".wjt").attr("class","gd");// 初始化一个房间 Session 对象, 这里使用 Stream 模式const myRoom = new QNRTC.StreamModeSession();myRoom_this = myRoom;// 这里替换成刚刚生成的 RoomTokenawait myRoom.joinRoomWithToken(RoomToken);console.log("joinRoom success!");//显示已连接的流视频autoSubscribe(myRoom);//播放本地视频摄像头try{await publish(myRoom);}catch(e){alert("权限获取失败,请允许摄像头访问");}}// 增加一个函数 publish,用于采集并发布自己的媒体流// 这里的参数 myRoom 是指刚刚加入房间时初始化的 Session 对象async function publish(myRoom) {// 调用采集模块采集本地的音频和视频数据,返回一个包含这些数据的 Stream 对象const localStream = await QNRTC.deviceManager.getLocalStream({audio: { enabled: true },video: { enabled: true },});// 将刚刚的 Stream 对象发布到房间中await myRoom.publish(localStream);console.log("publish success!");// 在这里添加// 获取页面上的一个元素作为播放画面的父元素const localElement = document.getElementById("videolocal");// 调用 Stream 对象的 play 方法在这个元素下播放媒体流,其中第二个参数代表 静音播放localStream.play(localElement, true);}if(confirm("我们将采集您的摄像头/麦克风数据并与房间其他用户进行音视频通话")){joinRoom();//启动}   // 这里的参数 myRoom 是指刚刚加入房间时初始化的 Session 对象, 同上// userId 是指订阅对象的用户名async function subscribe(myRoom, userId) {//判断是否存在该视频if($("#video"+userId).length==0){var html = '<div class="one" onclick="swithDialog(\''+userId+'\')">\n' +'            <div class="one_video"  id="video'+userId+'" ></div>\n' +'            <div class="one_text">'+userId+'</div>\n' +'        </div>';$(".list").append(html);}// 调用订阅方法发起订阅,成功会返回一个 Stream 对象,这就是远端的流了const remoteStream = await myRoom.subscribe(userId);// 选择页面上的一个元素作为父元素,播放远端的流const remoteElement = document.getElementById("video"+userId);remoteStream.play(remoteElement);}// 这里的参数 myRoom 是指刚刚加入房间时初始化的 Session 对象, 同上function autoSubscribe(myRoom) {const users = myRoom.users;console.log("room current users", users)// 遍历房间当前所有用户for (const user of users) {// 如果存在一个用户,用户名不是自己并且已经发布// 就可以发起订阅了if (user.userId !== myRoom.userId && user.published) {// 调用我们刚刚编写的 subscribe 方法// 注意这里我们没有使用 async/await,而是使用了 Promise,大家可以思考一下为什么subscribe(myRoom, user.userId).then(() => console.log("subscribe success!")).catch(e => console.error("subscribe error", e));}}//width change$(".list").css("width",$(".list .one").length*110+"px");$(".mylist").scrollBar();// 接下来我们需要处理第二种情况,也就是监听事件来感知房间内有用户发布了myRoom.on("user-publish", (user) => {console.log("user", user.userId, "is published!");subscribe(myRoom, user.userId).then(() => console.log("subscribe success!")).catch(e => console.error("subscribe error", e));});//远程用户离开房间myRoom.on("user-leave",(user)=>{console.log("user", user.userId, "go leave!");if($("#video"+user.userId).length>0){//存在用户$("#video"+user.userId).parent(".one").remove();//去掉UI}});}//离开房间function myleave(obj){$(obj).attr("class","wjt");myRoom_this.leaveRoom();}//交换窗口function swithDialog(zid){$("#video"+zid).parent(".one").addClass("max");$("#video"+zid).parent(".one").siblings().removeClass("max");}//离开页面function checkLeave(){myRoom_this.leaveRoom();}
</script>
</body>
</html>

未做太多业务的处理,只是简单的视频,未涉及文件传递或聊天socket功能!

有想法的可以研究,研究啦~

百度网盘:https://pan.baidu.com/s/1jv8dppNcjc3gpffGQnWVGw  提取码:67jz

感谢您的支持,写的文章如对您有所帮助,开源不易,请您打赏,谢谢啦~

html实现视频会议 (web端+手机端),支持多人在线,窗口切换,分享 - Cover 七牛相关推荐

  1. php安卓浏览器调用相机拍照,好用的pc端web端 手机端浏览器调用摄像头拍照JavaScript...

    亲测可用: 摄像头拍照 拍照 下载拍照图片 //访问用户媒体设备的兼容方法 function getUserMedia(constraints, success, error) { if (navig ...

  2. web,pc端及手机端支持的字体

    页面地址为:<点击此处> 以上为引致张鑫旭的网站内容,仅为了以后方便查看,如有不当,请指出谅解! 手机端字体选择: 手机端支持的字体比较少,对于要求的字体一般如何定义? 相信大家会想到 @ ...

  3. 移动端/手机端 完成图片旋转 压缩 剪裁 上传

    本篇文章主要介绍移动端/手机端图片的旋转.压缩.剪裁.上传 这个功能的实现已经好了几次方案流程了,对最终的方案流程进行简述 实现功能的主要方法/思想 1.图片的选取主要是通过input实现 2.图片的 ...

  4. ERP进销存软件系统 电脑端 手机端 小程序通用 (教程)

    ERP(Enterprise Resource Planning)即企业资源计划  可以电脑端  手机端 小程序    数据同步多账户使用 ERP进销存软件系统试用网址  https://erp.77 ...

  5. 移动端(手机端)页面自适应解决方案—rem布局篇

    移动端(手机端)页面自适应解决方案-rem布局 假设设计妹妹给我们的设计稿尺寸为750 * 1340.结合网易.淘宝移动端首页html元素上的动态font-size属性.设计稿尺寸.前端与设计之间协作 ...

  6. 移动端(手机端)页面自适应解决方案—rem布局篇 1

    动端(手机端)页面自适应解决方案-rem布局 假设设计妹妹给我们的设计稿尺寸为750 * 1340.结合网易.淘宝移动端首页html元素上的动态font-size属性.设计稿尺寸.前端与设计之间协作流 ...

  7. PC端手机端百度查排名工具(SEO工具)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kaeX0TZN-1637306311903)(http://cdn.h3blog.com/20211119142524. ...

  8. Java外卖点餐送餐平台源码带手机端带文档(源码分享)

    Java仿饿了么外卖点餐送餐平台源码带手机端带文档(源码分享) 一个简单的外卖系统,包括手机端,后台管理,api基于spring boot和vue的前后端分离的外卖系统.包含手机端,后台管理功能. 核 ...

  9. 1核2g1m服务器可以同时支持多少人在线使用

    目录 一.可以支持多少人访问? 一般可以支持14人在线同时访问 二.1核2g1m是什么样的配置 1核2G内存的服务器相当于一台手机1/4的功效 三.为什么是14人? 这一点也找腾讯工程师验证了,确实是 ...

最新文章

  1. Java后台获取前端传递的日期解析不了
  2. c语言如何用双重循环去重,c语言中一个一维数组怎样去重?
  3. 软件开发安全性_开发具有有效安全性的软件的最佳方法
  4. tomcat7 1000并发量配置 tomcat7配置优化
  5. 网易身患绝症员工被裁事件背后 年轻一代的辛酸和压力
  6. java操作数据库,以页面显示学生信息为例
  7. 关于php编译安装扩展模块memcache的问题
  8. SSH和SSM两个框架的浅显的区别
  9. myeclipse 报内存不足的解决方法
  10. np.ones(),np.zeros(), np.empty(),np.full(),np.ones_like() 基本用法
  11. 关于二维数组传参问题
  12. 【洛谷4920】[WC2015] 未来程序(提答题)
  13. 用net user新建用户并设置管理员
  14. mysql不识别生僻字_MySQL生僻字(不常用字)的完整解决方案
  15. From RankNet to LambdaRank to LambdaMART: An Overview
  16. gap year_应该gap year吗?过来人这么说
  17. Kubernetes:3步排查K8S Deployment故障
  18. 大数据毕业设计 基于时间序列的股票预测与分析系统 - 大数据分析
  19. java之class文件解析
  20. Python+Vue计算机毕业设计包头市大学生家教信息中介平台aizx2(源码+程序+LW+部署)

热门文章

  1. 葡萄酒质量和时间关系
  2. 2022年8月国内外数据库排名
  3. 解决Steam下载不了(缺失文件权限)的问题
  4. [雷倒]计算机系学生巨牛的请假条
  5. Spring的事务(Transaction)
  6. OpenCV中的图像金字塔(高斯金字塔、拉普拉斯金字塔)
  7. Linux VncServer 配置
  8. 加拿大FBA专线 什么是加拿大FBA专线物流
  9. WEB前端学习论坛整理
  10. STM32下串口通信——汇编