WebRTC屏幕在手机上冻结
问题描述:
我正在使用WebRTC在Angular 2应用程序上创建通信。此应用程序用于笔记本电脑和智能手机与CSS规则来处理响应。WebRTC屏幕在手机上冻结
我有一个特定的问题:我的应用程序完全可以在笔记本电脑上的2个网页之间工作,但是当我在智能手机上打开网页时,页面在通信开始时(智能手机和笔记本电脑之间)冻结。该页面只在智能手机端冻结,在笔记本电脑端工作良好。
我只在Chrome上有此行为。所有在Firefox上运行良好。
当我评论addStream()
函数时,问题“已解决”。现在,我使用addTrack()
函数代替addStream()
,但问题仍然存在。
这是我的服务来创建和管理WebRTC通信。我使用visioApi
通过信令服务器发送数据。
interface IceCandidateObject {
candidate: string
sdpMid: string
sdpMLineIndex: number
}
@Injectable()
export class VisioService {
conf: RTCConfiguration = {
iceServers: [
// Peer Configuration
{
urls: 'xxxxxx',
credential: 'xxxxxx',
username: 'xxxxxx',
},
{
urls: 'xxxxx',
credential: 'xxxxxx',
username: 'xxxxxx',
},
{
urls: 'xxxxxxxx',
credential: 'xxxxxx',
username: 'xxxxx',
},
],
}
pc: any // Peer connection
stream: any // Video stream
target: string // target userkey
remoteVideo = undefined
constraints = {
mandatory: [{ OfferToReceiveAudio: true }, { OfferToReceiveVideo: true }],
optional: [{ DtlsSrtpKeyAgreement: true }],
}
callId: string
caller = false
videoRunning = true
audioRunning = true
constructor(
private visioApi: ApiVisio,
private zpConnection: ZetaPushConnection,
) {
this.visioApi.onReplyToCall.subscribe((onReplyToCallMsg) => {
console.log('VisioService::OnReplyToCall')
this.callId = onReplyToCallMsg.result.id
})
this.visioApi.onCallUser.subscribe((onCallUserMsg) => {
console.log('VisioService::OnCallUser')
this.callId = onCallUserMsg.result.callObject.id
})
this.visioApi.onSendVisioMessage.subscribe((onSendVisioMsg) => {
const message = onSendVisioMsg.result.message
switch (message.type) {
case 'offer':
this.pc.setRemoteDescription(new RTCSessionDescription(message),() => {
this.pc.createAnswer().then((answer) => {
this.visioApi.sendVisioMessage(this.target, answer)
return this.pc.setLocalDescription(answer)
}).catch((err) => {
console.log('FailedCreateAnswer', err)
})
}, (err) => {
console.log('SetRemoteDescriptionFailed', err)
})
break
case 'answer':
const answerSessionDescription: RTCSessionDescriptionInit = {
sdp: message.sdp,
type: message.type
}
this.pc.setRemoteDescription(new RTCSessionDescription(answerSessionDescription))
break
case 'icecandidate':
const ice: RTCIceCandidateInit = {
candidate: message.candidate,
sdpMid: message.sdpMid,
sdpMLineIndex: message.sdpMLineIndex
}
this.pc.addIceCandidate(new RTCIceCandidate(ice))
break
}
})
}
/**
* Method used to launch a visio call with the other user
* @param target : userKey of the target
*/
launchVisioCall(target: string): void {
this.target = target
this.visioApi.callUser(this.target)
}
/**
* Stop the call
*/
stopCall(): void {
if (this.pc && this.pc.signalingState !== 'closed') {
this.pc.close()
}
}
/**
* Method to reply to an incoming call
*/
ReplyToIncomingCall(): void {
this.visioApi.replyToCall(this.callId, this.target)
}
/**
* Method to refuse an incoming call
*/
refuseIncomingCall(): void {
this.visioApi.refuseCall(this.callId, this.target)
}
/**
* Method to set the call id
* @param id : Id of the call
*/
setCallId(id: string): void {
this.callId = id
}
/**
* Method to set the target
* @param target : userKey of the target
*/
setTarget(target: string): void {
this.target = target
}
/**
* Init
* @param videoElement : remote video
* @param videoRemote : local video
*/
init(videoElement: HTMLVideoElement, videoRemote: HTMLVideoElement, caller: boolean): void {
this.caller = caller
this.startLocalVideo(videoElement)
this.remoteVideo = videoRemote
}
/**
* Start the local video
*/
startLocalVideo(videoElement: HTMLVideoElement): void {
videoElement.volume = 0;
videoElement.muted = false;
videoElement.load();
videoElement.play().then((result) => {
console.log('==> video played', result)
}).catch((err) => {
console.error('==> video error', err)
});
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).then((stream) => {
videoElement.srcObject = stream
this.stream = stream
this.initPeerConnection()
}).catch((err) => {
console.error('err local video', err)
})
}
/**
* Init peer connection
*/
initPeerConnection(): void {
this.pc = new RTCPeerConnection(this.conf)
this.stream.getTracks().forEach(element => {
this.stream.addTrack(element);
if (this.pc.addTrack) {
this.pc.addTrack(element, this.stream);
} else {
setTimeout(() => this.pc.dispatchEvent(new Event('negociationneeded')))
}
});
this.pc.onnegociationneeded = event => {
this.pc.createOffer().then((offer) => {
this.pc.setLocalDescription(offer)
}).then(() => {
const offerMsg: Message = {
sdp: this.pc.localDescription,
type: 'offer'
}
this.visioApi.sendVisioMessage(this.target, offerMsg)
})
}
this.pc.addStream(this.stream)
// Handle ICE Candidates
this.pc.onicecandidate = event => {
const iceMessage: Message = {
candidate: event.candidate.candidate,
sdpMid: event.candidate.sdpMid,
sdpMLineIndex: event.candidate.sdpMLineIndex,
type: event.type,
}
if (event.candidate != null) {
this.visioApi.sendVisioMessage(this.target, iceMessage)
}
}
// Handle new stream added
this.pc.onaddstream = event => {
console.log('onAddStream::Event', event)
const video = this.remoteVideo
video.srcObject = event.stream
video.load();
video.play()
}
if (!this.caller) {
this.sendOffer()
}
}
sendOffer(): void {
// We create an offer when the target accept the call
this.pc.createOffer(offer => {
this.pc.setLocalDescription(new RTCSessionDescription(offer)).then(() => {
const offerMsg: Message = {
sdp: offer.sdp,
type: offer.type
}
this.visioApi.sendVisioMessage(this.target, offerMsg)
})
}, (err) => {
console.log('ErrorCreateOffer', err)
}, this.constraints)
}
toggleAudio(): void {
this.stream.getTracks().forEach(element => {
if (element.kind === 'audio') {
element.enabled = !element.enabled
}
})
}
toggleVideo(): void {
this.stream.getTracks().forEach(element => {
if (element.kind === 'video') {
element.enabled = !element.enabled
}
})
}
terminateCall(): void {
this.visioApi.terminateCall(this.callId, this.target)
}
stopWebcam(): void {
this.stream.getTracks().forEach(track => {
track.stop()
})
我在每个平台上使用Chrome 61,而我的智能手机在Android上。
我希望有人帮助我。
谢谢你,
达明
答
有铬61的bug。
为了解决这个问题,看到菲利普Hancke的(Opentok on streamCreated subscribe makes mobile chrome freeze)的bug
详细答案:https://bugs.chromium.org/p/chromium/issues/detail?id=769148
解决方法:把border-radius: 1px;
每个HTML视频。
看到我的答案https://*.com/questions/46725469/opentok-on-streamcreated-subscribe-makes-mobile-chrome-freeze/46731092?noredirect=1#comment80519679_46731092 - 铬61错误,那里是一种解决方法: -/ –
非常感谢!解决方法运行良好。 –