记录前端代码,实现视频通话。后台主要用java写一个websocket实现传输通信,后边我改成了vue3,就不上传了,vue版本自己改一下就行。

代码片.

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>video</title>
</head>
<body>
<h2 style="text-align: center;">播放页面</h2>
<h3 id="userId" style="text-align: center;"></h3>
<center><div><video id="localVideo" class="video" muted autoplay="autoplay"></video><video id="remoteVideo" class="video" height="100px" autoplay="autoplay"></video></div>
</center>
</br>
<div style="text-align: center;"><button id="callBtn" onclick="requestConnect()">建立连接</button><button id="hangupBtn" onclick="hangupHandle()">断开连接</button>
</div>
</br>
<div style="text-align: center;">对方id: <input id="toUserId">
</div>
</body>
</html>
<script src="./js/adapter-latest.js"></script>
<script>var flag = false;//防止断开连接时彼此无法同时断开问题const localVideo = document.querySelector('#localVideo');const remoteVideo = document.querySelector('#remoteVideo');const callBtn = document.getElementById('callBtn')const hangupBtn = document.getElementById('hangupBtn')const config = {iceServers: [// { urls: 'stun:10.243.0.101:3478' }{ urls: 'stun:159.75.239.36:3478' }],};let peerConnection;let socket, userId, toUserId;userId = parseInt(Math.random()*10000);document.getElementById('userId').innerText = '我的id:' + userId;// 本地流和远端流let localStream, remoteStream;function requestConnect() {toUserId = document.getElementById('toUserId').valueif(!toUserId){alert('请输入对方id')return false}else if(!socket){alert('请先打开websocket')return false}else if(toUserId == userId){alert('自己不能和自己连接')return false}//准备连接startHandle().then(() => {//发送给远端开启请求socket.send(JSON.stringify({ 'userId': userId, 'toUserId': toUserId, 'message': {'type': 'connect'}}))})}//开启本地的媒体设备async function startHandle() {// 1.获取本地音视频流// 调用 getUserMedia API 获取音视频流let constraints = {video: true,audio: {// 设置回音消除noiseSuppression: true,// 设置降噪echoCancellation: true,}}await navigator.mediaDevices.getUserMedia(constraints).then(gotLocalMediaStream).catch((err) => {console.log('getUserMedia 错误', err);//创建点对点连接对象});createConnection();}// getUserMedia 获得流后,将音视频流展示并保存到 localStreamfunction gotLocalMediaStream(mediaStream) {localVideo.srcObject = mediaStream;localStream = mediaStream;callBtn.disabled = false;}function startWebsocket() {toUserId = document.getElementById('toUserId').valueconsole.log(userId)// let webSocketUrl = 'ws://10.243.1.200:8050' + '/websocket/' + userIdlet webSocketUrl = 'ws://192.168.31.230:8050' + '/websocket/' + userIdif ('WebSocket' in window) {// console.log(1)socket = new WebSocket(webSocketUrl);} else if ('MozWebSocket' in window) {// console.log(2)socket = new MozWebSocket(webSocketUrl);}// socket = new SockJS('https://' + location.host + '/websocket/' + userId);//连接成功socket.onopen = function (e) {console.log('连接服务器成功!')};//server端请求关闭socket.onclose = function (e) {console.log('close')alert(JSON.stringify(e))};//errorsocket.onerror = function (e) {console.error(e)alert(JSON.stringify(e))};socket.onmessage = onmessage}//连接服务器startWebsocket();function onmessage(e) {const json = JSON.parse(e.data)const description = json.messagetoUserId = json.userIdconsole.log(description.type)switch (description.type) {case 'connect':if(confirm(toUserId + '请求连接!')){//准备连接startHandle().then(() => {socket.send(JSON.stringify({ 'userId': userId, 'toUserId': toUserId, 'message': {'type': 'start'} }));})}break;case 'start'://同意连接之后开始连接startConnection()break;case 'offer':peerConnection.setRemoteDescription(new RTCSessionDescription(description)).then(() => {}).catch((err) => {console.log('local 设置远端描述信息错误', err);});peerConnection.createAnswer().then(function (answer) {peerConnection.setLocalDescription(answer).then(() => {console.log('设置本地answer成功!');}).catch((err) => {console.error('设置本地answer失败', err);});socket.send(JSON.stringify({ 'userId': userId, 'toUserId': toUserId, 'message': answer }));}).catch(e => {console.error(e)});break;case 'icecandidate':// 创建 RTCIceCandidate 对象let newIceCandidate = new RTCIceCandidate(description.icecandidate);// 将本地获得的 Candidate 添加到远端的 RTCPeerConnection 对象中peerConnection.addIceCandidate(newIceCandidate).then(() => {console.log(`addIceCandidate 成功`);}).catch((error) => {console.log(`addIceCandidate 错误:\n` + `${error.toString()}.`);});break;case 'answer':peerConnection.setRemoteDescription(new RTCSessionDescription(description)).then(() => {console.log('设置remote answer成功!');}).catch((err) => {console.log('设置remote answer错误', err);});break;case 'disconnect':hangupHandle();break;default:break;}}function createConnection() {peerConnection = new RTCPeerConnection(config)flag = false;if (localStream) {// 视频轨道const videoTracks = localStream.getVideoTracks();// 音频轨道const audioTracks = localStream.getAudioTracks();// 判断视频轨道是否有值if (videoTracks.length > 0) {console.log(`使用的设备为: ${videoTracks[0].label}.`);}// 判断音频轨道是否有值if (audioTracks.length > 0) {console.log(`使用的设备为: ${audioTracks[0].label}.`);}localStream.getTracks().forEach((track) => {peerConnection.addTrack(track, localStream)})}// 监听返回的 CandidatepeerConnection.addEventListener('icecandidate', handleConnection);// 监听 ICE 状态变化peerConnection.addEventListener('iceconnectionstatechange', handleConnectionChange)//拿到流的时候调用peerConnection.addEventListener('track', gotRemoteMediaStream);}//创建发起方会话描述对象(createOffer),设置本地SDP(setLocalDescription),并通过信令服务器发送到对等端,以启动与远程对等端的新WebRTC连接。function startConnection() {callBtn.disabled = false;hangupBtn.disabled = false;// 发送offerpeerConnection.createOffer().then(description => {console.log(`本地创建offer返回的sdp:\n${description.sdp}`)// 将 offer 保存到本地peerConnection.setLocalDescription(description).then(() => {console.log('local 设置本地描述信息成功');// 本地设置描述并将它发送给远端socket.send(JSON.stringify({ 'userId': userId, 'toUserId': toUserId, 'message': description }));}).catch((err) => {console.log('local 设置本地描述信息错误', err)});}).catch((err) => {console.log('createdOffer 错误', err);});}function hangupHandle() {if(!flag){let description = {type:'disconnect'}socket.send(JSON.stringify({ 'userId': userId, 'toUserId': toUserId, 'message': description }));}flag = true;//防止死循环// 关闭连接并设置为空if(peerConnection){peerConnection.close();peerConnection = null;}hangupBtn.disabled = false;callBtn.disabled = false;if(localStream){localStream.getTracks().forEach((track) => {track.stop()})}}// 3.端与端建立连接function handleConnection(event) {// 获取到触发 icecandidate 事件的 RTCPeerConnection 对象// 获取到具体的Candidateconsole.log("handleConnection")const peerConnection = event.target;const icecandidate = event.candidate;if (icecandidate) {socket.send(JSON.stringify({'userId': userId,'toUserId': toUserId,'message': {type: 'icecandidate',icecandidate: icecandidate}}));}}// 4.显示远端媒体流function gotRemoteMediaStream(event) {console.log('remote 开始接受远端流')if (event.streams[0]) {remoteVideo.srcObject = event.streams[0];remoteStream = event.streams[0];}}function handleConnectionChange(event) {const peerConnection = event.target;console.log('ICE state change event: ', event);console.log(`ICE state: ` + `${peerConnection.iceConnectionState}.`);}</script>
<style>.video {background-color: black;height: 30vh;}
</style>

webrtc实现视频通话(前端)相关推荐

  1. Android WebRTC语音视频通话demo

    Android WebRTC简介 https://blog.csdn.net/Charon_Chui/article/details/80510945?utm_term=%E6%89%8B%E6%9C ...

  2. 语音通话视频通话前端_新的视频通话

    语音通话视频通话前端 For the class of people referred to as " 对于被称为" knowledge workers", the co ...

  3. 流媒体服务器开发——SRS 4.0与WebRTC音视频通话丨音视频开发丨嵌入式开发丨FFmpeg丨iOS音视频开发

    SRS 4.0与WebRTC音视频通话 1. 音视频高薪岗位都需要什么技能点 2. WebRTC的技术点分析 3. SRS 4.0如何使用WebRTC 视频讲解如下,点击观看: 流媒体服务器开发--S ...

  4. WebRTC音频视频通话-支持android、ios、H5

    基于uniapp开发的WebRTC音频视频通话demo,插件免费下载地址: WebRTC音频视频通话-支持android.ios.H5 - DCloud 插件市场 视频通话开源demo功能列表 音频实 ...

  5. iOS下WebRTC音视频通话(一)

    在iOS下做IM功能时,难免都会涉及到音频通话和视频通话.QQ中的QQ电话和视频通话效果就非常好,但是如果你没有非常深厚的技术,也没有那么大的团队,很难做到QQ那么快速和稳定的通话效果. 但是利用We ...

  6. 5G时代必学的WebRTC音视频通话技术

    什么是WebRTC ◼ WebRTC(Web Real-Time Communication)是 Google于2010以6829万美 元从 Global IP Solutions 公司购买,并于20 ...

  7. 音视频通话:腾讯云 webRTC音视频通话的使用

    最近项目中用到关于视频通话的功能,一开始使用腾讯云云直播提供的接口进行web端推流和拉流,但苦于获取不到音频,而且那个web推流用的flash谷歌在12月份就不支持了.所以我们最终确定使用webrtc ...

  8. ios视频通话三方_iOS基于Socket.io即时通讯IM实现,WebRTC实现视频通话

    Socket.io-FLSocketIM-iOS 基于Socket.io iOS即时通讯客户端 iOS IM Client based on Socket.io 实现功能 文本发送 图片发送(从相册选 ...

  9. 在centos8环境下用asterisk18配置pjsip和webrtc音视频通话教程(一)

    记录一下2021年采用asterisk18配置pjsip分机和webrtc音视频的教程,测试采用浏览器WebRTC呼叫软电话sip分机,WebRTC接听之间的拨号和内部SIP分机和浏览器WebRTC分 ...

最新文章

  1. Python爬虫之破解百度翻译--requests案例详解(一)
  2. FPGA之道(70)提高设计的综合性能(二)提高设计的自测性
  3. 数据结构--二叉树--路径 假设二叉树采用二叉链表方式存储, root指向根结点,node 指向二叉树中的一个结点, 编写函数 path,计算root到 node 之间的路径,(该路径包括root结
  4. 建立Win32 Console Project时会出“error LNK1123” 错误
  5. 堆排序--采用快速排序(利用大堆实现升序,小堆实现降序)
  6. 比特币最主流,以太坊大跌,区块链技术“万金油”红利已结束 | 区块链开发者年度报告...
  7. 计算机技术和通信技术的关系,计算机技术与通信技术的关系
  8. 人工智能属于计算机科学研究方向,《人工智能》课程简介
  9. vue3 动态获取屏幕尺寸
  10. 计算机专用英语词汇1000个!
  11. Win10使用Lenovo Vantage更新驱动后蓝屏,提示system_service_exception ETD.sys如何解决
  12. 【涂鸦物联网足迹】涂鸦云平台接口列表—智能门锁
  13. ESLint+Prettier+Vetur 统一Vue项目代码风格
  14. C#键盘事件处理(来源网上)
  15. 待业在家,晚上10点接到HR面试电话,我拒绝了
  16. 宽带拨号任何使用计算机,宽带拨号密码怎么查看【图解】
  17. Animate.css动画演示
  18. C# WPF 实现英雄联盟图片 宝宝识图
  19. linux rm 命令详解,Linux rm命令使用指南
  20. 用python做时间序列预测十:时间序列实践-航司乘客数预测

热门文章

  1. tar.gz文件修复
  2. 《机房收费系统》可行性分析报告
  3. Android之Dalvik 、ART
  4. 智慧园区产业链、建设内容及架构
  5. python测量不确定度程序设计_测量不确定度计算 - 用于计算测量不确定度的资源...
  6. 童年游戏机项目,每天被动收入200+
  7. gcm支持php吗,我们如何在PHP中使用GCM模式加密?
  8. 每日一题(二十九):Oil Deposite
  9. 解决联想电脑上Microsoft Edge浏览器主页锁定hao123无法更改的问题
  10. Modern Robotics正运动学(forward kinematics)