ModuleBase.define("Audio", ["Base", "Error"], function(Base, Error) {
/**
* @desc 音频Audio构造函数。
* @constructor
* @alias Audio
* @param {String} id - 设备Id
* @param {String} name - 设备名称
*/
class Audio extends Base {
constructor(id, name, roomHandle) {
super(id, name);
this.roomHandle = roomHandle;
this.audioLevel = 0; //语音激励
this.isPubState = false; //防止重复发布,在发布过程中该状态为true
this.isMonitorAudioLevel = false;
this.monitorAudioLevelIntervalId = null;
this.openTimer = null;
this.closeTimer = null;
this.subscribleTimer = null;
this.unsubscribleTimer = null;
};
/**
* @desc 打开音频及把流渲染进视频控件,同时进行publish操作。
* @async
* @param {Object} element - 音频控件对象
*/
openMicrophone = function(element) {
log.info("===audio.openMicrophone()");
var deferred = when.defer();
var self = this;
if(self.roomHandle.roomJoinState != RoomStateEnum.CONNECTED){
var errObj = ErrorConstant.room_state_invalid
errObj.message += ("(State: "+ self.roomHandle.roomJoinState +")")
var err = new Error(errObj);
log.debug("===audio.openMicrophone() 发布视频流异常, room state: " + self.roomHandle.roomJoinState);
deferred.reject(err);
return;
}
// var error = doFsCheck(FTConstant.audio, Error)
// if(error) {
// deferred.reject(error);
// return deferred.promise;
// }
var orderId = getRandomNum(20000, 21000); //用于PubRoomResourceMsgRep中的ID
if(self.track) {
var microphoneUUID = self.roomHandle.setDeviceIdByUUID(2, self.id);
var audioStream = self.getNewStreamByTrack();
if(self.isPubState){
if(self.status == StreamStatus.published){
log.debug("===audio openMicrophone(self.track!=null),isPubState =true && self.status == StreamStatus.published to return");
deferred.resolve();
return deferred.promise;
}else if(self.status == StreamStatus.muted){
log.debug("===audio openMicrophone(self.track!=null),isPubState =true && self.status == StreamStatus.muted to audio.unmuteMicrophone()");
self.unmuteMicrophone();
deferred.resolve();
return deferred.promise;
}
}
if(self.isPubState){
log.debug("===audio openMicrophone(self.track!=null),isPubState =true to return");
deferred.resolve();
return deferred.promise;
}
self.isPubState = true;
self.roomHandle.masterServer.audioPublishHandle(microphoneUUID, audioStream, orderId);
clearTimeout(self.openTimer);
self.openTimer = setTimeout(function() {
self.isPubState = false;
log.debug("===audio openMicrophone(self.track!=null),pub_roomresourcemsg_rep timeout");
deferred.reject(new Error(ErrorConstant.operate_timeout.code, 'Release audio' + ErrorConstant.operate_timeout.message))
}, 3000)
self.roomHandle.addCallback(EngineCallback.pub_roomresourcemsg_rep_success, function(id) {
if(id == orderId) {
clearTimeout(self.openTimer);
self.state = StreamStatus.opened;
if(typeof(element) != 'undefined' && element && element != '') {
self.element = element;
element.srcObject = audioStream;
}
self.status = StreamStatus.published;
if(!self.roomHandle.hasObject(self.roomHandle.pubAudios,self)){
self.roomHandle.pubAudios.push(self);
}
log.info("===audio openMicrophone(),打开音频及发布流成功,callback microphone_status_notify (self.track!=null),status:"+self.status+",audioId:"+ self.id+",userId:"+self.ownerId);
avdEngineHandle.loggerReport.info("audio openMicrophone(),打开音频及发布流成功,(self.track!=null),audioId:"+ self.id+",userId:"+self.ownerId);
self.roomHandle.selfUser.eventEmitter.emit(UserCallback.microphone_status_notify, self.status, self.id, self.name, self.roomHandle.selfUser.id);
deferred.resolve();
}
});
self.roomHandle.addCallback(EngineCallback.pub_roomresourcemsg_rep_error, function(error, id) {
if(id == orderId) {
clearTimeout(self.openTimer);
self.isPubState = false;
log.error("===audio openMicrophone(),打开音频及发布流失败,(self.track!=null),audioId:"+ self.id+",userId:"+self.ownerId+",error:"+JSON.stringify(error));
avdEngineHandle.loggerReport.error("audio openMicrophone(),Failed to open audio and publish stream,(self.track!=null),audioId:"+ self.id+",userId:"+self.ownerId+",error:"+JSON.stringify(error));
deferred.reject(error);
}
});
} else {
obtainUserMedia(self, null).then(function(stream) {
self.track = stream.audioStream.getAudioTracks()[0];
if(self.roomHandle.selfUser.stream ==null){
self.roomHandle.selfUser.stream = stream.audioStream;
}else{
self.roomHandle.selfUser.stream.addTrack(self.track);
}
self.state = StreamStatus.opened;
var microphoneUUID = self.roomHandle.setDeviceIdByUUID(2, self.id);
var audioStream = self.getNewStreamByTrack();
if(self.isPubState){
log.debug("===audio openMicrophone(self.track=null),isPubState =true to return");
deferred.resolve();
return deferred.promise;
}
self.isPubState = true;
self.roomHandle.masterServer.audioPublishHandle(microphoneUUID, audioStream, orderId);
clearTimeout(self.openTimer);
self.openTimer = setTimeout(function() {
self.isPubState = false;
log.debug("===audio openMicrophone(self.track==null),pub_roomresourcemsg_rep timeout");
deferred.reject(new Error(ErrorConstant.operate_timeout.code, 'Release audio ' + ErrorConstant.operate_timeout.message))
}, 3000)
self.roomHandle.addCallback(EngineCallback.pub_roomresourcemsg_rep_success, function(id) {
if(id == orderId) {
clearTimeout(self.openTimer);
if(typeof(element) != 'undefined' && element && element != '') {
self.element = element;
element.srcObject = audioStream;
}
self.status = StreamStatus.published;
if(!self.roomHandle.hasObject(self.roomHandle.pubAudios,self)){
self.roomHandle.pubAudios.push(self);
}
log.info("===audio openMicrophone(),打开音频及发布流成功,callback microphone_status_notify (self.track==null),status:"+self.status+",audioId:"+ self.id+",userId:"+self.ownerId);
avdEngineHandle.loggerReport.info("audio openMicrophone(),打开音频及发布流成功,(self.track==null),audioId:"+ self.id+",userId:"+self.ownerId);
self.roomHandle.selfUser.eventEmitter.emit(UserCallback.microphone_status_notify, self.status, self.id, self.name, self.roomHandle.selfUser.id);
deferred.resolve();
}
});
self.roomHandle.addCallback(EngineCallback.pub_roomresourcemsg_rep_error, function(error, id) {
if(id == orderId) {
clearTimeout(self.openTimer);
self.isPubState = false;
log.error("===audio openMicrophone(),打开音频及发布流失败,(self.track==null),audioId:"+ self.id+",userId:"+self.ownerId+",error:"+JSON.stringify(error));
avdEngineHandle.loggerReport.error("audio openMicrophone(),Failed to open audio and publish stream,(self.track==null),audioId:"+ self.id+",userId:"+self.ownerId+",error:"+JSON.stringify(error));
deferred.reject(error);
}
});
}).otherwise(function(e) {
deferred.reject(e);
});
}
return deferred.promise;
};
/**
* @desc 关闭音频,同时进行unpublish操作。
* @async
*/
closeMicrophone = function() {
log.info("===audio.closeMicrophone()");
var deferred = when.defer();
var self = this;
var orderId = getRandomNum(21001, 22000);
if(self.status == StreamStatus.published || self.status == StreamStatus.muted) {
self.isPubState = false;
arrayUtil.objectSplice(self.roomHandle.pubAudios, this.id);
self.status = StreamStatus.init;
self.roomHandle.selfUser.eventEmitter.emit(UserCallback.microphone_status_notify, self.status, self.id, self.name, self.roomHandle.selfUser.id);
var microphoneUUID = self.roomHandle.setDeviceIdByUUID(2, self.id);
var audioStream = self.getNewStreamByTrack();
self.roomHandle.masterServer.audioUnpublishHandle(microphoneUUID, audioStream, orderId);
clearTimeout(self.closeTimer);
self.closeTimer = setTimeout(function() {
self.isPubState = false;
log.debug("===audio closeMicrophone,unpub_roomresourcemsg_rep timeout");
deferred.reject(new Error(ErrorConstant.operate_timeout.code, 'Unpublish audio' + ErrorConstant.operate_timeout.message))
}, 3000);
self.roomHandle.addCallback(EngineCallback.unpub_roomresourcemsg_rep_success, function(id) {
if(id == orderId) {
clearTimeout(self.closeTimer);
//第三方导入流closeMicrophone时,不对本地track清场,在user.deleteCustomAudioTrack()时统一清场。
if(self.id.indexOf('custom_audio') !== -1 ){
self.setAudioLevel(0);
var stream = self.roomHandle.selfUser.stream;
if(stream){
stream.getTracks().forEach(function(track) {
if(self.track && self.track.id == track.id){
track.stop();
}
});
}
if(self.element) {
var elementStream = self.element.srcObject;
if(elementStream){
elementStream.getTracks().forEach(function(track) {
track.stop();
});
}
self.element.srcObject = null;
self.element = null;
}
self.track.stop();
self.track = null;
}
log.info("===audio closeMicrophone(),关闭音频及取消发布流. audioId:"+ self.id+",userId:"+self.ownerId);
avdEngineHandle.loggerReport.info("audio closeMicrophone(),关闭音频及取消发布流操作. audioId:"+ self.id+",userId:"+self.ownerId);
setTimeout(function(){
deferred.resolve();
},50);
}
});
self.roomHandle.addCallback(EngineCallback.unpub_roomresourcemsg_rep_error, function(error, id) {
if(id == orderId) {
clearTimeout(self.closeTimer);
self.isPubState = false;
log.error("===audio closeMicrophone(),关闭音频及发布流失败. audioId:"+ self.id+",userId:"+self.ownerId+",error:"+JSON.stringify(error));
avdEngineHandle.loggerReport.error("audio closeMicrophone(),Failed to close the audio and publish stream. audioId:"+ self.id+",userId:"+self.ownerId+",error:"+JSON.stringify(error));
deferred.reject(error);
}
});
}
return deferred.promise;
};
/**
* @desc 订阅音频流
* @async
*/
subscrible = function() {
log.info("===audio subscrible(),订阅音频流操作, audioId:"+ this.id+",userId:"+this.ownerId);
avdEngineHandle.loggerReport.info("audio subscrible(),订阅音频流操作, audioId:"+ this.id+",userId:"+this.ownerId);
var deferred = when.defer();
var orderId = getRandomNum(22001, 23000);
var self = this;
self.roomHandle.masterServer.audioSubscribleHandle(self.resourceInfo,orderId);
clearTimeout(self.subscribleTimer);
self.subscribleTimer = setTimeout(function() {
log.debug("===audio subscrible, sub_roomresourcemsg_rep_success timeout");
deferred.reject(new Error(ErrorConstant.operate_timeout.code, 'Subscribe to audio' + ErrorConstant.operate_timeout.message))
}, 3000);
self.roomHandle.addCallback(EngineCallback.sub_roomresourcemsg_rep_success, function(id) {
if(id == orderId) {
clearTimeout(self.subscribleTimer);
setTimeout(function(){
log.info("===audio subscrible(),订阅音频流成功,audioId:"+ self.id+",userId:"+self.ownerId);
deferred.resolve();
},50);
}
});
self.roomHandle.addCallback(EngineCallback.sub_roomresourcemsg_rep_error, function(error, id) {
if(id == orderId) {
clearTimeout(self.subscribleTimer);
deferred.reject(error);
}
});
return deferred.promise;
}
/**
* @desc 取消订阅音频流
* @async
*/
unsubscrible = function() {
log.info("===audio unsubscrible(),取消订阅音频流操作,audioId:"+ this.id+",userId:"+this.ownerId);
avdEngineHandle.loggerReport.info("audio unsubscrible(),取消订阅音频流操作,audioId:"+ this.id+",userId:"+this.ownerId);
var deferred = when.defer();
var orderId = getRandomNum(23001, 24000);
var self = this;
//console.log("===audio unsubscrible(),this.resourceInfo.stream.stream_name:"+this.resourceInfo.stream.stream_name);
self.roomHandle.masterServer.audioUnsubscribleHandle(this.resourceInfo,orderId);
clearTimeout(self.unsubscribleTimer);
self.unsubscribleTimer = setTimeout(function() {
log.debug("===audio unsubscrible, unsub_roomresourcemsg_rep_success timeout");
deferred.reject(new Error(ErrorConstant.operate_timeout.code, 'Unsubscribe Audio' + ErrorConstant.operate_timeout.message))
}, 3000);
self.roomHandle.addCallback(EngineCallback.unsub_roomresourcemsg_rep_success, function(id) {
if(id == orderId) {
clearTimeout(self.unsubscribleTimer);
setTimeout(function(){
log.info("===audio unsubscrible(),取消订阅音频流成功,audioId:"+ self.id+",userId:"+self.ownerId);
deferred.resolve();
},50);
}
});
self.roomHandle.addCallback(EngineCallback.unsub_roomresourcemsg_rep_error, function(error, id) {
if(id == orderId) {
clearTimeout(self.unsubscribleTimer);
deferred.reject(error);
}
});
return deferred.promise;
}
/**
* @desc 禁音
*/
muteMicrophone = function() {
log.info("===audio.muteMicrophone()");
var self = this;
if(this.status == StreamStatus.published) {
this.status = StreamStatus.muted;
self.roomHandle.selfUser.eventEmitter.emit(UserCallback.microphone_status_notify, this.status, this.id, this.name, self.roomHandle.selfUser.id);
var stream = self.roomHandle.selfUser.stream;
stream.getTracks().forEach(function(track) {
if(track.id == self.track.id){
track.enabled = false;
}
});
if(self.element) {
var elementStream = self.element.srcObject;
if(elementStream){
elementStream.getTracks().forEach(function(track) {
if(track.id == self.track.id){
track.enabled = false;
}
});
}
}
if(self.track){
self.track.enabled = false;
}
var senders = self.roomHandle.traceablePeerConnection.getToMCUPeerConnection().getSenders();
//console.log("AAAAAAA00000000,senders:",senders);
if(senders){
for (var i = 0; i < senders.length; i++) {
var sender = senders[i];
//console.log("AAAAAAA1111111111111,sender:",sender);
if(sender && sender.track && sender.track.kind == "audio" && sender.track.id == self.track.id){
// console.log("AAAAAAA2222222222,sender.track.enabled:",sender.track.enabled);
sender.track.enabled = false;
}
}
}
var microphoneUUID = self.roomHandle.setDeviceIdByUUID(2, this.id);
self.roomHandle.masterServer.updateSpeakerMsg(self.roomHandle.selfUser.nodeId, microphoneUUID, this);
log.info("===audio muteMicrophone(),禁音. Id:"+ self.id+",ownerId:"+self.ownerId+",status:"+self.status);
avdEngineHandle.loggerReport.info("audio muteMicrophone(),禁音. Id:"+ self.id+",ownerId:"+self.ownerId+",status:"+self.status);
}
};
/**
* @desc 取消禁音
*/
unmuteMicrophone = function() {
log.info("===audio.unmuteMicrophone()");
var self = this;
if(this.status == StreamStatus.muted) {
this.status = StreamStatus.published;
self.roomHandle.selfUser.eventEmitter.emit(UserCallback.microphone_status_notify, this.status, this.id, this.name, self.roomHandle.selfUser.id);
var stream = self.roomHandle.selfUser.stream;
stream.getTracks().forEach(function(track) {
if(track.id == self.track.id){
track.enabled = true;
}
});
if(self.element) {
var elementStream = self.element.srcObject;
if(elementStream){
elementStream.getTracks().forEach(function(track) {
if(track.id == self.track.id){
track.enabled = true;
}
});
}
}
if(self.track){
self.track.enabled = true;
}
var senders = self.roomHandle.traceablePeerConnection.getToMCUPeerConnection().getSenders();
if(senders){
for (var i = 0; i < senders.length; i++) {
var sender = senders[i];
if(sender && sender.track && sender.track.kind == "audio" && sender.track.id == self.track.id){
sender.track.enabled = true;
}
}
}
var microphoneUUID = self.roomHandle.setDeviceIdByUUID(2, this.id);
self.roomHandle.masterServer.updateSpeakerMsg(self.roomHandle.selfUser.nodeId, microphoneUUID, this);
log.info("===audio unmuteMicrophone(),取消禁音. Id:"+ self.id+",ownerId:"+self.ownerId+",status:"+self.status);
avdEngineHandle.loggerReport.info("audio unmuteMicrophone(),取消禁音. Id:"+ self.id+",ownerId:"+self.ownerId+",status:"+self.status);
}
};
/**
* @desc 获取禁音状态
*/
ismuteMicrophone = function() {
var ismute = false;
if(this.status == StreamStatus.muted) {
ismute = true;
}
return ismute;
};
/**
* @desc 设置语音激励级别
* @param {int} audioLevel -语音激励级别
*/
setAudioLevel = function(audioLevel) {
this.audioLevel = audioLevel;
};
/**
* @desc 获取语音激励级别
*/
getAudioLevel = function() {
return this.audioLevel;
};
}
return Audio;
});