如何在 ionic 平台的 APIRTC 上静音和取消静音视频/音频?
Posted
技术标签:
【中文标题】如何在 ionic 平台的 APIRTC 上静音和取消静音视频/音频?【英文标题】:how to Mute and Unmute video/audio on APIRTC for ionic platform? 【发布时间】:2020-10-01 05:25:51 【问题描述】:我已经在 Ionic 平台上实现了视频通话集成,我可以打电话,但我不能静音音频和视频流。为了获取本地流,我使用了 apiRTC.getLocalStreams() 但获取 getLocalStreams 不是一种方法。对于静音音频 我使用了 localStraem.muteAudio()、this.webRTCClient.toggleAudioMute(this.callId)。 这里也同样的错误静音音频不是一种方法。谁能帮我解决这个问题?
谢谢。
这是我的代码
declare var iosrtc;
declare var apiRTC;
declare var apiCC;
const STATE_WAIT = "wait";
const STATE_INCALL = "incall";
const LABEL_CALL = "Call";
const LABEL_HANGOUT = "Hangout";
const COLOR_CALL = "#5cb85c";
const COLOR_HANGOUT = "#d9534f";
@Component(
selector: 'page-home',
templateUrl: 'home.html'
);
export class HomePage
distantNumber: any;
webRTCClient: any;
infoLabel: any;
buttonLabel: any;
buttonColor: any;
state: any;
localStraem;
callId;
isMute;
constructor(public navCtrl: NavController, public alertCtrl: AlertController, public platform: Platform, public nativeAudio: NativeAudio)
this.isMute = false;
this.incomingCallHandler = this.incomingCallHandler.bind(this);
this.userMediaErrorHandler = this.userMediaErrorHandler.bind(this);
this.remoteStreamAddedHandler = this.remoteStreamAddedHandler.bind(this);
this.hangupHandler = this.hangupHandler.bind(this);
this.refreshVideoView = this.refreshVideoView.bind(this);
this.sessionReadyHandler = this.sessionReadyHandler.bind(this);
this.userMediaSuccessHandler = this.userMediaSuccessHandler.bind(this);
apiRTC.init(
onReady: this.sessionReadyHandler,
apiKey: "My APIKey",
);
this.nativeAudio.preloadComplex('uniqueI1', 'assets/tone.mp3', 1, 1, 0).then((succ) =>
console.log("suu..........", succ)
, (err) =>
console.log("err..........", err)
);
this.infoLabel = "Registration Ongoing...";
this.buttonLabel = LABEL_CALL;
this.buttonColor = COLOR_CALL;
this.state = STATE_WAIT;
/**
* Call Action
*/
pushCall(event)
console.log("Push, callState=" + this.state);
if (this.distantNumber && this.state == STATE_WAIT)
setTimeout(this.refreshVideoView, 4000);
this.webRTCClient.call(this.distantNumber);
else if (this.state == STATE_INCALL)
this.state = STATE_WAIT;
this.buttonColor = COLOR_CALL;
this.buttonLabel = LABEL_CALL;
this.webRTCClient.hangUp();
sessionReadyHandler(e)
console.log("sessionReadyHandler");
apiRTC.addEventListener("incomingCall", this.incomingCallHandler);
apiRTC.addEventListener("userMediaError", this.userMediaErrorHandler);
apiRTC.addEventListener("remoteStreamAdded", this.remoteStreamAddedHandler);
apiRTC.addEventListener("userMediaSuccess", this.userMediaSuccessHandler);
apiRTC.addEventListener("hangup", this.hangupHandler);
this.webRTCClient = apiCC.session.createWebRTCClient();
this.infoLabel = "Your local ID : " + apiCC.session.apiCCId;
this.callId = apiCC.session.apiCCId;
this.localStraem= this.webRTCClient.getLocalStreams() // getting here error like getLocalStreams is not a method
// this.localStraem= apiRTC.getLocalStreams() // getting here also same error
refreshVideoView()
if (this.platform.is('ios'))
console.log("REFRESH");
iosrtc.refreshVideos();
incomingCallHandler(e)
console.log("incomingCallHandler");
this.state = STATE_INCALL;
this.buttonColor = COLOR_HANGOUT;
this.buttonLabel = LABEL_HANGOUT;
setTimeout(this.refreshVideoView, 2000);
hangupHandler(e)
console.log("hangupHandler");
this.state = STATE_WAIT;
this.buttonColor = COLOR_CALL;
this.buttonLabel = LABEL_CALL;
this.initMediaElementState(e.detail.callId);
;
userMediaSuccessHandler(e)
console.log("userMediaSuccessHandler", e);
console.log('loca..........' + JSON.stringify(e.detail.stream))
this.webRTCClient.addStreamInDiv(
e.detail.stream,
e.detail.callType,
"mini",
'miniElt-' + e.detail.callId,
width: "200px", height: "200px" ,
false
);
userMediaErrorHandler(e)
muteAudio()
this.localStraem.muteAudio(); // here mute audio not a method error
console.log('cal......id............' + this.callId)
// this.webRTCClient.toggleAudioMute(this.callId)
// this.localStraem.getAudioTracks()[0].stop();
// this.localStraem.getTracks().forEach((track) =>
// track.stop();
// );
unmuteAudio()
// this.localStraem.unmuteAudio();
this.localStraem.getTracks().forEach((track) =>
track.start();
);
remoteStreamAddedHandler(e)
console.log('mute..........' + this.isMute)
console.log("remoteStreamAddedHandler", e);
this.state = STATE_INCALL;
this.buttonColor = COLOR_HANGOUT;
this.buttonLabel = LABEL_HANGOUT;
this.webRTCClient.addStreamInDiv(
e.detail.stream,
e.detail.callType,
"remote",
'remoteElt-' + e.detail.callId,
width: "200px", height: "200px" ,
this.isMute
);
setTimeout(this.refreshVideoView, 1000);
initMediaElementState(callId)
this.webRTCClient.removeElementFromDiv('mini', 'miniElt-' + callId);
this.webRTCClient.removeElementFromDiv('remote', 'remoteElt-' + callId);
【问题讨论】:
那么如果你 console.log(apiRTC) - 声明的 var 是定义的? 是的,我也可以连接视频通话,我的问题是静音选项。请参考这段代码,我已经从这里导入了代码 github.com/apizee/ApiRTC-ionic 【参考方案1】:首先,我会确保声明的“apiRTC”变量不是未定义的,并且您知道如何导入它以使其已定义。
然后,确保首先执行 apiRTC 的 init 方法 - 将此代码块移动到您声明 apiRTC var 的位置:
declare var apiRTC;
apiRTC.init(
onReady: this.sessionReadyHandler,
apiKey: "My APIKey",
);
注意:目前在您的代码中,您尝试在 apiRTC 初始化之前使用它。
然后,我会将您的方法 sessionReadyHandler 拆分为在其中您实际上正在初始化 this.localStream(straem?)。
里面有我的 cmets 的代码是这样的:
declare var iosrtc;
declare var apiRTC;
apiRTC.init(
onReady: this.sessionReadyHandler,
apiKey: "My APIKey",
);
console.log(apiRTC) // should return defined here
declare var apiCC;
const STATE_WAIT = "wait";
const STATE_INCALL = "incall";
const LABEL_CALL = "Call";
const LABEL_HANGOUT = "Hangout";
const COLOR_CALL = "#5cb85c";
const COLOR_HANGOUT = "#d9534f";
@Component(
selector: 'page-home',
templateUrl: 'home.html'
) // get rid of ; here
export class HomePage
distantNumber; // no point using type 'any' here
webRTCClient;
infoLabel;
buttonLabel;
buttonColor;
state;
localStraem;
callId;
isMute;
constructor(public navCtrl: NavController, public alertCtrl: AlertController, public platform: Platform, public nativeAudio: NativeAudio)
// initialize handlers inside ngOnInit hook and you do not need binding 'this' here:
/* this.incomingCallHandler = this.incomingCallHandler.bind(this);
this.userMediaErrorHandler = this.userMediaErrorHandler.bind(this);
this.remoteStreamAddedHandler = this.remoteStreamAddedHandler.bind(this);
this.hangupHandler = this.hangupHandler.bind(this);
this.refreshVideoView = this.refreshVideoView.bind(this);
this.sessionReadyHandler = this.sessionReadyHandler.bind(this);
this.userMediaSuccessHandler = this.userMediaSuccessHandler.bind(this); */
;
ngOnInit()
this.nativeAudio.preloadComplex('uniqueI1', 'assets/tone.mp3', 1, 1, 0).then((succ) =>
console.log("suu..........", succ)
, (err) =>
console.log("err..........", err)
);
this.isMute = false;
this.infoLabel = "Registration Ongoing...";
this.buttonLabel = LABEL_CALL;
this.buttonColor = COLOR_CALL;
this.state = STATE_WAIT;
// moved here from sessionReadyHandler:
this.webRTCClient = apiCC.session.createWebRTCClient();
this.infoLabel = "Your local ID : " + apiCC.session.apiCCId;
this.callId = apiCC.session.apiCCId;
this.localStraem= this.webRTCClient.getLocalStreams() // should work now;
// this.localStraem= apiRTC.getLocalStreams() // same
this.sessionReadyHandler() // init listeners, you also might want to remove listeners inside onDestroy hook
;
/**
* Call Action
*/
pushCall(event)
console.log("Push, callState=" + this.state);
if (this.distantNumber && this.state == STATE_WAIT)
setTimeout(this.refreshVideoView, 4000);
this.webRTCClient.call(this.distantNumber);
else if (this.state == STATE_INCALL)
this.state = STATE_WAIT;
this.buttonColor = COLOR_CALL;
this.buttonLabel = LABEL_CALL;
this.webRTCClient.hangUp();
sessionReadyHandler() // event argument is not used here
console.log("sessionReadyHandler");
apiRTC.addEventListener("incomingCall", this.incomingCallHandler);
apiRTC.addEventListener("userMediaError", this.userMediaErrorHandler);
apiRTC.addEventListener("remoteStreamAdded", this.remoteStreamAddedHandler);
apiRTC.addEventListener("userMediaSuccess", this.userMediaSuccessHandler);
apiRTC.addEventListener("hangup", this.hangupHandler);
refreshVideoView()
if (this.platform.is('ios'))
console.log("REFRESH");
iosrtc.refreshVideos();
incomingCallHandler(e)
console.log("incomingCallHandler");
this.state = STATE_INCALL;
this.buttonColor = COLOR_HANGOUT;
this.buttonLabel = LABEL_HANGOUT;
setTimeout(this.refreshVideoView, 2000);
hangupHandler(e)
console.log("hangupHandler");
this.state = STATE_WAIT;
this.buttonColor = COLOR_CALL;
this.buttonLabel = LABEL_CALL;
this.initMediaElementState(e.detail.callId);
;
userMediaSuccessHandler(e)
console.log("userMediaSuccessHandler", e);
console.log('loca..........' + JSON.stringify(e.detail.stream))
this.webRTCClient.addStreamInDiv(
e.detail.stream,
e.detail.callType,
"mini",
'miniElt-' + e.detail.callId,
width: "200px", height: "200px" ,
false
);
userMediaErrorHandler(e)
muteAudio()
this.localStraem.muteAudio(); // here mute audio not a method error
console.log('cal......id............' + this.callId)
// this.webRTCClient.toggleAudioMute(this.callId)
// this.localStraem.getAudioTracks()[0].stop();
// this.localStraem.getTracks().forEach((track) =>
// track.stop();
// );
unmuteAudio()
// this.localStraem.unmuteAudio();
this.localStraem.getTracks().forEach((track) =>
track.start();
);
remoteStreamAddedHandler(e)
console.log('mute..........' + this.isMute)
console.log("remoteStreamAddedHandler", e);
this.state = STATE_INCALL;
this.buttonColor = COLOR_HANGOUT;
this.buttonLabel = LABEL_HANGOUT;
this.webRTCClient.addStreamInDiv(
e.detail.stream,
e.detail.callType,
"remote",
'remoteElt-' + e.detail.callId,
width: "200px", height: "200px" ,
this.isMute
);
setTimeout(this.refreshVideoView, 1000);
initMediaElementState(callId)
this.webRTCClient.removeElementFromDiv('mini', 'miniElt-' + callId);
this.webRTCClient.removeElementFromDiv('remote', 'remoteElt-' + callId);
还不确定您为什么尝试在构造函数中使用“bind(this)”。在构造函数中,“this”没有值。它是新对象(在您的情况下为 Homepage 类)的替代品。 'this' 的值将在创建新对象时成为新对象。
【讨论】:
对我来说一切正常,上面的代码除了 localstream 和静音选项。请通过这个链接,这样你会更清楚,然后回答我 FYI:github.com/apizee/ApiRTC-ionic 谢谢你 我尝试了您的代码,但无法正常工作。收到类似 TypeError 的错误:无法读取 null 的属性“createWebRTCClient”【参考方案2】:得到了静音选项的答案,这里是代码 只需将 userMediaSuccessHandler 替换为上述代码中的 userMediaSuccessHandler 方法
userMediaSuccessHandler(e)
console.log("userMediaSuccessHandler", e);
this.webRTCClient.addStreamInDiv(
e.detail.stream,
e.detail.callType,
"mini",
'miniElt-' + e.detail.callId,
width: "128px", height: "96px" ,
true
);
this.myStreemAudio = e.detail.stream;
myStreemAudio;
isMute = false;
muteCall(val)
if (val == 0)
this.myStreemAudio.getAudioTracks()[0].enabled = false;
else
this.myStreemAudio.getAudioTracks()[0].enabled = true;
console.log('de.........' + val)
muteVideo(val)
if (val == 0)
this.myStreemAudio.getVideoTracks()[0].enabled = false;
else
this.myStreemAudio.getVideoTracks()[0].enabled = true;
【讨论】:
以上是关于如何在 ionic 平台的 APIRTC 上静音和取消静音视频/音频?的主要内容,如果未能解决你的问题,请参考以下文章