wildfire-im-sdk
Version:
野火IM SDK for Vue3 projects
338 lines (294 loc) • 12.9 kB
JavaScript
import {EventEmitter} from "events";
import wfc from "../../client/wfc";
import PttClientImpl from "../internal/ptt.min";
import PttErrorCode from "./pttErrorCode";
import ConversationType from "../../model/conversationType";
import GroupMemberType from "../../model/groupMemberType";
import NullGroupInfo from "../../model/nullGroupInfo";
import ModifyGroupInfoType from "../../model/modifyGroupInfoType";
import UserSettingScope from "../../client/userSettingScope";
import PttEventType from "./pttEventType";
export class PttClient {
/**
* 只在正常模式下生效
* 单聊会话里面,最多允许几个人同时说话
*/
static SINGLE_CHAT_MAX_SPEAKER_COUNT = 1;
/**
* 只在正常模式下生效
* 群会话里面,最多允许几个人同时说话
*/
static GROUP_CHAT_MAX_SPEAKER_COUNT = 3;
// 对讲时,是否发送额外的语音消息
static SINGLE_CHAT_SEND_VOICE_MESSAGE = true;
static GROUP_CHAT_SEND_VOICE_MESSAGE = true;
/**
* 单位是秒
*/
static SINGLE_CHAT_MAX_SPEAK_TIME = 60;
/**
* 单位是秒
*/
static GROUP_CHAT_MAX_SPEAK_TIME = 60;
/**
* 对讲模式
* 默认是正常模式
* 1. 正常模式,用户可以同时播放多路对讲,一个会话里面,可以配置允许多个人同时说话
* 2. 优先级模式,用户只能播放优先级最高的那路对讲,一个会话里面,只允许一个人说话
*/
static ENABLE_PRIORITY_MODE = false;
/**
* 全局开启对讲功能,为false时,会话需要分别开启 {@link PTTClient#setEnablePtt}
*/
static ENABLE_GLOBAL_PTT = true;
// 是否支持双工模式,双工模式下,说话的时候,允许收听其他人的说话。
static ENABLE_FULL_DUPLEX = false;
/**
* 事件通知,{@link PttEventType}中定义的事件,都会采用本{@link eventEmitter} 通知
* @type {module:events.internal.EventEmitter}
*/
eventEmitter = new EventEmitter();
deltaTime;
conversationPttStatusMap = new Map();
pttClientImpl;
// 初始化
init() {
if (this.pttClientImpl) {
console.warn('already init')
return;
}
this.deltaTime = wfc.getServerDeltaTime();
this.pttClientImpl = new PttClientImpl(this.eventEmitter);
this.pttClientImpl.init();
this._eventTest();
}
uninit() {
if (!this.pttClientImpl) {
return;
}
this.pttClientImpl.end();
this.pttClientImpl = null;
}
/**
* 请求说话
* @param conversation
* @param talkingCallback
*/
requestTalk(conversation, talkingCallback) {
console.log('requestTalk', conversation, talkingCallback)
if (!talkingCallback || !this.pttClientImpl || !conversation) {
console.error('can not requestTalk, callback is null or not init')
return;
}
if (!PttClient.ENABLE_GLOBAL_PTT) {
let enabled = this.conversationPttStatusMap.get(this._conversationKey(conversation));
if (!enabled) {
talkingCallback.onRequestFail(conversation, PttErrorCode.PTT_DISABLED);
return;
}
}
if (this.pttClientImpl.recordingSession) {
talkingCallback.onRequestFail(conversation, PttErrorCode.TALKING);
return;
}
let maxSpeakerCount = 1;
if (!PttClient.ENABLE_PRIORITY_MODE) {
maxSpeakerCount = conversation.type === ConversationType.Single ? PttClient.SINGLE_CHAT_MAX_SPEAKER_COUNT : PttClient.GROUP_CHAT_MAX_SPEAKER_COUNT;
}
let maxDurationMillis = PttClient.SINGLE_CHAT_MAX_SPEAK_TIME * 1000;
let sendVoiceMessage = conversation.type === ConversationType.Single ? PttClient.SINGLE_CHAT_SEND_VOICE_MESSAGE : PttClient.GROUP_CHAT_SEND_VOICE_MESSAGE;
if (conversation.type === ConversationType.Group) {
maxDurationMillis = PttClient.GROUP_CHAT_MAX_SPEAK_TIME * 1000;
let groupInfo = wfc.getGroupInfo(conversation.target, false);
if (!groupInfo || groupInfo instanceof NullGroupInfo) {
console.error('requestTalk failed, groupInfo is null')
talkingCallback.onRequestFail(conversation, -1);
return;
}
let selfUid = wfc.getUserId();
let groupMember = wfc.getGroupMember(conversation.target, selfUid);
if (groupInfo.mute === 1 && (groupMember.type !== GroupMemberType.Owner && groupMember.type !== GroupMemberType.Manager)) {
talkingCallback.onRequestFail(conversation, PttErrorCode.GROUP_MUTED);
return;
} else if (groupMember.type === GroupMemberType.Muted) {
talkingCallback.onRequestFail(conversation, PttErrorCode.GROUP_MEMBER_MUTED);
return;
}
let groupExtra = groupInfo.extra;
if (groupExtra) {
try {
let obj = JSON.parse(groupExtra);
maxSpeakerCount = !PttClient.ENABLE_PRIORITY_MODE && obj.hasOwnProperty('n') ? obj.n : 1;
sendVoiceMessage = obj.hasOwnProperty('s') ? obj.s : sendVoiceMessage;
maxDurationMillis = obj.hasOwnProperty('t') ? obj.t : PttClient.GROUP_CHAT_MAX_SPEAK_TIME;
maxDurationMillis = maxDurationMillis * 1000;
} catch (e) {
console.error('parse groupExtra error', e);
}
}
}
let talkingMemberCount = this.getTalkingMembers(conversation);
if (maxSpeakerCount === 1) {
if (talkingMemberCount === 1) {
talkingCallback.onRequestFail(conversation, PttErrorCode.MAX_SPEAKER);
} else {
let priority = talkingCallback.talkingPriority(conversation);
wfc.requireLock('WFPTT_' + conversation.target, 5, () => {
this.pttClientImpl._startTalk(conversation, maxDurationMillis, sendVoiceMessage, priority, talkingCallback)
}, err => {
talkingCallback.onRequestFail(conversation, PttErrorCode.OCCUPIED);
})
}
} else if (maxSpeakerCount === 0 || maxSpeakerCount > talkingMemberCount) {
let priority = talkingCallback.talkingPriority(conversation);
this.pttClientImpl._startTalk(conversation, maxDurationMillis, sendVoiceMessage, priority, talkingCallback)
} else {
talkingCallback.onRequestFail(conversation, PttErrorCode.MAX_SPEAKER);
}
}
// 说话结束
releaseTalk(conversation) {
if (!this.pttClientImpl) {
return;
}
this.pttClientImpl.stopRecord();
}
/**
* 获取频道允许同时说话人数
*/
getMaxSpeakCount(conversation) {
if (conversation.type === ConversationType.Group) {
let extra = this._getGroupExtra(conversation.target);
return extra.hasOwnProperty('n') ? extra.n : PttClient.GROUP_CHAT_MAX_SPEAKER_COUNT;
} else {
return PttClient.SINGLE_CHAT_MAX_SPEAKER_COUNT;
}
}
isSendVoiceMessage(conversation) {
if (conversation.type === ConversationType.Group) {
let extra = this._getGroupExtra(conversation.target);
return extra.hasOwnProperty('s') ? extra.s : PttClient.GROUP_CHAT_SEND_VOICE_MESSAGE;
} else {
return PttClient.SINGLE_CHAT_SEND_VOICE_MESSAGE;
}
}
getMaxSpeakTime(conversation) {
if (conversation.type === ConversationType.Group) {
let extra = this._getGroupExtra(conversation.target);
return extra.hasOwnProperty('t') ? extra.t : PttClient.GROUP_CHAT_MAX_SPEAK_TIME;
} else {
return PttClient.SINGLE_CHAT_MAX;
}
}
setSendVoiceMessage(conversation, send, successCB, failCB) {
if (conversation.type === ConversationType.Group) {
let obj = this._getGroupExtra(conversation.target);
obj['s'] = send;
this._updateGroupExtra(conversation.target, conversation.line, obj, successCB, failCB)
} else {
failCB && failCB(-1);
console.error('错误,此方法只在群组有效')
}
}
setConversationMaxSpeakTime(conversation, duration, successCB, failCB) {
if (conversation.type === ConversationType.Group) {
let obj = this._getGroupExtra(conversation.target);
obj['t'] = duration;
this._updateGroupExtra(conversation.target, conversation.line, obj, successCB, failCB)
} else {
failCB && failCB(-1);
console.error('错误,此方法只在群组有效')
}
}
setConversationMaxSpeakerCount(conversation, count, successCB, failCB) {
if (conversation.type === ConversationType.Group) {
let obj = this._getGroupExtra(conversation.target);
obj['n'] = count;
this._updateGroupExtra(conversation.target, conversation.line, obj, successCB, failCB)
} else {
failCB && failCB(-1);
console.error('错误,此方法只在群组有效')
}
}
setConversationPttSilent(conversation, silent, successCB, failCB) {
let key = conversation.target + '-' + conversation.type + '-' + conversation.line;
wfc.setUserSetting(UserSettingScope.PttSilent, key, silent ? "1" : 0, successCB, failCB);
if (this.pttClientImpl){
this.pttClientImpl.setConversationPttSilent(conversation, silent)
}
}
isConversationPttSilent(conversation) {
let key = conversation.target + '-' + conversation.type + '-' + conversation.line;
let value = wfc.getUserSetting(UserSettingScope.PttSilent, key);
return value === '1';
}
getTalkingConversation() {
return this.pttClientImpl.getTalkingConversation();
}
getTalkingStartTime() {
return this.pttClientImpl.getTalkingStartTime();
}
getTalkingMembers(conversation) {
return this.pttClientImpl.getTalkingMembers(conversation);
}
getTalkingMemberCount(conversation) {
return this.pttClientImpl.getTalkingMembers(conversation).length;
}
setEnablePtt(conversation, enable) {
if (!conversation) {
this.conversationPttStatusMap.set(this._conversationKey(conversation), enable);
}
}
_conversationKey(conversation) {
return conversation.type + '-' + conversation.target + '-' + conversation.line;
}
_getGroupExtra(groupId) {
let groupInfo = wfc.getGroupInfo(groupId, false);
let obj = {};
if (!groupInfo || groupInfo instanceof NullGroupInfo || !groupInfo.extra) {
return obj;
}
try {
return JSON.parse(groupInfo.extra);
} catch (e) {
console.error('parse group extra error', e)
}
return obj;
}
// TODO more api
_updateGroupExtra(groupId, notifyLine, extra, successCB, failCB) {
extra = !extra ? {} : extra;
wfc.modifyGroupInfo(groupId, ModifyGroupInfoType.Modify_Group_Extra, JSON.stringify(extra), [notifyLine], null, successCB, failCB);
}
_eventTest() {
// //某人开始在频道中讲话
// // function (conversation, userId) {}
// static userStartTalking = 'userStartTalking'
//
// //某人结束在频道中讲话
// // function (conversation, userId) {}
// static userEndTalking = 'userEndTalking'
//
// //接收到用户自定义数据
// // function (conversation, userId, data) {}
// static receiveData = 'receiveData';
//
// //用户说话音量大小回调
// // function (conversation, userId, averageAmplitude) {}
// static userAmplitudeUpdate = 'userAmplitudeUpdate';
this.eventEmitter.on(PttEventType.userStartTalking, (conversation, userId) => {
console.log('userStartTalking', conversation, userId);
})
this.eventEmitter.on(PttEventType.userEndTalking, (conversation, userId) => {
console.log('userEndTalking', conversation, userId);
})
this.eventEmitter.on(PttEventType.receiveData, (conversation, userId, data) => {
console.log('receiveData', conversation, userId, data);
})
this.eventEmitter.on(PttEventType.userAmplitudeUpdate, (conversation, userId, averageAmplitude) => {
console.log('userAmplitudeUpdate', conversation, userId, averageAmplitude);
})
}
}
const self = new PttClient();
export default self;