点击上方 前端瓶子君,关注公众号
回复算法,加入前端编程面试算法每日一题群
原文: https://juejin.cn/post/6993133406565449736
作者: 云的世界
专栏: 前端SSD系列
前言
前端一些有意思的内容,旨在3-10分钟里, 500-1000字,有所获,又不为所累。
共享桌面程序,哇,高大尚耶!其实不然,让我带你3分钟实现桌面共享程序,还能听到对面说话哦。
效果演示和源码
两个Tab标签,一个是分享者,一个是观众。 顺便问一下,怎么把声音保存到gif图里面去?
思路
用户1 ==> Screen Capture API ===> Web RTC ===> User2 Video 标签播放
其核心 Screen Capture API[1] + WebRTC API[2], 我们一起来了解一波。
Screen Capture API[3] - 屏幕捕捉API
MDN解释:
屏幕捕获API,对现有的媒体捕获和流API进行了补充,让用户选择一个屏幕或屏幕的一部分(如一个窗口)作为媒体流进行捕获。然后,该流可以被记录或通过网络与他人共享。
先看动态,再看代码:
仅仅只需 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[4]
MDN
WebRTC (Web Real-Time Communications) 是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。
我们明白其是点对点传输技术,解决传输问题就行。
实现
遵循SSD系列的准则:3-10分钟里, 500-1000字,有所获,又不为所累。我自行实现,字数会超,而且还要有中转服务器。罢了,借助声网吧。
声网 agora[5], 为什么是他,因为他一个月免费 10000 分钟, 做测试和个人使用是完全够了的。其底层的基本原理上面已经说过了,核心就是 Screen Capture API[6] + Web RTC[7]。
当然声网还支持摄像头,麦克风等等其他流的推送,摄像头和麦克风是 MediaDevices[8]相关的内容不做过多的解释。
注册账号
声网管理台登录或者注册[9],链接地址已给,自行操作即可。
创建应用
详情参见 跑通示例项目[10], 里面有详细的步骤教你创建应用,以及获得AppID和Token
SDK下载
去这里下载 Agora SDK下载[11]
分享者代码编写
这里有一个参数理解一下:
appId:应用ID
channel: 渠道,你可以理解为房间
token:票证
uid: 用户ID
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完整的代码
源码地址: https://github.com/xiangwenhu/juejinBlogsCodes/tree/master/shareYourDesktop
小结
是不是很简单,一切都看起来没那么难,这样,你才容易入坑啊。
写在最后
写作不易,你的一赞一评就是我前行的最大动力。
最后
欢迎关注【前端瓶子君】✿✿ヽ(°▽°)ノ✿
回复「算法」,加入前端编程源码算法群,每日一道面试题(工作日),第二天瓶子君都会很认真的解答哟!
回复「交流」,吹吹水、聊聊技术、吐吐槽!
回复「阅读」,每日刷刷高质量好文!
如果这篇文章对你有帮助,「在看」是最大的支持
》》面试官也在看的算法资料《《
“在看和转发”就是最大的支持