共享桌面,3分钟自己实现一个吧,还能听见麦克风声音哦

前言

关于【SSD系列】:
前端一些有意思的内容,旨在3-10分钟里, 500-1000字,有所获,又不为所累。
共享桌面程序,哇,高大尚耶!其实不然,让我带你3分钟实现桌面共享程序,还能听到对面说话哦。

效果演示和源码

两个Tab标签,一个是分享者,一个是观众。分享桌面源码
顺便问一下,怎么把声音保存到gif图里面去????

deskShare.gif

思路


用户1 ==> Screen Capture API  ===>  Web RTC  ===>  User2 Video 标签播放

其核心 Screen Capture API + WebRTC API, 我们一起来了解一波。

Screen Capture API - 屏幕捕捉API

MDN解释:

屏幕捕获API,对现有的媒体捕获和流API进行了补充,让用户选择一个屏幕或屏幕的一部分(如一个窗口)作为媒体流进行捕获。然后,该流可以被记录或通过网络与他人共享。

先看动态,再看代码:

desk1.gif

仅仅只需 10 余行代码,就可以把桌面展示在网页面里面是不是很酷。

    <video id="deskVideo" autoplay controls></video>
    <script>
        (async function captureDesk() {
            deskVideo.srcObject = await navigator.mediaDevices.getDisplayMedia({
                video: {
                    cursor: "always"
                },
                audio: false
            });
        })();
    </script>

Web RTC

MDN

WebRTC (Web Real-Time Communications) 是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。

我们明白其是点对点传输技术,解决传输问题就行。

实现

遵循SSD系列的准则: 3-10分钟里, 500-1000字,有所获,又不为所累。
我自行实现,字数会超,而且还要有中转服务器。罢了,借助声网吧。

声网 agora, 为什么是他,因为他一个月免费 10000 分钟, 做测试和个人使用是完全够了的。 其底层的基本原理上面已经说过了,核心就是
Screen Capture API + Web RTC。

当然声网还支持摄像头,麦克风等等其他流的推送,摄像头和麦克风是 MediaDevices相关的内容不做过多的解释。

注册账号

声网管理台登录或者注册,链接地址已给,自行操作即可。

创建应用

详情参见 跑通示例项目, 里面有详细的步骤教你创建应用,以及获得AppIDToken

SDK下载

去这里下载 Agora SDK下载

分享者代码编写

这里有一个参数理解一下:

  1. appId: 应用ID
  2. channel: 渠道,你可以理解为房间
  3. token:票证
  4. uid: 用户ID
  5. role: 用户角色,有主播和观众两种

核心代码:

async function startBasicLive() {
    rtc.client = AgoraRTC.createClient({ mode: "live", codec: "vp8" }); // 初始化客户端
    rtc.client.setClientRole(options.role);  // 设置角色

    const uid = await rtc.client.join(options.appId, options.channel, options.token, options.uid);       
    rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack(); // 麦克风
    rtc.localVideoTrack = await AgoraRTC.createScreenVideoTrack();  // 桌面

    // 将这些音视频轨道对象发布到频道中。
    await rtc.client.publish([rtc.localAudioTrack, rtc.localVideoTrack]);
    console.log("publish success!");
}
btnShareDesk.onclick = startBasicLive; // 注册点击事件

观众端代码编写

核心代码

async function startBasicLive() {
    rtc.client = AgoraRTC.createClient({ mode: "live", codec: "vp8" });
    rtc.client.setClientRole(options.role);

    rtc.client.on("user-published", async (user, mediaType) => {
         // 开始订阅远端用户。
        await rtc.client.subscribe(user, mediaType);
        console.log("subscribe success", mediaType);

        // 表示本次订阅的是视频。
        if (mediaType === "video") {
            // 订阅完成后,从 `user` 中获取远端视频轨道对象。
            const remoteVideoTrack = user.videoTrack;
            // 动态插入一个 DIV 节点作为播放远端视频轨道的容器。
            const playerContainer = document.createElement("div");
            // 给这个 DIV 节点指定一个 ID,这里指定的是远端用户的 UID。
            playerContainer.id = user.uid.toString();
            playerContainer.style.width = "640px";
            playerContainer.style.height = "480px";
            document.body.append(playerContainer);

            // 订阅完成,播放远端音视频。
            // 传入 DIV 节点,让 SDK 在这个节点下创建相应的播放器播放远端视频。
            remoteVideoTrack.play(playerContainer);
        }

        // 表示本次订阅的是音频。
        if (mediaType === "audio") {
            // 订阅完成后,从 `user` 中获取远端音频轨道对象。
            const remoteAudioTrack = user.audioTrack;
            // 播放音频因为不会有画面,不需要提供 DOM 元素的信息。
            remoteAudioTrack.play();
        }
    });   
    const uid = await rtc.client.join(options.appId, options.channel, options.token, null);
    console.log("uid", uid);
}

demo完整的代码

分享桌面源码

小结

是不是很简单,一切都看起来没那么难,这样,你才容易入坑啊。

写在最后

写作不易,你的一赞一评就是我前行的最大动力。

参考引用

Web RTC
Screen Capture API
Media Devices
实现视频直播
s://developer.mozilla.org/en-US/docs/Web/API/MediaDevices)
实现视频直播
跑通示例项目

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/549521.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Entity Framework】你知道如何处理无键实体吗

【Entity Framework】你知道如何处理无键实体吗 文章目录 【Entity Framework】你知道如何处理无键实体吗一、概述二、定义无键实体类型数据注释 三、无键实体类型特征四、无键实体使用场景五、无键实体使用场景六、无键使用示例6.1 定义一个简单的Blog和Post模型&#xff1a;6…

sqlilabs靶场1—20题学习笔记(思路+解析+方法)

前几个题目较为简单&#xff0c;均尝试使用各种方法进行SQL注入 第一题 联合查询 1&#xff09;思路&#xff1a; 有回显值 1.判断有无注入点 2.猜解列名数量 3.判断回显点 4.利用注入点进行信息收集 爆用户权限&#xff0c;爆库&#xff0c;爆版本号 爆表&#xff0c;爆列&…

AI 领域精选高质量信息源分享

我在这篇 ChatGPT 发布一周年的总结文章中大模型时代&#xff0c;程序员如何实现自我成长&#xff1f;——一名普通开发者的 ChatGPT 一周年记&#xff0c;已经推荐了不少优质的信息源&#xff0c;但主要还是偏技术向&#xff0c;随着我自己的身份从纯研发角色转变为产品&#…

【Linux】服务器硬件及RAID配置实战

目录 一、服务器 1.服务器 2.查看服务器信息 二、RAID 磁盘阵列 三、软RAID的创建和使用 1.添加硬盘&#xff0c;fdisk分区&#xff0c;分区类型ID设置为 fd 2.使用mdadm创建软raid 3.格式化 4.挂载使用 5.mdadm 一、服务器 1.服务器 分类机架式居多 塔…

Qt | 事件第二节

Qt | 事件第一节书接上回 四、事件的接受和忽略 1、事件可以被接受或忽略,被接受的事件不会再传递给其他对象,被忽略的事件会被传递给其他对象处理,或者该事件被丢弃(即没有对象处理该事件) 2、使用 QEvent::accept()函数表示接受一个事件,使用 QEvent::ignore()函数表示…

牛客网刷题 | BC51 及格分数

描述 KiKi想知道他的考试分数是否通过&#xff0c;请帮他判断。从键盘任意输入一个整数表示的分数&#xff0c;编程判断该分数是否在及格范围内&#xff0c;如果及格&#xff0c;即&#xff1a;分数大于等于60分&#xff0c;是输出“Pass”&#xff0c;否则&#xff0c;输出“…

【Entity Framework】你必须要了解EF中数据查询之数据加载

【Entity Framework】你必须要了解EF中数据查询之数据加载 文章目录 【Entity Framework】你必须要了解EF中数据查询之数据加载一、概述二、预先加载2.1 包含多个层级2.2 经过筛选的包含 三、显示加载3.1查询关联实体 四、延时加载4.1 不使用代理进行延迟加载 一、概述 Entity…

数据分析(2)

数据分析&#xff08;2&#xff09; 本文介绍pandas的另一种数据类型DataFrame,中文叫数据框 DataFrame 定义&#xff1a; DataFrame是一个二维的矩阵数据表&#xff0c;通过行和列&#xff0c;可以定位一个值。 在某种程度上&#xff0c;可以认为DataFrame是“具有相同ind…

自定义类型: 结构体 (详解)

本文索引 一. 结构体类型的声明1. 结构体的声明和初始化2. 结构体的特殊声明3. 结构体的自引用 二. 结构体内存对齐1. 对齐规则2. 为啥存在对齐?3. 修改默认对齐值 三. 结构体传参四. 结构体实现位段1. 什么是位段?2. 位段的内存分配3. 位段的应用4. 位段的注意事项 ​ 前言:…

Python leetcode 2906 构造乘积矩阵,力扣练习,矩阵递推,经典递推题目,递推代码实战

leetcode 2906 构造乘积矩阵&#xff0c;矩阵递推 1.题目描述 给你一个下标从 0 开始、大小为 n * m 的二维整数矩阵 grid &#xff0c;定义一个下标从 0 开始、大小为 n * m 的的二维矩阵 p。如果满足以下条件&#xff0c;则称 p 为 grid 的 乘积矩阵 &#xff1a; 对于每个元…

JavaWeb前端/后端开发规范——接口文档概述及YApi平台的使用

前言&#xff1a; 整理下笔记&#xff0c;打好基础&#xff0c;daydayup!!! 接口文档 什么是接口文档&#xff1f; 目前主流的开发模式为前后端分离式开发&#xff0c;为了方便前后端的对接&#xff0c;就需要使用接口文件进行统一规范。 接口文档记载什么信息&#xff1f; 1&…

Mac搭建Java环境【环境搭建】

Mac搭建Java环境【环境搭建】 1 安装Java SDK 官网地址&#xff1a;https://www.oracle.com/java/technologies/downloads/archive/ 下载dmg&#xff0c;双击之后无脑安装即可。 # 进入 JDK 安装目录 cd /Library/Java/JavaVirtualMachines# 查看文件 ls# 输入 cd ~# 打开环…

短剧分销系统:引领影视娱乐新潮流,开启内容变现全新模式!

近年来&#xff0c;随着互联网的飞速发展和人们生活节奏的加快&#xff0c;短剧项目在我国逐渐崭露头角&#xff0c;并在短时间内吸引了大量观众和投资者的目光。短剧以其时长短、剧情紧凑、制作精良等特点&#xff0c;迅速在视频市场中占据了一席之地。 一、短剧项目发展现状…

vue学习日记22:非父子通信(拓展)-provideinject

一、概念 二、实践 代码 App <template><div class"app">我是APP组件<button click"change">修改数据</button><SonA></SonA><SonB></SonB></div> </template><script> import SonA …

【C++进阶】详解C++类型转换IO流

C类型转换及IO流 一&#xff0c;C语言的类型转换方式二&#xff0c;C的四种强制类型转换方式2.1 static_cast2.2 reinterpret_cast2.3 const_cast2.4 dynamic_cast 三&#xff0c;C语言的输入和输出四&#xff0c;C的标准IO流五&#xff0c;C文件IO流总结 这一节我们来讲解 C的…

`Spring Cloud OpenFeign`底层实现原理

Spring Cloud OpenFeign工作原理 一 、简介 OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解&#xff0c;如RequesMapping等等。 OpenFeign的FeignClient可以解析SpringMVC的RequestMapping注解下的接口&#xff0c;并通过动态代理的方式产生实现类&#xff…

【Git】初识 Git

文章目录 1. 提出问题2. 如何解决&#xff1f;版本控制器3. 注意事项 1. 提出问题 不知道你工作或学习时&#xff0c;有没有遇到这样的情况&#xff1a;我们在编写各种文档时&#xff0c;为了防止文档丢失、更改失误、失误后能恢复到原来的版本&#xff0c;不得不复制出一个副…

Apifox接口测试教程(一)接口测试的原理与工具

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

「GO基础」GO程序组成要素

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

力扣爆刷第119天之CodeTop100五连刷81-85

力扣爆刷第119天之CodeTop100五连刷81-85 文章目录 力扣爆刷第119天之CodeTop100五连刷81-85一、14. 最长公共前缀二、718. 最长重复子数组三、169. 多数元素四、662. 二叉树最大宽度五、128. 最长连续序列 一、14. 最长公共前缀 题目链接&#xff1a;https://leetcode.cn/pro…
最新文章