【发布时间】:2021-07-12 11:17:04
【问题描述】:
我使用 Nodejs 和 Twilio CLI 创建了一个视频通话应用程序。并在我的移动应用程序 Android 和 iOS 中使用它。在 Android 上运行良好。但是在 iOS 上,有一个问题,当用户到达视频通话页面时,它会显示预览,但是当用户单击加入房间按钮时,他/她的视频会停止并只显示黑屏。虽然他可以与其他用户交谈并可以看到他们的视频。第二个用户也可以完美地看到他/她的视频。只有他/她在该通话中看不到他/她的视频的问题。
我的html代码
<!DOCTYPE html>
<html>
<head>
<style>
.joinbtn {
border: none;
padding: 10px 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
background-color: #2b96cc;
color: #fff;
}
.stvbtn {
border: none;
padding: 10px 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
background-color: #2b96cc;
color: #fff;
}
.endbtn {
float:right;
border: none;
padding: 10px 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
background-color: #dc3545;
color: #fff;
}
@media screen and (max-width: 820px) {
video {
object-fit: cover;
width: 100%;
height: 47vh;
}
}
@media screen and (min-width: 821px){
video {
object-fit: contain;
}
}
.connect_btn{
display: flex;
justify-content: center;
align-content: space-around;
margin-top: -50px;
opacity: 0.8;
padding-bottom:8px;
}
button.endbtn:disabled, button.joinbtn:disabled {
background-color: #607d8b;
color: #ffffff;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/webrtc-adapter/6.4.0/adapter.js" type="text/javascript"></script>
<script src="webrtc.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Clifix Video Chat</title>
</head>
<body>
<div id="room-controls">
<video id="video" autoplay muted playsinline loop width="100%"></video>
<div class="connect_btn">
<label for="passcode"></label>
<input id="passcode" type="hidden" value="8514"/>
<!--button class="stvbtn" id="start-video" onclick="viplay()">On/Off</button-->
<button class="joinbtn" id="button-join">Join Room</button>
<button class="endbtn" id="button-leave" disabled="disabled">End Call</button>
</div>
</div>
<!-- EDIT_CODE -->
<script src="//media.twiliocdn.com/sdk/js/video/releases/2.3.0/twilio-video.min.js"></script>
<script src="index.js"></script>
</body>
</html>
我的nodejs代码:
'use strict';
(() => {
//const ROOM_NAME = 'demo';
var urltemp = location.search;
var array = urltemp.split('?');
var array1 = array[1];
var array2 = array1.split('=');
var id = array2[1];
const ROOM_NAME = id;
const Video = Twilio.Video;
let videoRoom, localStream;
const video = document.getElementById('video');
// preview screen
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((vid) => {
video.srcObject = vid;
localStream = vid;
});
// buttons
const joinRoomButton = document.getElementById('button-join');
const leaveRoomButton = document.getElementById('button-leave');
joinRoomButton.onclick = () => {
//video.play();
// get access token
fetch(`video-token?passcode=${getPasscode()}&room=${ROOM_NAME}`)
.then((resp) => {
if (resp.ok) {
var url=window.location.href,
separator = (url.indexOf("?")===-1)?"?":"&",
newParam=separator + "join=true";
var newUrl=url.replace(newParam,"");
newUrl+=newParam;
window.history.replaceState(null,null,newUrl);
return resp.json();
} else {
console.error(resp);
if (resp.status === 401) {
throw new Error('Go Back & Join Again');
} else {
throw new Error('Unexpected error. Open dev tools for logs');
}
}
})
.then((body) => {
const token = body.token;
//console.log(token);
//connect to room
return Video.connect(token, { name: ROOM_NAME });
})
.then((room) => {
//console.log(`Connected to Room ${room.name}`);
videoRoom = room;
room.participants.forEach(participantConnected);
room.on('participantConnected', participantConnected);
room.on('participantDisconnected', participantDisconnected);
room.once('disconnected', (error) =>
room.participants.forEach(participantDisconnected)
);
joinRoomButton.disabled = true;
leaveRoomButton.disabled = false;
})
.catch((err) => {
alert(err.message);
});
};
// leave room
leaveRoomButton.onclick = () => {
var url=window.location.href,
separator = (url.indexOf("?")===-1)?"?":"&",
newParam=separator + "end=true";
var newUrl=url.replace(newParam,"");
newUrl+=newParam;
window.history.replaceState(null,null,newUrl);
videoRoom.disconnect();
//console.log(`Disconnected from Room ${videoRoom.name}`);
joinRoomButton.disabled = false;
leaveRoomButton.disabled = true;
};
})();
const getPasscode = () => {
const passcodeInput = document.getElementById('passcode') || {};
const passcode = passcodeInput.value;
passcodeInput.value = '';
return passcode;
};
// connect participant
const participantConnected = (participant) => {
//console.log(`Participant ${participant.identity} connected'`);
const div = document.createElement('div'); //create div for new participant
div.id = participant.sid;
participant.on('trackSubscribed', (track) => trackSubscribed(div, track));
participant.on('trackUnsubscribed', trackUnsubscribed);
participant.tracks.forEach((publication) => {
if (publication.isSubscribed) {
trackSubscribed(div, publication.track);
}
});
document.body.appendChild(div);
};
const participantDisconnected = (participant) => {
//console.log(`Participant ${participant.identity} disconnected.`);
document.getElementById(participant.sid).remove();
};
const trackSubscribed = (div, track) => {
div.appendChild(track.attach());
};
const trackUnsubscribed = (track) => {
track.detach().forEach((element) => element.remove());
};
据我了解,在此之前我的视频无法在 iOS Safari 上运行,然后我对 HTML 视频代码进行了修改。
从这里:
<video id="video" autoplay muted width="100%"></video>
收件人:
<video id="video" autoplay muted playsinline loop width="100%"></video>
然后,当他/她开始呼叫时,它开始在 iOS 用户端冻结视频。
【问题讨论】:
-
首先,您可以尝试升级您正在使用的 Twilio Video JS 的版本。我可以看到您使用的是 CDN 的 2.3.0 版本,最新版本是 2.15.1。另外,当这种情况发生时,Safari 的开发者工具中是否有任何错误或有用的日志?
-
不,ios日志中没有错误。
-
您是否尝试过升级 Twilio Video JS 的版本?
-
我发现了别的东西,但我现在没有时间写一个完整的答案。
Video.connect请求获取新的视频和音频轨道,而 Safari 不喜欢一次访问多个轨道。相反,您应该保存对轨道的引用并将它们传递给Video.connect(token, { tracks: tracks })。这样,您将在实际连接中重复使用相同的预览曲目。 -
我已经按照您的建议尝试了新的 CDN,但仍然没有成功。
标签: ios node.js twilio mobile-safari videocall