diff --git a/TrtcCloud/lib/TrtcCloudImpl.js b/TrtcCloud/lib/TrtcCloudImpl.js new file mode 100644 index 0000000..74d6bc1 --- /dev/null +++ b/TrtcCloud/lib/TrtcCloudImpl.js @@ -0,0 +1,664 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { NAME } from './constants'; +import { TRTCRoleType, TRTCAudioQuality, TRTCVideoRotation, TRTCVideoFillMode, TRTCVideoMirrorType, TRTCVideoStreamType, TRTCVideoEncParam, TRTCAppScene, TRTCAudioRoute, TRTCBeautyStyle, } from './TrtcDefines'; +import TrtcError, { TXLiteJSError, generateError_ } from './TrtcCode'; +const TrtcNativeTrtcCloudModule = uni.requireNativePlugin('TRTCCloudUniPlugin-TRTCCloudImpl'); +const TXAudioEffectManagerModule = uni.requireNativePlugin('TRTCCloudUniPlugin-TRTCCloudImpl-TXAudioEffectManagerModule'); +const TrtcEvent = uni.requireNativePlugin('globalEvent'); +let trtcCloud = null; // trtcCloud 单例 +export default class TrtcCloudImpl { + constructor() { + this.listenersMap_ = new Map(); + } + static _createInstance() { + try { + if (trtcCloud) { + return trtcCloud; + } + TrtcNativeTrtcCloudModule.sharedInstance(); + trtcCloud = new TrtcCloudImpl(); + return trtcCloud; + } + catch (error) { + throw generateError_(error); + } + } + static _getInstance() { + if (trtcCloud) { + return trtcCloud; + } + throw new TrtcError({ + code: TXLiteJSError.INVALID_OPERATION, + message: 'get trtcCloud failed, please create trtcCloud first', + }); + } + static _destroyInstance() { + try { + trtcCloud = null; + TrtcNativeTrtcCloudModule.destroySharedInstance(); + } + catch (error) { + throw new TrtcError({ + code: error.code || TXLiteJSError.UNKNOWN, + message: error.message, + name: error.name, + }); + } + } + // 截图保存 + // async saveImage_(base64Data) { + // return new Promise((resolve, reject) => { + // let bitmap = new plus.nativeObj.Bitmap(); + // bitmap.loadBase64Data(base64Data, () => { + // const url = "_doc/" + new Date().getTime() + ".png"; // url为时间戳命名方式 + // console.log('saveHeadImgFile', url); + // bitmap.save(url, { overwrite: true }, (i) => { + // uni.saveImageToPhotosAlbum({ + // filePath: url, + // success: function() { + // uni.showToast({ + // title: '图片保存成功', + // icon: 'none' + // }) + // bitmap.clear(); + // resolve({ code: 0, message: '图片保存成功' }); + // } + // }); + // }, (e) => { + // uni.showToast({ + // title: '图片保存失败, 请重新截图', + // icon: 'none' + // }) + // bitmap.clear(); + // resolve({ code: -1, message: '图片保存失败, 请重新截图' }); + // }); + // }); + // }); + // } + on(event, callback) { + if (typeof event !== NAME.STRING || typeof callback !== NAME.FUNCTION) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the on method parameter types. event type is a ${typeof event}; callback type is a ${typeof callback}`, + }); + } + const nativeListener = (res) => __awaiter(this, void 0, void 0, function* () { + const { data = [] } = res; + const code = data[0]; + const message = data[1] || ''; + const extraInfo = data[2] || {}; + switch (event) { + case 'onEnterRoom': { + const result = code; + callback(result); + break; + } + case 'onExitRoom': { + const reason = code; + callback(reason); + break; + } + case 'onFirstVideoFrame': { + const userId = code; + const streamType = data[1] || 0; + const width = data[2] || 0; + const height = data[3] || 0; + callback({ userId, streamType, width, height }); + break; + } + case 'onFirstAudioFrame': { + const userId = code || ''; + callback(userId); + break; + } + case 'onMicDidReady': { + callback(); + break; + } + case 'onCameraDidReady': { + callback(); + break; + } + case 'onNetworkQuality': { + const localQuality = data[0]; + const remoteQuality = data[1]; + callback({ localQuality, remoteQuality }); + break; + } + case 'onRemoteUserEnterRoom': { + const userId = code || ''; + callback(userId); + break; + } + case 'onRemoteUserLeaveRoom': { + const userId = code || ''; + const reason = message; + callback({ userId, reason }); + break; + } + case 'onSendFirstLocalAudioFrame': { + callback(); + break; + } + case 'onSendFirstLocalVideoFrame': { + const streamType = code; + callback(streamType); + break; + } + case 'onStatistics': { + const statics = data[0] || {}; + callback(statics); + break; + } + case 'onUserAudioAvailable': { + const userId = code || ''; + const available = message; + callback({ userId, available }); + break; + } + case 'onUserVideoAvailable': { + const userId = code || ''; + const available = message; + callback({ userId, available }); + break; + } + case 'onUserVoiceVolume': { + const userVolumes = data[0]; + const totalVolume = data[1]; + callback({ userVolumes, totalVolume }); + break; + } + case 'onSwitchRole': { + callback({ code, message }); + break; + } + case 'onScreenCaptureStarted': { + callback({ code, message }); + break; + } + case 'onScreenCapturePaused': { + callback({ code, message }); + break; + } + case 'onScreenCaptureResumed': { + callback({ code, message }); + break; + } + case 'onScreenCaptureStopped': { + callback({ code, message }); + break; + } + case 'onUserSubStreamAvailable': { + const userId = code || ''; + const available = message; + callback({ userId, available }); + break; + } + case 'onSnapshotComplete': { + // base64 直接保存到本地图库 + // const { code: snapShotCode, message: msg } = await this.saveImage_(code); + // callback({ snapShotCode, message: msg }); + callback({ base64Data: code, message }); + break; + } + case 'onUserVideoSizeChanged': { + callback(data); + break; + } + case 'onStart': { + callback({ id: code, errCode: message }); + break; + } + case 'onPlayProgress': { + callback({ id: code, curPtsMS: message, durationMS: extraInfo }); + break; + } + case 'onComplete': { + callback({ id: code, errCode: message }); + break; + } + case 'onError': { + console.error(`onError: ${code}, ${message}, ${extraInfo}`); + callback(generateError_({ message }, code, extraInfo)); + break; + } + default: { + callback({ code, message, extraInfo }); + } + } + }); + this.listenersMap_.set(event, nativeListener); // 多次设置同一个事件时,后面的 callback 覆盖前面 + TrtcEvent.addEventListener(event, nativeListener); + } + off(event) { + if (typeof event !== NAME.STRING) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the off method parameter types. event type is a ${typeof event} not a ${NAME.STRING}`, + }); + } + try { + if (event === '*') { + this.listenersMap_.forEach((value, key) => { + TrtcEvent.removeEventListener(key, value); + }); + this.listenersMap_.clear(); + } + else { + TrtcEvent.removeEventListener(event, this.listenersMap_.get(event)); + this.listenersMap_.delete(event); + } + } + catch (error) { + throw generateError_(error); + } + } + enterRoom(params, scene) { + if (scene !== TRTCAppScene.TRTCAppSceneVideoCall && scene !== TRTCAppScene.TRTCAppSceneLIVE && scene !== TRTCAppScene.TRTCAppSceneAudioCall && scene !== TRTCAppScene.TRTCAppSceneVoiceChatRoom) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the enterRoom method parameters. scene is not of TRTCAppScene`, + }); + } + try { + const enterRoomParams = Object.assign(Object.assign({}, params), { role: params.role || TRTCRoleType.TRTCRoleAnchor, appScene: scene }); + TrtcNativeTrtcCloudModule.enterRoom(enterRoomParams); + } + catch (error) { + throw generateError_(error); + } + } + exitRoom() { + try { + TrtcNativeTrtcCloudModule.exitRoom(); + } + catch (error) { + throw generateError_(error); + } + } + switchRole(role) { + if (role !== TRTCRoleType.TRTCRoleAnchor && role !== TRTCRoleType.TRTCRoleAudience) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the switchRole method parameter. role is not of TRTCRoleType`, + }); + } + try { + role && TrtcNativeTrtcCloudModule.switchRole(role); + } + catch (error) { + throw generateError_(error); + } + } + startLocalPreview(isFrontCamera = true, viewId) { + if (typeof isFrontCamera !== NAME.BOOLEAN || !viewId || typeof viewId !== NAME.STRING) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the startLocalPreview method parameters`, + }); + } + try { + let param = { isFrontCamera: !!isFrontCamera }; + param = viewId ? Object.assign(Object.assign({}, param), { userId: viewId }) : param; + TrtcNativeTrtcCloudModule.startLocalPreview(param); + } + catch (error) { + throw generateError_(error); + } + } + setVideoEncoderParam(param) { + try { + TrtcNativeTrtcCloudModule.setVideoEncoderParam(param); + } + catch (error) { + throw generateError_(error); + } + } + stopLocalPreview() { + try { + TrtcNativeTrtcCloudModule.stopLocalPreview(); + } + catch (error) { + throw generateError_(error); + } + } + switchCamera(isFrontCamera) { + if (typeof isFrontCamera !== NAME.BOOLEAN) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the switchCamera method parameter`, + }); + } + try { + TrtcNativeTrtcCloudModule.switchCamera(isFrontCamera); + } + catch (error) { + throw generateError_(error); + } + } + setLocalRenderParams(params) { + try { + const { rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fill, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Auto } = params; + TrtcNativeTrtcCloudModule.setLocalRenderParams({ + rotation, + fillMode, + mirrorType, + }); + } + catch (error) { + throw generateError_(error); + } + } + muteLocalVideo(streamType, mute) { + if (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub || typeof mute !== NAME.BOOLEAN) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the muteLocalVideo method parameters`, + }); + } + try { + TrtcNativeTrtcCloudModule.muteLocalVideo({ streamType, mute: !!mute }); + } + catch (error) { + throw generateError_(error); + } + } + startRemoteView(userId, streamType, viewId) { + if (!userId || streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSmall && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub || !viewId) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the startRemoteView method parameters`, + }); + } + try { + TrtcNativeTrtcCloudModule.startRemoteView({ userId, streamType, viewId }); + } + catch (error) { + throw generateError_(error); + } + } + stopRemoteView(userId, streamType) { + if (!userId || streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSmall && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the stopRemoteView method parameters`, + }); + } + try { + TrtcNativeTrtcCloudModule.stopRemoteView({ userId, streamType }); + } + catch (error) { + throw generateError_(error); + } + } + // 远端渲染设置 + setRemoteRenderParams(userId, streamType, params) { + try { + if (!userId || (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub)) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the snapshotVideo method parameters`, + }); + } + const { rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fill, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Auto } = params; + TrtcNativeTrtcCloudModule.setRemoteRenderParams({ + userId, + streamType, + rotation, + fillMode, + mirrorType + }); + } + catch (error) { + throw generateError_(error); + } + } + // 截图 + snapshotVideo(userId, streamType) { + if (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the snapshotVideo method parameters`, + }); + } + try { + TrtcNativeTrtcCloudModule.snapshotVideo({ userId: userId || null, streamType }); + } + catch (error) { + throw generateError_(error); + } + } + startLocalAudio(quality = TRTCAudioQuality.TRTCAudioQualityDefault) { + if (quality !== TRTCAudioQuality.TRTCAudioQualitySpeech && quality !== TRTCAudioQuality.TRTCAudioQualityDefault && quality !== TRTCAudioQuality.TRTCAudioQualityMusic) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the startLocalAudio method parameters`, + }); + } + try { + TrtcNativeTrtcCloudModule.startLocalAudio(quality); + } + catch (error) { + throw generateError_(error); + } + } + stopLocalAudio() { + try { + TrtcNativeTrtcCloudModule.stopLocalAudio(); + } + catch (error) { + throw generateError_(error); + } + } + muteLocalAudio(mute) { + if (typeof mute !== NAME.BOOLEAN) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the muteLocalAudio method parameters, mute type is a ${typeof mute} not a ${NAME.BOOLEAN}`, + }); + } + try { + TrtcNativeTrtcCloudModule.muteLocalAudio(!!mute); + } + catch (error) { + throw generateError_(error); + } + } + muteRemoteAudio(userId, mute) { + if (typeof mute !== NAME.BOOLEAN || !userId) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the muteRemoteAudio method parameters`, + }); + } + try { + TrtcNativeTrtcCloudModule.muteRemoteAudio({ userId, mute: !!mute }); + } + catch (error) { + throw generateError_(error); + } + } + muteAllRemoteAudio(mute) { + if (typeof mute !== NAME.BOOLEAN) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the muteAllRemoteAudio method parameters, mute type is a ${typeof mute} not a ${NAME.BOOLEAN}`, + }); + } + try { + TrtcNativeTrtcCloudModule.muteAllRemoteAudio(!!mute); + } + catch (error) { + throw generateError_(error); + } + } + setAudioRoute(route) { + if (route !== TRTCAudioRoute.TRTCAudioRouteSpeaker && route !== TRTCAudioRoute.TRTCAudioRouteEarpiece) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the setAudioRoute method parameter, route is not of TRTCAudioRoute`, + }); + } + try { + TrtcNativeTrtcCloudModule.setAudioRoute(route); + } + catch (error) { + throw generateError_(error); + } + } + enableAudioVolumeEvaluation(interval) { + if (typeof interval !== NAME.NUMBER) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the enableAudioVolumeEvaluation method parameter, interval type is a ${typeof interval} not a ${NAME.NUMBER}`, + }); + } + try { + interval > 0 && TrtcNativeTrtcCloudModule.enableAudioVolumeEvaluation(interval); + } + catch (error) { + throw generateError_(error); + } + } + // /////////////////////////////////////////////////////////////////////////////// + // + // 美颜 + 水印 + // + // /////////////////////////////////////////////////////////////////////////////// + setBeautyStyle(beautyStyle) { + if (beautyStyle !== TRTCBeautyStyle.TRTCBeautyStyleSmooth && beautyStyle !== TRTCBeautyStyle.TRTCBeautyStyleNature && beautyStyle !== TRTCBeautyStyle.TRTCBeautyStylePitu) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the setBeautyStyle method parameter, beautyStyle is not of TRTCBeautyStyle`, + }); + } + try { + TrtcNativeTrtcCloudModule.setBeautyStyle(beautyStyle); + } + catch (error) { + throw generateError_(error); + } + } + setBeautyLevel(beautyLevel) { + if (typeof beautyLevel !== NAME.NUMBER || (beautyLevel < 0 || beautyLevel > 9)) { + throw new TrtcError({ + code: TXLiteJSError.INVALID_PARAMETER, + message: `${NAME.LOG_PREFIX} please check the setBeautyLevel method parameter, beautyLevel should in the range 0-9`, + }); + } + try { + TrtcNativeTrtcCloudModule.setBeautyLevel(beautyLevel); + } + catch (error) { + throw generateError_(error); + } + } + // /////////////////////////////////////////////////////////////////////////////// + // + // 背景音效 + // + // /////////////////////////////////////////////////////////////////////////////// + startPlayMusic(musicParam) { + try { + TXAudioEffectManagerModule.startPlayMusic(musicParam); + } + catch (error) { + throw generateError_(error); + } + } + stopPlayMusic(id) { + try { + TXAudioEffectManagerModule.stopPlayMusic(id); + } + catch (error) { + throw generateError_(error); + } + } + pausePlayMusic(id) { + try { + TXAudioEffectManagerModule.pausePlayMusic(id); + } + catch (error) { + throw generateError_(error); + } + } + resumePlayMusic(id) { + try { + TXAudioEffectManagerModule.resumePlayMusic(id); + } + catch (error) { + throw generateError_(error); + } + } + // /////////////////////////////////////////////////////////////////////////////// + // + // 屏幕分享 + // + // /////////////////////////////////////////////////////////////////////////////// + setSubStreamEncoderParam(param) { + try { + TrtcNativeTrtcCloudModule.setSubStreamEncoderParam(param); + } + catch (error) { + throw generateError_(error); + } + } + startScreenCapture(streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams = null) { + try { + let platform = uni.getSystemInfoSync().platform; + if ((streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig)) { + streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub; + } + const screenCaptureParams = Object.assign({ streamType }, encParams); + if (platform === NAME.ANDROID) { + TrtcNativeTrtcCloudModule.startScreenCapture(screenCaptureParams); + } + if (platform === NAME.IOS) { + // 开始应用内的屏幕分享(仅支持 iOS 13.0 及以上系统) + TrtcNativeTrtcCloudModule.startScreenCaptureInApp(screenCaptureParams); + // if (shareSource === TRTCShareSource.InApp) { + // TrtcNativeTrtcCloudModule.startScreenCaptureInApp(screenCaptureParams); + // } + // // 开始全系统的屏幕分享(仅支持 iOS 11.0 及以上系统) + // if (shareSource === TRTCShareSource.ByReplaykit) { + // TrtcNativeTrtcCloudModule.startScreenCaptureByReplaykit({ ...screenCaptureParams, appGroup: null }); + // } + } + } + catch (error) { + throw generateError_(error); + } + } + stopScreenCapture() { + try { + TrtcNativeTrtcCloudModule.stopScreenCapture(); + } + catch (error) { + throw generateError_(error); + } + } + pauseScreenCapture() { + try { + TrtcNativeTrtcCloudModule.pauseScreenCapture(); + } + catch (error) { + throw generateError_(error); + } + } + resumeScreenCapture() { + try { + TrtcNativeTrtcCloudModule.resumeScreenCapture(); + } + catch (error) { + throw generateError_(error); + } + } +} diff --git a/TrtcCloud/lib/TrtcCode.js b/TrtcCloud/lib/TrtcCode.js new file mode 100644 index 0000000..93f998e --- /dev/null +++ b/TrtcCloud/lib/TrtcCode.js @@ -0,0 +1,612 @@ +import { NAME, errorCodeUrl } from './constants'; +/** + * @namespace ErrorCode + * + * @description 错误码、警告码和事件列表 + */ +///////////////////////////////////////////////////////////////////////////////// +// +// (一)错误码(严重) +// +///////////////////////////////////////////////////////////////////////////////// +/** + * @memberof ErrorCode + * @typedef 错误码(严重) + * @description SDK 错误码(严重)对照表 + * | 符号 | 值 | 含义 | + * |---|---|---| + * |ERR_NULL|0|无错误| + * |ERR_ROOM_ENTER_FAIL|-3301|进入房间失败| + * |ERR_ENTER_ROOM_PARAM_NULL|-3316|进房参数为空,请检查 enterRoom:appScene: 接口调用是否传入有效的 param| + * |ERR_SDK_APPID_INVALID|-3317|进房参数 sdkAppId 错误| + * |ERR_ROOM_ID_INVALID|-3318|进房参数 roomId 错误| + * |ERR_USER_ID_INVALID|-3319|进房参数 userID 不正确| + * |ERR_USER_SIG_INVALID|-3320|进房参数 userSig 不正确| + * |ERR_ROOM_REQUEST_ENTER_ROOM_TIMEOUT|-3308|请求进房超时,请检查网络| + * |ERR_SERVER_INFO_SERVICE_SUSPENDED|-100013|服务不可用。请检查:套餐包剩余分钟数是否大于0,腾讯云账号是否欠费| + * |ERR_ROOM_REQUEST_QUIT_ROOM_TIMEOUT|-3325|请求退房超时| + * |ERR_CAMERA_START_FAIL|-1301|打开摄像头失败,例如在 Windows 或 Mac 设备,摄像头的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序| + * |ERR_CAMERA_NOT_AUTHORIZED|-1314|摄像头设备未授权,通常在移动设备出现,可能是权限被用户拒绝了| + * |ERR_CAMERA_SET_PARAM_FAIL|-1315|摄像头参数设置出错(参数不支持或其它)| + * |ERR_CAMERA_OCCUPY|-1316|摄像头正在被占用中,可尝试打开其他摄像头| + * |ERR_MIC_START_FAIL|-1302|打开麦克风失败,例如在 Windows 或 Mac 设备,麦克风的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序| + * |ERR_MIC_NOT_AUTHORIZED|-1317|麦克风设备未授权,通常在移动设备出现,可能是权限被用户拒绝了| + * |ERR_MIC_SET_PARAM_FAIL|-1318|麦克风设置参数失败| + * |ERR_MIC_OCCUPY|-1319|麦克风正在被占用中,例如移动设备正在通话时,打开麦克风会失败| + * |ERR_MIC_STOP_FAIL|-1320|停止麦克风失败| + * |ERR_SPEAKER_START_FAIL|-1321|打开扬声器失败,例如在 Windows 或 Mac 设备,扬声器的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序| + * |ERR_SPEAKER_SET_PARAM_FAIL|-1322|扬声器设置参数失败| + * |ERR_SPEAKER_STOP_FAIL|-1323|停止扬声器失败| + * |ERR_SCREEN_CAPTURE_START_FAIL|-1308|开始录屏失败,如果在移动设备出现,可能是权限被用户拒绝了,如果在 Windows 或 Mac 系统的设备出现,请检查录屏接口的参数是否符合要求| + * |ERR_SCREEN_CAPTURE_UNSURPORT|-1309|录屏失败,在 Android 平台,需要5.0以上的系统| + * |ERR_SERVER_CENTER_NO_PRIVILEDGE_PUSH_SUB_VIDEO|-102015|没有权限上行辅路| + * |ERR_SERVER_CENTER_ANOTHER_USER_PUSH_SUB_VIDEO|-102016|其他用户正在上行辅路| + * |ERR_VIDEO_ENCODE_FAIL|-1303|视频帧编码失败,例如 iOS 设备切换到其他应用时,硬编码器可能被系统释放,再切换回来时,硬编码器重启前,可能会抛出| + * |ERR_UNSUPPORTED_RESOLUTION|-1305|不支持的视频分辨率| + * |ERR_AUDIO_ENCODE_FAIL|-1304|音频帧编码失败,例如传入自定义音频数据,SDK 无法处理| + * |ERR_UNSUPPORTED_SAMPLERATE|-1306|不支持的音频采样率| + * |ERR_PIXEL_FORMAT_UNSUPPORTED|-1327|设置的 pixel format 不支持| + * |ERR_BUFFER_TYPE_UNSUPPORTED|-1328|设置的 buffer type 不支持| + * |ERR_PUBLISH_CDN_STREAM_REQUEST_TIME_OUT|-3321|旁路转推请求超时| + * |ERR_CLOUD_MIX_TRANSCODING_REQUEST_TIME_OUT|-3322|云端混流请求超时| + * |ERR_PUBLISH_CDN_STREAM_SERVER_FAILED|-3323|旁路转推回包异常| + * |ERR_CLOUD_MIX_TRANSCODING_SERVER_FAILED|-3324|云端混流回包异常| + * |ERR_ROOM_REQUEST_START_PUBLISHING_TIMEOUT|-3333|开始向腾讯云的直播 CDN 推流信令超时| + * |ERR_ROOM_REQUEST_START_PUBLISHING_ERROR|-3334|开始向腾讯云的直播 CDN 推流信令异常| + * |ERR_ROOM_REQUEST_STOP_PUBLISHING_TIMEOUT|-3335|停止向腾讯云的直播 CDN 推流信令超时| + * |ERR_ROOM_REQUEST_STOP_PUBLISHING_ERROR|-3336|停止向腾讯云的直播 CDN 推流信令异常| + * |ERR_ROOM_REQUEST_CONN_ROOM_TIMEOUT|-3326|请求连麦超时| + * |ERR_ROOM_REQUEST_DISCONN_ROOM_TIMEOUT|-3327|请求退出连麦超时| + * |ERR_ROOM_REQUEST_CONN_ROOM_INVALID_PARAM|-3328|无效参数| + * |ERR_CONNECT_OTHER_ROOM_AS_AUDIENCE|-3330|当前是观众角色,不能请求或断开跨房连麦,需要先 switchRole() 到主播| + * |ERR_SERVER_CENTER_CONN_ROOM_NOT_SUPPORT|-102031|不支持跨房间连麦| + * |ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_NUM|-102032|达到跨房间连麦上限| + * |ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_RETRY_TIMES|-102033|跨房间连麦重试次数耗尽| + * |ERR_SERVER_CENTER_CONN_ROOM_REQ_TIMEOUT|-102034|跨房间连麦请求超时| + * |ERR_SERVER_CENTER_CONN_ROOM_REQ|-102035|跨房间连麦请求格式错误| + * |ERR_SERVER_CENTER_CONN_ROOM_NO_SIG|-102036|跨房间连麦无签名| + * |ERR_SERVER_CENTER_CONN_ROOM_DECRYPT_SIG|-102037|跨房间连麦签名解密失败| + * |ERR_SERVER_CENTER_CONN_ROOM_NO_KEY|-102038|未找到跨房间连麦签名解密密钥| + * |ERR_SERVER_CENTER_CONN_ROOM_PARSE_SIG|-102039|跨房间连麦签名解析错误| + * |ERR_SERVER_CENTER_CONN_ROOM_INVALID_SIG_TIME|-102040|跨房间连麦签名时间戳错误| + * |ERR_SERVER_CENTER_CONN_ROOM_SIG_GROUPID|-102041|跨房间连麦签名不匹配| + * |ERR_SERVER_CENTER_CONN_ROOM_NOT_CONNED|-102042|本房间无连麦| + * |ERR_SERVER_CENTER_CONN_ROOM_USER_NOT_CONNED|-102043|本用户未发起连麦| + * |ERR_SERVER_CENTER_CONN_ROOM_FAILED|-102044|跨房间连麦失败| + * |ERR_SERVER_CENTER_CONN_ROOM_CANCEL_FAILED|-102045|取消跨房间连麦失败| + * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_ROOM_NOT_EXIST|-102046|被连麦房间不存在| + * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_REACH_MAX_ROOM|-102047|被连麦房间达到连麦上限| + * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_NOT_EXIST|-102048|被连麦用户不存在| + * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_DELETED|-102049|被连麦用户已被删除| + * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_FULL|-102050|被连麦用户达到资源上限| + * |ERR_SERVER_CENTER_CONN_ROOM_INVALID_SEQ|-102051|连麦请求序号错乱| + */ +export const TXLiteAVError = { + /** 无错误 */ + ERR_NULL: 0, + /** 进入房间失败 */ + ERR_ROOM_ENTER_FAIL: -3301, + /** 进房参数为空,请检查 enterRoom:appScene: 接口调用是否传入有效的 param */ + ERR_ENTER_ROOM_PARAM_NULL: -3316, + /** 进房参数 sdkAppId 错误 */ + ERR_SDK_APPID_INVALID: -3317, + /** 进房参数 roomId 错误 */ + ERR_ROOM_ID_INVALID: -3318, + /** 进房参数 userID 不正确 */ + ERR_USER_ID_INVALID: -3319, + /** 进房参数 userSig 不正确 */ + ERR_USER_SIG_INVALID: -3320, + /** 请求进房超时,请检查网络 */ + ERR_ROOM_REQUEST_ENTER_ROOM_TIMEOUT: -3308, + /** 服务不可用。请检查:套餐包剩余分钟数是否大于0,腾讯云账号是否欠费 */ + ERR_SERVER_INFO_SERVICE_SUSPENDED: -100013, + /** 请求退房超时 */ + ERR_ROOM_REQUEST_QUIT_ROOM_TIMEOUT: -3325, + /** 打开摄像头失败,例如在 Windows 或 Mac 设备,摄像头的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 */ + ERR_CAMERA_START_FAIL: -1301, + /** 摄像头设备未授权,通常在移动设备出现,可能是权限被用户拒绝了 */ + ERR_CAMERA_NOT_AUTHORIZED: -1314, + /** 摄像头参数设置出错(参数不支持或其它) */ + ERR_CAMERA_SET_PARAM_FAIL: -1315, + /** 摄像头正在被占用中,可尝试打开其他摄像头 */ + ERR_CAMERA_OCCUPY: -1316, + /** 打开麦克风失败,例如在 Windows 或 Mac 设备,麦克风的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 */ + ERR_MIC_START_FAIL: -1302, + /** 麦克风设备未授权,通常在移动设备出现,可能是权限被用户拒绝了 */ + ERR_MIC_NOT_AUTHORIZED: -1317, + /** 麦克风设置参数失败 */ + ERR_MIC_SET_PARAM_FAIL: -1318, + /** 麦克风正在被占用中,例如移动设备正在通话时,打开麦克风会失败 */ + ERR_MIC_OCCUPY: -1319, + /** 停止麦克风失败 */ + ERR_MIC_STOP_FAIL: -1320, + /** 打开扬声器失败,例如在 Windows 或 Mac 设备,扬声器的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 */ + ERR_SPEAKER_START_FAIL: -1321, + /** 扬声器设置参数失败 */ + ERR_SPEAKER_SET_PARAM_FAIL: -1322, + /** 停止扬声器失败 */ + ERR_SPEAKER_STOP_FAIL: -1323, + /** 开始录屏失败,如果在移动设备出现,可能是权限被用户拒绝了,如果在 Windows 或 Mac 系统的设备出现,请检查录屏接口的参数是否符合要求 */ + ERR_SCREEN_CAPTURE_START_FAIL: -1308, + /** 录屏失败,在 Android 平台,需要5.0以上的系统 */ + ERR_SCREEN_CAPTURE_UNSURPORT: -1309, + /** 没有权限上行辅路 */ + ERR_SERVER_CENTER_NO_PRIVILEDGE_PUSH_SUB_VIDEO: -102015, + /** 其他用户正在上行辅路 */ + ERR_SERVER_CENTER_ANOTHER_USER_PUSH_SUB_VIDEO: -102016, + /** 视频帧编码失败,例如 iOS 设备切换到其他应用时,硬编码器可能被系统释放,再切换回来时,硬编码器重启前,可能会抛出 */ + ERR_VIDEO_ENCODE_FAIL: -1303, + /** 音频帧编码失败,例如传入自定义音频数据,SDK 无法处理 */ + ERR_AUDIO_ENCODE_FAIL: -1304, + /** 不支持的视频分辨率 */ + ERR_UNSUPPORTED_RESOLUTION: -1305, + /** 不支持的音频采样率 */ + ERR_UNSUPPORTED_SAMPLERATE: -1306, + /** 设置的 pixel format 不支持 */ + ERR_PIXEL_FORMAT_UNSUPPORTED: -1327, + /** 设置的 buffer type 不支持 */ + ERR_BUFFER_TYPE_UNSUPPORTED: -1328, + /** 旁路转推请求超时 */ + ERR_PUBLISH_CDN_STREAM_REQUEST_TIME_OUT: -3321, + /** 云端混流请求超时 */ + ERR_CLOUD_MIX_TRANSCODING_REQUEST_TIME_OUT: -3322, + /** 旁路转推回包异常 */ + ERR_PUBLISH_CDN_STREAM_SERVER_FAILED: -3323, + /** 云端混流回包异常 */ + ERR_CLOUD_MIX_TRANSCODING_SERVER_FAILED: -3324, + /** 开始向腾讯云的直播 CDN 推流信令超时 */ + ERR_ROOM_REQUEST_START_PUBLISHING_TIMEOUT: -3333, + /** 开始向腾讯云的直播 CDN 推流信令异常 */ + ERR_ROOM_REQUEST_START_PUBLISHING_ERROR: -3334, + /** 停止向腾讯云的直播 CDN 推流信令超时 */ + ERR_ROOM_REQUEST_STOP_PUBLISHING_TIMEOUT: -3335, + /** 停止向腾讯云的直播 CDN 推流信令异常 */ + ERR_ROOM_REQUEST_STOP_PUBLISHING_ERROR: -3336, + /** 请求连麦超时 */ + ERR_ROOM_REQUEST_CONN_ROOM_TIMEOUT: -3326, + /** 请求退出连麦超时 */ + ERR_ROOM_REQUEST_DISCONN_ROOM_TIMEOUT: -3327, + /** 无效参数 */ + ERR_ROOM_REQUEST_CONN_ROOM_INVALID_PARAM: -3328, + /** 当前是观众角色,不能请求或断开跨房连麦,需要先 switchRole() 到主播 */ + ERR_CONNECT_OTHER_ROOM_AS_AUDIENCE: -3330, + /** 不支持跨房间连麦 */ + ERR_SERVER_CENTER_CONN_ROOM_NOT_SUPPORT: -102031, + /** 达到跨房间连麦上限 */ + ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_NUM: -102032, + /** 跨房间连麦重试次数耗尽 */ + ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_RETRY_TIMES: -102033, + /** 跨房间连麦请求超时 */ + ERR_SERVER_CENTER_CONN_ROOM_REQ_TIMEOUT: -102034, + /** 跨房间连麦请求格式错误 */ + ERR_SERVER_CENTER_CONN_ROOM_REQ: -102035, + /** 跨房间连麦无签名 */ + ERR_SERVER_CENTER_CONN_ROOM_NO_SIG: -102036, + /** 跨房间连麦签名解密失败 */ + ERR_SERVER_CENTER_CONN_ROOM_DECRYPT_SIG: -102037, + /** 未找到跨房间连麦签名解密密钥 */ + ERR_SERVER_CENTER_CONN_ROOM_NO_KEY: -102038, + /** 跨房间连麦签名解析错误 */ + ERR_SERVER_CENTER_CONN_ROOM_PARSE_SIG: -102039, + /** 跨房间连麦签名时间戳错误 */ + ERR_SERVER_CENTER_CONN_ROOM_INVALID_SIG_TIME: -102040, + /** 跨房间连麦签名不匹配 */ + ERR_SERVER_CENTER_CONN_ROOM_SIG_GROUPID: -102041, + /** 本房间无连麦 */ + ERR_SERVER_CENTER_CONN_ROOM_NOT_CONNED: -102042, + /** 本用户未发起连麦 */ + ERR_SERVER_CENTER_CONN_ROOM_USER_NOT_CONNED: -102043, + /** 跨房间连麦失败 */ + ERR_SERVER_CENTER_CONN_ROOM_FAILED: -102044, + /** 取消跨房间连麦失败 */ + ERR_SERVER_CENTER_CONN_ROOM_CANCEL_FAILED: -102045, + /** 被连麦房间不存在 */ + ERR_SERVER_CENTER_CONN_ROOM_CONNED_ROOM_NOT_EXIST: -102046, + /** 被连麦房间达到连麦上限 */ + ERR_SERVER_CENTER_CONN_ROOM_CONNED_REACH_MAX_ROOM: -102047, + /** 被连麦用户不存在 */ + ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_NOT_EXIST: -102048, + /** 被连麦用户已被删除 */ + ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_DELETED: -102049, + /** 被连麦用户达到资源上限 */ + ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_FULL: -102050, + /** 连麦请求序号错乱 */ + ERR_SERVER_CENTER_CONN_ROOM_INVALID_SEQ: -102051, + /** 直播,推流出现网络断开,且经过多次重试无法恢复 */ + ERR_RTMP_PUSH_NET_DISCONNECT: -1307, + /** 直播,推流地址非法,例如不是 RTMP 协议的地址 */ + ERR_RTMP_PUSH_INVALID_ADDRESS: -1313, + /** 直播,连接推流服务器失败(若支持智能选路,IP 全部失败) */ + ERR_RTMP_PUSH_NET_ALLADDRESS_FAIL: -1324, + /** 直播,网络不可用,请确认 WiFi、移动数据或者有线网络是否正常 */ + ERR_RTMP_PUSH_NO_NETWORK: -1325, + /** 直播,服务器拒绝连接请求,可能是该推流地址已经被占用,或者 TXSecret 校验失败,或者是过期了,或者是欠费了 */ + ERR_RTMP_PUSH_SERVER_REFUSE: -1326, + /** 直播,网络断连,且经多次重连抢救无效,可以放弃治疗,更多重试请自行重启播放 */ + ERR_PLAY_LIVE_STREAM_NET_DISCONNECT: -2301, + /** 直播,获取加速拉流的地址失败 */ + ERR_GET_RTMP_ACC_URL_FAIL: -2302, + /** 播放的文件不存在 */ + ERR_FILE_NOT_FOUND: -2303, + /** H265 解码失败 */ + ERR_HEVC_DECODE_FAIL: -2304, + /** 点播,音视频流解密失败 */ + ERR_VOD_DECRYPT_FAIL: -2305, + /** 点播,获取点播文件信息失败 */ + ERR_GET_VODFILE_MEDIAINFO_FAIL: -2306, + /** 直播,切流失败(切流可以播放不同画面大小的视频) */ + ERR_PLAY_LIVE_STREAM_SWITCH_FAIL: -2307, + /** 直播,服务器拒绝连接请求 */ + ERR_PLAY_LIVE_STREAM_SERVER_REFUSE: -2308, + /** 直播,RTMPACC 低延时拉流失败,且经过多次重试无法恢复 */ + ERR_RTMP_ACC_FETCH_STREAM_FAIL: -2309, + /** 心跳失败,客户端定时向服务器发送数据包,告诉服务器自己活着,这个错误通常是发包超时 */ + ERR_ROOM_HEARTBEAT_FAIL: -3302, + /** 拉取接口机服务器地址失败 */ + ERR_ROOM_REQUEST_IP_FAIL: -3303, + /** 连接接口机服务器失败 */ + ERR_ROOM_CONNECT_FAIL: -3304, + /** 请求视频位失败 */ + ERR_ROOM_REQUEST_AVSEAT_FAIL: -3305, + /** 请求 token https 超时,请检查网络是否正常,或网络防火墙是否放行 https 访问 official.opensso.tencent-cloud.com:443 */ + ERR_ROOM_REQUEST_TOKEN_HTTPS_TIMEOUT: -3306, + /** 请求 IP 和 sig 超时,请检查网络是否正常,或网络防火墙是否放行 UDP 访问下列 IP 和域名 query.tencent-cloud.com:8000 162.14.23.140:8000 162.14.7.49:8000 */ + ERR_ROOM_REQUEST_IP_TIMEOUT: -3307, + /** 请求视频位超时 */ + ERR_ROOM_REQUEST_VIDEO_FLAG_TIMEOUT: -3309, + /** 请求视频数据超时 */ + ERR_ROOM_REQUEST_VIDEO_DATA_ROOM_TIMEOUT: -3310, + /** 请求修改视频能力项超时 */ + ERR_ROOM_REQUEST_CHANGE_ABILITY_TIMEOUT: -3311, + /** 请求状态上报超时 */ + ERR_ROOM_REQUEST_STATUS_REPORT_TIMEOUT: -3312, + /** 请求关闭视频超时 */ + ERR_ROOM_REQUEST_CLOSE_VIDEO_TIMEOUT: -3313, + /** 请求接收视频项超时 */ + ERR_ROOM_REQUEST_SET_RECEIVE_TIMEOUT: -3314, + /** 请求 token 无效参数,请检查 TRTCParams.userSig 是否填写正确 */ + ERR_ROOM_REQUEST_TOKEN_INVALID_PARAMETER: -3315, + /** 请求 AES TOKEN 时,server 返回的内容是空的 */ + ERR_ROOM_REQUEST_AES_TOKEN_RETURN_ERROR: -3329, + /** 请求接口机 IP 返回的列表为空的 */ + ERR_ACCIP_LIST_EMPTY: -3331, + /** 请求发送 Json 信令超时 */ + ERR_ROOM_REQUEST_SEND_JSON_CMD_TIMEOUT: -3332, + // Info 服务器(查询接口机 IP), 服务器错误码,数值范围[-100000, -110000] + /** server 解包错误,可能请求数据被篡改 */ + ERR_SERVER_INFO_UNPACKING_ERROR: -100000, + /** TOKEN 错误 */ + ERR_SERVER_INFO_TOKEN_ERROR: -100001, + /** 分配接口机错误 */ + ERR_SERVER_INFO_ALLOCATE_ACCESS_FAILED: -100002, + /** 生成签名错误 */ + ERR_SERVER_INFO_GENERATE_SIGN_FAILED: -100003, + /** https token 超时 */ + ERR_SERVER_INFO_TOKEN_TIMEOUT: -100004, + /** 无效的命令字 */ + ERR_SERVER_INFO_INVALID_COMMAND: -100005, + /** 权限位校验失败 */ + ERR_SERVER_INFO_PRIVILEGE_FLAG_ERROR: -100006, + /** https 请求时,生成加密 key 错误 */ + ERR_SERVER_INFO_GENERATE_KEN_ERROR: -100007, + /** https 请求时,生成 token 错误 */ + ERR_SERVER_INFO_GENERATE_TOKEN_ERROR: -100008, + /** 数据库查询失败(房间相关存储信息) */ + ERR_SERVER_INFO_DATABASE: -100009, + /** 房间号错误 */ + ERR_SERVER_INFO_BAD_ROOMID: -100010, + /** 场景或角色错误 */ + ERR_SERVER_INFO_BAD_SCENE_OR_ROLE: -100011, + /** 房间号转换出错 */ + ERR_SERVER_INFO_ROOMID_EXCHANGE_FAILED: -100012, + /** 房间号非法 */ + ERR_SERVER_INFO_STRGROUP_HAS_INVALID_CHARS: -100014, + /** 非法SDKAppid */ + ERR_SERVER_INFO_LACK_SDKAPPID: -100015, + /** 无效请求, 旧版 0x1 要求带 Token; ECDH 要求带 ECDH Publich Key; 两个都没有就按报错 */ + ERR_SERVER_INFO_INVALID: -100016, + /** 生成公钥失败 */ + ERR_SERVER_INFO_ECDH_GET_KEY: -100017, + /** 获取tinyid失败 */ + ERR_SERVER_INFO_ECDH_GET_TINYID: -100018, + // Access 接口机 + /** token 过期 */ + ERR_SERVER_ACC_TOKEN_TIMEOUT: -101000, + /** 签名错误 */ + ERR_SERVER_ACC_SIGN_ERROR: -101001, + /** 签名超时 */ + ERR_SERVER_ACC_SIGN_TIMEOUT: -101002, + /** 房间不存在 */ + ERR_SERVER_ACC_ROOM_NOT_EXIST: -101003, + /** 后台房间标识 roomId 错误 */ + ERR_SERVER_ACC_ROOMID: -101004, + /** 后台用户位置标识 locationId 错误 */ + ERR_SERVER_ACC_LOCATIONID: -101005, + // center 服务器(信令和流控处理等任务) + /** 后台错误 */ + ERR_SERVER_CENTER_SYSTEM_ERROR: -102000, + /** 无效的房间 Id */ + ERR_SERVER_CENTER_INVALID_ROOMID: -102001, + /** 创建房间失败 */ + ERR_SERVER_CENTER_CREATE_ROOM_FAILED: -102002, + /** 签名错误 */ + ERR_SERVER_CENTER_SIGN_ERROR: -102003, + /** 签名过期 */ + ERR_SERVER_CENTER_SIGN_TIMEOUT: -102004, + /** 房间不存在 */ + ERR_SERVER_CENTER_ROOM_NOT_EXIST: -102005, + /** 房间添加用户失败 */ + ERR_SERVER_CENTER_ADD_USER_FAILED: -102006, + /** 查找用户失败 */ + ERR_SERVER_CENTER_FIND_USER_FAILED: -102007, + /** 频繁切换终端 */ + ERR_SERVER_CENTER_SWITCH_TERMINATION_FREQUENTLY: -102008, + /** locationid 错误 */ + ERR_SERVER_CENTER_LOCATION_NOT_EXIST: -102009, + /** 没有权限创建房间 */ + ERR_SERVER_CENTER_NO_PRIVILEDGE_CREATE_ROOM: -102010, + /** 没有权限进入房间 */ + ERR_SERVER_CENTER_NO_PRIVILEDGE_ENTER_ROOM: -102011, + /** 辅路抢视频位、申请辅路请求类型参数错误 */ + ERR_SERVER_CENTER_INVALID_PARAMETER_SUB_VIDEO: -102012, + /** 没有权限上视频 */ + ERR_SERVER_CENTER_NO_PRIVILEDGE_PUSH_VIDEO: -102013, + /** 没有空闲路由表 */ + ERR_SERVER_CENTER_ROUTE_TABLE_ERROR: -102014, + /** 当前用户没有上行辅路 */ + ERR_SERVER_CENTER_NOT_PUSH_SUB_VIDEO: -102017, + /** 用户被删除状态 */ + ERR_SERVER_CENTER_USER_WAS_DELETED: -102018, + /** 没有权限请求视频 */ + ERR_SERVER_CENTER_NO_PRIVILEDGE_REQUEST_VIDEO: -102019, + /** 进房参数 bussInfo 错误 */ + ERR_SERVER_CENTER_INVALID_PARAMETER: -102023, + /** 请求 I 帧未知 opType */ + ERR_SERVER_CENTER_I_FRAME_UNKNOW_TYPE: -102024, + /** 请求 I 帧包格式错误 */ + ERR_SERVER_CENTER_I_FRAME_INVALID_PACKET: -102025, + /** 请求 I 帧目标用户不存在 */ + ERR_SERVER_CENTER_I_FRAME_DEST_USER_NOT_EXIST: -102026, + /** 请求 I 帧房间用户太多 */ + ERR_SERVER_CENTER_I_FRAME_ROOM_TOO_BIG: -102027, + /** 请求 I 帧参数错误 */ + ERR_SERVER_CENTER_I_FRAME_RPS_INVALID_PARAMETER: -102028, + /** 房间号非法 */ + ERR_SERVER_CENTER_INVALID_ROOM_ID: -102029, + /** 房间号超过限制 */ + ERR_SERVER_CENTER_ROOM_ID_TOO_LONG: -102030, + /** 房间满员 */ + ERR_SERVER_CENTER_ROOM_FULL: -102052, + /** json串解析失败 */ + ERR_SERVER_CENTER_DECODE_JSON_FAIL: -102053, + /** 未定义命令字 */ + ERR_SERVER_CENTER_UNKNOWN_SUB_CMD: -102054, + /** 未定义角色 */ + ERR_SERVER_CENTER_INVALID_ROLE: -102055, + /** 代理机超出限制 */ + ERR_SERVER_CENTER_REACH_PROXY_MAX: -102056, + //add by sunlitwang begin + /** 无法保存用户自定义recordId */ + ERR_SERVER_CENTER_RECORDID_STORE: -102057, + /** Protobuf序列化错误 */ + ERR_SERVER_CENTER_PB_SERIALIZE: -102058, + // https://cloud.tencent.com/document/product/269/1671#.E5.B8.90.E5.8F.B7.E7.B3.BB.E7.BB.9F , 帐号系统, 主要是70000 - 79999之间. + // 在请求 token 过程中,出现账号错误,SSO 返回的错误码,原为正数,现将其转换为负数。 + /** sig 过期,请尝试重新生成。如果是刚生成,就过期,请检查有效期填写的是否过小,或者填的 0 */ + ERR_SERVER_SSO_SIG_EXPIRED: -70001, + /** sig 校验失败,请确认下 sig 内容是否被截断,如缓冲区长度不够导致的内容截断 */ + ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_1: -70003, + /** sig 校验失败,请确认下 sig 内容是否被截断,如缓冲区长度不够导致的内容截断 */ + ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_2: -70004, + /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */ + ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_3: -70005, + /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */ + ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_4: -70006, + /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */ + ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_5: -70007, + /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */ + ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_6: -70008, + /** 用业务公钥验证 sig 失败,请确认生成的 usersig 使用的私钥和 sdkAppId 是否对应 */ + ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_7: -70009, + /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */ + ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_8: -70010, + /** sig 中 identifier 与请求时的 identifier 不匹配,请检查登录时填写的 identifier 与 sig 中的是否一致 */ + ERR_SERVER_SSO_SIG_VERIFICATION_ID_NOT_MATCH: -70013, + /** sig 中 sdkAppId 与请求时的 sdkAppId 不匹配,请检查登录时填写的 sdkAppId 与 sig 中的是否一致 */ + ERR_SERVER_SSO_APPID_NOT_MATCH: -70014, + /** 内部第三方票据验证超时,请重试,如多次重试不成功,请@TLS 帐号支持,QQ 3268519604 */ + ERR_SERVER_SSO_VERIFICATION_EXPIRED: -70017, + /** 内部第三方票据验证超时,请重试,如多次重试不成功,请@TLS 帐号支持,QQ 3268519604 */ + ERR_SERVER_SSO_VERIFICATION_FAILED: -70018, + /** sdkAppId 未找到,请确认是否已经在腾讯云上配置 */ + ERR_SERVER_SSO_APPID_NOT_FOUND: -70020, + /** 帐号已被拉入黑名单,请联系 TLS 帐号支持 QQ 3268519604 */ + ERR_SERVER_SSO_ACCOUNT_IN_BLACKLIST: -70051, + /** usersig 已经失效,请重新生成,再次尝试 */ + ERR_SERVER_SSO_SIG_INVALID: -70052, + /** 安全原因被限制 */ + ERR_SERVER_SSO_LIMITED_BY_SECURITY: -70114, + /** 登录状态无效,请使用 usersig 重新鉴权 */ + ERR_SERVER_SSO_INVALID_LOGIN_STATUS: -70221, + /** sdkAppId 填写错误 */ + ERR_SERVER_SSO_APPID_ERROR: -70252, + /** 票据校验失败,请检查各项参数是否正确 */ + ERR_SERVER_SSO_TICKET_VERIFICATION_FAILED: -70346, + /** 票据因过期原因校验失败 */ + ERR_SERVER_SSO_TICKET_EXPIRED: -70347, + /** 创建账号数量超过已购买预付费数量限制 */ + ERR_SERVER_SSO_ACCOUNT_EXCEED_PURCHASES: -70398, + /** 服务器内部错误,请重试 */ + ERR_SERVER_SSO_INTERNAL_ERROR: -70500, +}; +///////////////////////////////////////////////////////////////////////////////// +// +// (二)错误码(警告) +// +///////////////////////////////////////////////////////////////////////////////// +/** + * @memberof ErrorCode + * @typedef 错误码(警告) + * @description SDK 错误码(警告)对照表 + * | 符号 | 值 | 含义 | + * |---|---|---| + * |WARNING_HW_ENCODER_START_FAIL|1103|硬编码启动出现问题,自动切换到软编码| + * |WARNING_VIDEO_ENCODER_SW_TO_HW|1107|当前 CPU 使用率太高,无法满足软件编码需求,自动切换到硬件编码| + * |WARNING_INSUFFICIENT_CAPTURE_FPS|1108|摄像头采集帧率不足,部分自带美颜算法的 Android 手机上会出现| + * |WARNING_SW_ENCODER_START_FAIL|1109|软编码启动失败| + * |WARNING_REDUCE_CAPTURE_RESOLUTION|1110|摄像头采集分辨率被降低,以满足当前帧率和性能最优解。| + * |WARNING_VIDEO_FRAME_DECODE_FAIL|2101|当前视频帧解码失败| + * |WARNING_AUDIO_FRAME_DECODE_FAIL|2102|当前音频帧解码失败| + * |WARNING_VIDEO_PLAY_LAG|2105|当前视频播放出现卡顿| + * |WARNING_HW_DECODER_START_FAIL|2106|硬解启动失败,采用软解码| + * |WARNING_VIDEO_DECODER_HW_TO_SW|2108|当前流硬解第一个 I 帧失败,SDK 自动切软解| + * |WARNING_SW_DECODER_START_FAIL|2109|软解码器启动失败| + * |WARNING_VIDEO_RENDER_FAIL|2110|视频渲染失败| + * |WARNING_AUDIO_RECORDING_WRITE_FAIL|7001|音频录制写入文件失败| + * |WARNING_ROOM_DISCONNECT|5101|网络断开连接| + * |WARNING_IGNORE_UPSTREAM_FOR_AUDIENCE|6001|当前是观众角色,忽略上行音视频数据| + */ +export const TXLiteAVWarning = { + /** 硬编码启动出现问题,自动切换到软编码 */ + WARNING_HW_ENCODER_START_FAIL: 1103, + /** 当前 CPU 使用率太高,无法满足软件编码需求,自动切换到硬件编码 */ + WARNING_VIDEO_ENCODER_SW_TO_HW: 1107, + /** 摄像头采集帧率不足,部分自带美颜算法的 Android 手机上会出现 */ + WARNING_INSUFFICIENT_CAPTURE_FPS: 1108, + /** 软编码启动失败 */ + WARNING_SW_ENCODER_START_FAIL: 1109, + /** 摄像头采集分辨率被降低,以满足当前帧率和性能最优解。 */ + WARNING_REDUCE_CAPTURE_RESOLUTION: 1110, + /** 当前视频帧解码失败 */ + WARNING_VIDEO_FRAME_DECODE_FAIL: 2101, + /** 当前音频帧解码失败 */ + WARNING_AUDIO_FRAME_DECODE_FAIL: 2102, + /** 当前视频播放出现卡顿 */ + WARNING_VIDEO_PLAY_LAG: 2105, + /** 硬解启动失败,采用软解码 */ + WARNING_HW_DECODER_START_FAIL: 2106, + /** 当前流硬解第一个 I 帧失败,SDK 自动切软解 */ + WARNING_VIDEO_DECODER_HW_TO_SW: 2108, + /** 软解码器启动失败 */ + WARNING_SW_DECODER_START_FAIL: 2109, + /** 视频渲染失败 */ + WARNING_VIDEO_RENDER_FAIL: 2110, + /** 音频录制写入文件失败 */ + WARNING_AUDIO_RECORDING_WRITE_FAIL: 7001, + /** 网络断开连接 */ + WARNING_ROOM_DISCONNECT: 5101, + /** 当前是观众角色,忽略上行音视频数据 */ + WARNING_IGNORE_UPSTREAM_FOR_AUDIENCE: 6001, + /** 网络状况不佳:上行带宽太小,上传数据受阻 */ + WARNING_NET_BUSY: 1101, + /** 直播,网络断连, 已启动自动重连(自动重连连续失败超过三次会放弃) */ + WARNING_RTMP_SERVER_RECONNECT: 1102, + /** 直播,网络断连, 已启动自动重连(自动重连连续失败超过三次会放弃) */ + WARNING_LIVE_STREAM_SERVER_RECONNECT: 2103, + /** 网络来包不稳:可能是下行带宽不足,或由于主播端出流不均匀 */ + WARNING_RECV_DATA_LAG: 2104, + /** 直播,DNS 解析失败 */ + WARNING_RTMP_DNS_FAIL: 3001, + /** 直播,服务器连接失败 */ + WARNING_RTMP_SEVER_CONN_FAIL: 3002, + /** 直播,与 RTMP 服务器握手失败 */ + WARNING_RTMP_SHAKE_FAIL: 3003, + /** 直播,服务器主动断开 */ + WARNING_RTMP_SERVER_BREAK_CONNECT: 3004, + /** 直播,RTMP 读/写失败,将会断开连接 */ + WARNING_RTMP_READ_WRITE_FAIL: 3005, + /** 直播,RTMP 写失败(SDK 内部错误码,不会对外抛出) */ + WARNING_RTMP_WRITE_FAIL: 3006, + /** 直播,RTMP 读失败(SDK 内部错误码,不会对外抛出) */ + WARNING_RTMP_READ_FAIL: 3007, + /** 直播,超过30s 没有数据发送,主动断开连接 */ + WARNING_RTMP_NO_DATA: 3008, + /** 直播,connect 服务器调用失败(SDK 内部错误码,不会对外抛出) */ + WARNING_PLAY_LIVE_STREAM_INFO_CONNECT_FAIL: 3009, + /** 直播,连接失败,该流地址无视频(SDK 内部错误码,不会对外抛出) */ + WARNING_NO_STEAM_SOURCE_FAIL: 3010, + /** 网络断连,已启动自动重连 */ + WARNING_ROOM_RECONNECT: 5102, + /** 网络状况不佳:上行带宽太小,上传数据受阻 */ + WARNING_ROOM_NET_BUSY: 5103, +}; +///////////////////////////////////////////////////////////////////////////////// +// +// (三)JS 封装层抛出的异常(严重) +// +///////////////////////////////////////////////////////////////////////////////// +/** + * @namespace ErrorCode + * @description 错误码 + */ +export const TXLiteJSError = { + /** + * 未知错误 + * @default 0xFFFF + * @memberof module:ErrorCode + */ + UNKNOWN: 0xffff, + /** + * 无效参数 + * + * @default 0x1000 + * @memberof module:ErrorCode + */ + INVALID_PARAMETER: 0x1000, + /** + * 非法操作 + * + * @default 0x1001 + * @memberof module:ErrorCode + */ + INVALID_OPERATION: 0x1001, +}; +const getErrorName = function (code) { + for (let key in TXLiteJSError) { + if (TXLiteJSError[key] === code) { + return key; + } + } + return 'UNKNOWN'; +}; +/** + * TrtcError 错误对象
+ * @extends Error + * @namespace ErrorCode + */ +class TrtcError extends Error { + constructor({ code = TXLiteJSError.UNKNOWN, message, extraInfo }) { + if (extraInfo) { + const tempError = { + errCode: code, + errMsg: message, + extraInfo: Object.assign(Object.assign({}, extraInfo), { errCodeUrl: errorCodeUrl }), + }; + super(JSON.stringify(tempError)); + } + else { + super(message + + ` <${getErrorName(code)} 0x${code.toString(16)}>. Refer to: ${errorCodeUrl}`); + } + this.errCode = code; + this.errMsg = message; + this.extraInfo = Object.assign(Object.assign({}, extraInfo), { errCodeUrl: errorCodeUrl }); + } + /** + * 获取错误码
+ * 详细错误码列表参见 {@link module:ErrorCode ErrorCode} + * @memberof TrtcError + */ + getCode() { + return this.errCode; + } +} +export default TrtcError; +export function generateError_(error, code = TXLiteJSError.UNKNOWN, extraInfo) { + return new TrtcError({ + code: error.code || code, + message: `${NAME.LOG_PREFIX}${error.message}`, + extraInfo, + }); +} +; diff --git a/TrtcCloud/lib/TrtcDefines.js b/TrtcCloud/lib/TrtcDefines.js new file mode 100644 index 0000000..5054d3d --- /dev/null +++ b/TrtcCloud/lib/TrtcDefines.js @@ -0,0 +1,433 @@ +/** + * TRTC 关键类型定义
+ * @description 分辨率、质量等级等枚举和常量值的定义 + */ +///////////////////////////////////////////////////////////////////////////////// +// +// 【(一)视频相关枚举值定义】 +// +///////////////////////////////////////////////////////////////////////////////// +/** + * 视频分辨率
+ * 此处仅定义横屏分辨率(如 640 × 360),如需使用竖屏分辨率(如 360 × 640),需要同时指定 VideoResolutionMode 为 Portrait + * @enum {Number} + */ +const TRTCVideoResolution_HACK_JSDOC = { + /** 宽高比 1:1;分辨率 120x120;建议码率(VideoCall)80kbps; 建议码率(LIVE)120kbps */ + TRTCVideoResolution_120_120: 1, + /** 宽高比 1:1 分辨率 160x160;建议码率(VideoCall)100kbps; 建议码率(LIVE)150kbps */ + TRTCVideoResolution_160_160: 3, + /** 宽高比 1:1;分辨率 270x270;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps */ + TRTCVideoResolution_270_270: 5, + /** 宽高比 1:1;分辨率 480x480;建议码率(VideoCall)350kbps; 建议码率(LIVE)500kbps */ + TRTCVideoResolution_480_480: 7, + /** 宽高比4:3;分辨率 160x120;建议码率(VideoCall)100kbps; 建议码率(LIVE)150kbps */ + TRTCVideoResolution_160_120: 50, + /** 宽高比 4:3;分辨率 240x180;建议码率(VideoCall)150kbps; 建议码率(LIVE)250kbps */ + TRTCVideoResolution_240_180: 52, + /** 宽高比 4:3;分辨率 280x210;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps */ + TRTCVideoResolution_280_210: 54, + /** 宽高比 4:3;分辨率 320x240;建议码率(VideoCall)250kbps; 建议码率(LIVE)375kbps */ + TRTCVideoResolution_320_240: 56, + /** 宽高比 4:3;分辨率 400x300;建议码率(VideoCall)300kbps; 建议码率(LIVE)450kbps */ + TRTCVideoResolution_400_300: 58, + /** 宽高比 4:3;分辨率 480x360;建议码率(VideoCall)400kbps; 建议码率(LIVE)600kbps */ + TRTCVideoResolution_480_360: 60, + /** 宽高比 4:3;分辨率 640x480;建议码率(VideoCall)600kbps; 建议码率(LIVE)900kbps */ + TRTCVideoResolution_640_480: 62, + /** 宽高比 4:3;分辨率 960x720;建议码率(VideoCall)1000kbps; 建议码率(LIVE)1500kbps */ + TRTCVideoResolution_960_720: 64, + /** 宽高比 16:9;分辨率 160x90;建议码率(VideoCall)150kbps; 建议码率(LIVE)250kbps */ + TRTCVideoResolution_160_90: 100, + /** 宽高比 16:9;分辨率 256x144;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps */ + TRTCVideoResolution_256_144: 102, + /** 宽高比 16:9;分辨率 320x180;建议码率(VideoCall)250kbps; 建议码率(LIVE)400kbps */ + TRTCVideoResolution_320_180: 104, + /** 宽高比 16:9;分辨率 480x270;建议码率(VideoCall)350kbps; 建议码率(LIVE)550kbps */ + TRTCVideoResolution_480_270: 106, + /** 宽高比 16:9;分辨率 640x360;建议码率(VideoCall)500kbps; 建议码率(LIVE)900kbps */ + TRTCVideoResolution_640_360: 108, + /** 宽高比 16:9;分辨率 960x540;建议码率(VideoCall)850kbps; 建议码率(LIVE)1300kbps */ + TRTCVideoResolution_960_540: 110, + /** 宽高比 16:9;分辨率 1280x720;建议码率(VideoCall)1200kbps; 建议码率(LIVE)1800kbps */ + TRTCVideoResolution_1280_720: 112, + /** 宽高比 16:9;分辨率 1920x1080;建议码率(VideoCall)2000kbps; 建议码率(LIVE)3000kbps */ + TRTCVideoResolution_1920_1080: 114, +}; +export var TRTCVideoResolution; +(function (TRTCVideoResolution) { + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_120_120"] = 1] = "TRTCVideoResolution_120_120"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_160_160"] = 3] = "TRTCVideoResolution_160_160"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_270_270"] = 5] = "TRTCVideoResolution_270_270"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_480_480"] = 7] = "TRTCVideoResolution_480_480"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_160_120"] = 50] = "TRTCVideoResolution_160_120"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_240_180"] = 52] = "TRTCVideoResolution_240_180"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_280_210"] = 54] = "TRTCVideoResolution_280_210"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_320_240"] = 56] = "TRTCVideoResolution_320_240"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_400_300"] = 58] = "TRTCVideoResolution_400_300"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_480_360"] = 60] = "TRTCVideoResolution_480_360"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_640_480"] = 62] = "TRTCVideoResolution_640_480"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_960_720"] = 64] = "TRTCVideoResolution_960_720"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_160_90"] = 100] = "TRTCVideoResolution_160_90"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_256_144"] = 102] = "TRTCVideoResolution_256_144"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_320_180"] = 104] = "TRTCVideoResolution_320_180"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_480_270"] = 106] = "TRTCVideoResolution_480_270"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_640_360"] = 108] = "TRTCVideoResolution_640_360"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_960_540"] = 110] = "TRTCVideoResolution_960_540"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_1280_720"] = 112] = "TRTCVideoResolution_1280_720"; + TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_1920_1080"] = 114] = "TRTCVideoResolution_1920_1080"; +})(TRTCVideoResolution || (TRTCVideoResolution = {})); +/** + * 视频分辨率模式
+ * TRTCVideoResolution 中仅定义了横屏分辨率(如 640 × 360),如需使用竖屏分辨率(如 360 × 640),需要同时指定 TRTCVideoResolutionMode 为 Portrait + * @enum {Number} + */ +const TRTCVideoResolutionMode_HACK_JSDOC = { + /** 横屏分辨率 */ + TRTCVideoResolutionModeLandscape: 0, + /** 竖屏分辨率 */ + TRTCVideoResolutionModePortrait: 1, +}; +export var TRTCVideoResolutionMode; +(function (TRTCVideoResolutionMode) { + TRTCVideoResolutionMode[TRTCVideoResolutionMode["TRTCVideoResolutionModeLandscape"] = 0] = "TRTCVideoResolutionModeLandscape"; + TRTCVideoResolutionMode[TRTCVideoResolutionMode["TRTCVideoResolutionModePortrait"] = 1] = "TRTCVideoResolutionModePortrait"; +})(TRTCVideoResolutionMode || (TRTCVideoResolutionMode = {})); +; +/** + * 视频流类型
+ * TRTC 内部有三种不同的音视频流,分别是: + * - 高清大画面:一般用来传输摄像头的视频数据 + * - 低清小画面:小画面和大画面的内容相互,但是分辨率和码率都比大画面低,因此清晰度也更低 + * - 辅流画面:一般用于屏幕分享,同一时间在同一个房间中只允许一个用户发布辅流视频,其他用户必须要等该用户关闭之后才能发布自己的辅流 + * + * **Note:** + * - 不支持单独开启低清小画面,小画面必须依附于大画面而存在,SDK 会自动设定低清小画面的分辨率和码率 + * @enum {Number} + */ +const TRTCVideoStreamType_HACK_JSDOC = { + /** 大画面视频流 */ + TRTCVideoStreamTypeBig: 0, + /** 小画面视频流 */ + TRTCVideoStreamTypeSmall: 1, + /** 辅流(屏幕分享) */ + TRTCVideoStreamTypeSub: 2, +}; +export var TRTCVideoStreamType; +(function (TRTCVideoStreamType) { + TRTCVideoStreamType[TRTCVideoStreamType["TRTCVideoStreamTypeBig"] = 0] = "TRTCVideoStreamTypeBig"; + TRTCVideoStreamType[TRTCVideoStreamType["TRTCVideoStreamTypeSmall"] = 1] = "TRTCVideoStreamTypeSmall"; + TRTCVideoStreamType[TRTCVideoStreamType["TRTCVideoStreamTypeSub"] = 2] = "TRTCVideoStreamTypeSub"; +})(TRTCVideoStreamType || (TRTCVideoStreamType = {})); +/** + * 视频画面填充模式
+ * 如果画面的显示分辨率不等于画面的原始分辨率,就需要您设置画面的填充模式: + * - TRTCVideoFillMode_Fill,图像铺满屏幕,超出显示视窗的视频部分将被截掉,所以画面显示可能不完整。 + * - TRTCVideoFillMode_Fit,图像长边填满屏幕,短边区域会被填充黑色,但画面的内容肯定是完整的。 + * @enum {Number} + */ +const TRTCVideoFillMode_HACK_JSDOC = { + /** 图像铺满屏幕,超出显示视窗的视频部分将被截掉 */ + TRTCVideoFillMode_Fill: 0, + /** 图像长边填满屏幕,短边区域会被填充黑色 */ + TRTCVideoFillMode_Fit: 1, +}; +export var TRTCVideoFillMode; +(function (TRTCVideoFillMode) { + TRTCVideoFillMode[TRTCVideoFillMode["TRTCVideoFillMode_Fill"] = 0] = "TRTCVideoFillMode_Fill"; + TRTCVideoFillMode[TRTCVideoFillMode["TRTCVideoFillMode_Fit"] = 1] = "TRTCVideoFillMode_Fit"; +})(TRTCVideoFillMode || (TRTCVideoFillMode = {})); +; +/** + * 视频画面旋转方向
+ * TRTC SDK 提供了对本地和远程画面的旋转角度设置 API,如下的旋转角度都是指顺时针方向的。 + * @enum {Number} + */ +const TRTCVideoRotation_HACK_JSDOC = { + /** 顺时针旋转0度 */ + TRTCVideoRotation_0: 0, + /** 顺时针旋转90度 */ + TRTCVideoRotation_90: 1, + /** 顺时针旋转180度 */ + TRTCVideoRotation_180: 2, + /** 顺时针旋转270度 */ + TRTCVideoRotation_270: 3, +}; +export var TRTCVideoRotation; +(function (TRTCVideoRotation) { + TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_0"] = 0] = "TRTCVideoRotation_0"; + TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_90"] = 1] = "TRTCVideoRotation_90"; + TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_180"] = 2] = "TRTCVideoRotation_180"; + TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_270"] = 3] = "TRTCVideoRotation_270"; +})(TRTCVideoRotation || (TRTCVideoRotation = {})); +/** + * 画面渲染镜像类型
+ * TRTC 的画面镜像提供下列设置模式 + * @enum {Number} + */ +const TRTCVideoMirrorType_HACK_JSDOC = { + /** 只适用于移动端, 本地预览时,前置摄像头镜像,后置摄像头不镜像 */ + TRTCVideoMirrorType_Auto: 0, + /** 所有画面均镜像 */ + TRTCVideoMirrorType_Enable: 1, + /** 所有画面均不镜像 */ + TRTCVideoMirrorType_Disable: 2 +}; +export var TRTCVideoMirrorType; +(function (TRTCVideoMirrorType) { + TRTCVideoMirrorType[TRTCVideoMirrorType["TRTCVideoMirrorType_Auto"] = 0] = "TRTCVideoMirrorType_Auto"; + TRTCVideoMirrorType[TRTCVideoMirrorType["TRTCVideoMirrorType_Enable"] = 1] = "TRTCVideoMirrorType_Enable"; + TRTCVideoMirrorType[TRTCVideoMirrorType["TRTCVideoMirrorType_Disable"] = 2] = "TRTCVideoMirrorType_Disable"; +})(TRTCVideoMirrorType || (TRTCVideoMirrorType = {})); +/** + * 美颜(磨皮)算法
+ * TRTC SDK 内置了多种不同的磨皮算法,您可以选择最适合您产品定位的方案。 + * @enum {Number} + */ +const TRTCBeautyStyle_HACK_JSDOC = { + /** 光滑,算法比较激进,磨皮效果比较明显,适用于秀场直播 */ + TRTCBeautyStyleSmooth: 0, + /** 自然,算法更多地保留了面部细节,磨皮效果更加自然,适用于绝大多数直播场景 */ + TRTCBeautyStyleNature: 1, + /** 优图,由优图实验室提供,磨皮效果介于光滑和自然之间,比光滑保留更多皮肤细节,比自然磨皮程度更高 */ + TRTCBeautyStylePitu: 2, +}; +export var TRTCBeautyStyle; +(function (TRTCBeautyStyle) { + TRTCBeautyStyle[TRTCBeautyStyle["TRTCBeautyStyleSmooth"] = 0] = "TRTCBeautyStyleSmooth"; + TRTCBeautyStyle[TRTCBeautyStyle["TRTCBeautyStyleNature"] = 1] = "TRTCBeautyStyleNature"; + TRTCBeautyStyle[TRTCBeautyStyle["TRTCBeautyStylePitu"] = 2] = "TRTCBeautyStylePitu"; +})(TRTCBeautyStyle || (TRTCBeautyStyle = {})); +/** + * 背景音效
+ * @enum {Number} + */ +export class AudioMusicParam { + constructor(id, path, loopCount, publish, isShortFile, startTimeMS, endTimeMS) { + this.id = id; + this.path = path; + this.loopCount = loopCount; + this.publish = publish; + this.isShortFile = isShortFile; + this.startTimeMS = startTimeMS; + this.endTimeMS = endTimeMS; + } +} +///////////////////////////////////////////////////////////////////////////////// +// +// 【(二)网络相关枚举值定义】 +// +///////////////////////////////////////////////////////////////////////////////// +/** + * 应用场景
+ * TRTC 可用于视频会议和在线直播等多种应用场景,针对不同的应用场景,TRTC SDK 的内部会进行不同的优化配置: + * - TRTCAppSceneVideoCall :视频通话场景,适合[1对1视频通话]、[300人视频会议]、[在线问诊]、[视频聊天]、[远程面试]等。 + * - TRTCAppSceneLIVE :视频互动直播,适合[视频低延时直播]、[十万人互动课堂]、[视频直播 PK]、[视频相亲房]、[互动课堂]、[远程培训]、[超大型会议]等。 + * - TRTCAppSceneAudioCall :语音通话场景,适合[1对1语音通话]、[300人语音会议]、[语音聊天]、[语音会议]、[在线狼人杀]等。 + * - TRTCAppSceneVoiceChatRoom:语音互动直播,适合:[语音低延时直播]、[语音直播连麦]、[语聊房]、[K 歌房]、[FM 电台]等。 + * @enum {Number} + */ +const TRTCAppScene_HACK_JSDOC = { + /** + * 视频通话场景,支持720P、1080P高清画质,单个房间最多支持300人同时在线,最高支持50人同时发言。
+ * 适合:[视频低延时直播]、[十万人互动课堂]、[视频直播 PK]、[视频相亲房]、[互动课堂]、[远程培训]、[超大型会议]等。
+ * 注意:此场景下,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色。 + */ + TRTCAppSceneVideoCall: 0, + /** + * 视频互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。
+ * 在线直播场景,内部编码器和网络协议优化侧重性能和兼容性,性能和清晰度表现更佳。 + */ + TRTCAppSceneLIVE: 1, + /** + * 语音通话场景,支持 48kHz,支持双声道。单个房间最多支持300人同时在线,最高支持50人同时发言。
+ * 适合:[1对1语音通话]、[300人语音会议]、[语音聊天]、[语音会议]、[在线狼人杀]等。 + */ + TRTCAppSceneAudioCall: 2, + /** + * 语音互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。
+ * 适合:[语音低延时直播]、[语音直播连麦]、[语聊房]、[K 歌房]、[FM 电台]等。
+ * 注意:此场景下,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色。 + */ + TRTCAppSceneVoiceChatRoom: 3, +}; +export var TRTCAppScene; +(function (TRTCAppScene) { + TRTCAppScene[TRTCAppScene["TRTCAppSceneVideoCall"] = 0] = "TRTCAppSceneVideoCall"; + TRTCAppScene[TRTCAppScene["TRTCAppSceneLIVE"] = 1] = "TRTCAppSceneLIVE"; + TRTCAppScene[TRTCAppScene["TRTCAppSceneAudioCall"] = 2] = "TRTCAppSceneAudioCall"; + TRTCAppScene[TRTCAppScene["TRTCAppSceneVoiceChatRoom"] = 3] = "TRTCAppSceneVoiceChatRoom"; +})(TRTCAppScene || (TRTCAppScene = {})); +/** + * 角色,仅适用于直播场景(TRTCAppSceneLIVE 和 TRTCAppSceneVoiceChatRoom)
+ * 在直播场景中,多数用户只是观众,只有个别用户是主播,这种角色区分可以有利于 TRTC 进行更好的定向优化。 + * - Anchor:主播,可以上行视频和音频,一个房间里最多支持50个主播同时上行音视频。 + * - Audience:观众,只能观看,不能上行视频和音频,一个房间里的观众人数没有上限。 + * + * @enum {Number} + */ +const TRTCRoleType_HACK_JSDOC = { + /** 主播 */ + TRTCRoleAnchor: 20, + /** 观众 */ + TRTCRoleAudience: 21, +}; +export var TRTCRoleType; +(function (TRTCRoleType) { + TRTCRoleType[TRTCRoleType["TRTCRoleAnchor"] = 20] = "TRTCRoleAnchor"; + TRTCRoleType[TRTCRoleType["TRTCRoleAudience"] = 21] = "TRTCRoleAudience"; +})(TRTCRoleType || (TRTCRoleType = {})); +///////////////////////////////////////////////////////////////////////////////// +// +// 【(三)音频相关枚举值定义】 +// +///////////////////////////////////////////////////////////////////////////////// +/** + * 音频质量
+ * @enum {Number} + */ +const TRTCAudioQuality_HACK_JSDOC = { + /** 人声模式:适用于以人声沟通为主的应用场景,该模式下音频传输的抗性较强,TRTC 会通过各种人声处理技术保障在弱网络环境下的流畅度最佳 */ + TRTCAudioQualitySpeech: 1, + /** 标准模式(或者默认模式):介于 Speech 和 Music 之间的档位,对音乐的还原度比人声模式要好,但传输数据量比音乐模式要低很多,对各种场景均有不错的适应性,如无特殊需求推荐选择之。 */ + TRTCAudioQualityDefault: 2, + /** 音乐模式:适用于对声乐要求很苛刻的场景,该模式下音频传输的数据量很大,TRTC 会通过各项技术确保音乐信号在各频段均能获得高保真的细节还原度 */ + TRTCAudioQualityMusic: 3 +}; +export var TRTCAudioQuality; +(function (TRTCAudioQuality) { + TRTCAudioQuality[TRTCAudioQuality["TRTCAudioQualitySpeech"] = 1] = "TRTCAudioQualitySpeech"; + TRTCAudioQuality[TRTCAudioQuality["TRTCAudioQualityDefault"] = 2] = "TRTCAudioQualityDefault"; + TRTCAudioQuality[TRTCAudioQuality["TRTCAudioQualityMusic"] = 3] = "TRTCAudioQualityMusic"; +})(TRTCAudioQuality || (TRTCAudioQuality = {})); +///////////////////////////////////////////////////////////////////////////////// +// +// 【(四)TRTC 核心类型定义】 +// +///////////////////////////////////////////////////////////////////////////////// +/** + * 进房相关参数
+ * 只有该参数填写正确,才能顺利调用 enterRoom 进入 roomId 所指定的音视频房间。 + * @param {Number} sdkAppId - 【字段含义】应用标识(必填),腾讯视频云基于 sdkAppId 完成计费统计。
+ * 【推荐取值】在腾讯云 [TRTC 控制台](https://console.cloud.tencent.com/rav/) 中创建应用,之后可以在账号信息页面中得到该 ID。
+ * @param {String} userId - 【字段含义】用户标识(必填)。当前用户的 userId,相当于用户名,UTF-8编码。
+ * 【推荐取值】如果一个用户在您的账号系统中的 ID 为“abc”,则 userId 即可设置为“abc”。
+ * @param {String} userSig - 【字段含义】用户签名(必填),当前 userId 对应的验证签名,相当于登录密码。
+ * 【推荐取值】请参考 [如何计算UserSig](https://cloud.tencent.com/document/product/647/17275)。
+ * @param {Number} roomId - 【字段含义】房间号码(必填),指定房间号,在同一个房间里的用户(userId)可以彼此看到对方并进行视频通话, roomId 和 strRoomId 必须填一个, 若您选用 strRoomId,则 roomId 需要填写为0。
+ * 【推荐取值】您可以随意指定,但请不要重复,如果您的用户账号 ID 是数字类型的,可以直接用创建者的用户 ID 作为 roomId。
+ * @param {String} strRoomId - 【字段含义】字符串房间号码(选填),roomId 和 strRoomId 必须填一个。若两者都填,则优先选择 roomId。
+ * 【推荐取值】您可以随意指定,但请不要重复。
+ * @param {TRTCRoleType} role - 【字段含义】直播场景下的角色,仅适用于直播场景(TRTCAppSceneLIVE 和 TRTCAppSceneVoiceChatRoom),视频通话场景下指定无效。
+ * 【推荐取值】默认值:主播(TRTCRoleAnchor)
+ * @param {String} privateMapKey - 【字段含义】房间签名(非必填),如果您希望某个房间只能让特定的某些 userId 进入,就需要使用 privateMapKey 进行权限保护。
+ * 【推荐取值】仅建议有高级别安全需求的客户使用,参考文档:[进房权限保护](https://cloud.tencent.com/document/product/647/32240)
+ * @param {String} businessInfo - 【字段含义】业务数据(非必填),某些非常用的高级特性才需要用到此字段。
+ * 【推荐取值】不建议使用
+ * @param {String} streamId - 【字段含义】绑定腾讯云直播 CDN 流 ID[非必填],设置之后,您就可以在腾讯云直播 CDN 上通过标准直播方案(FLV或HLS)播放该用户的音视频流。
+ * 【推荐取值】限制长度为64字节,可以不填写,一种推荐的方案是使用 “sdkappid_roomid_userid_main” 作为 streamid,这样比较好辨认且不会在您的多个应用中发生冲突。
+ * 【特殊说明】要使用腾讯云直播 CDN,您需要先在[控制台](https://console.cloud.tencent.com/trtc/) 中的功能配置页开启“启动自动旁路直播”开关。
+ * 【参考文档】[CDN 旁路直播](https://cloud.tencent.com/document/product/647/16826)。 + * @param {String} userDefineRecordId - 【字段含义】设置云端录制完成后的回调消息中的 "userdefinerecordid" 字段内容,便于您更方便的识别录制回调。
+ * 【推荐取值】限制长度为64字节,只允许包含大小写英文字母(a-zA-Z)、数字(0-9)及下划线和连词符。
+ * 【参考文档】[云端录制](https://cloud.tencent.com/document/product/647/16823)。 + */ +export class TRTCParams { + constructor(sdkAppId, userId, roomId, userSig, strRoomId, privateMapKey, role, businessInfo, streamId, userDefineRecordId) { + this.sdkAppId = sdkAppId; + this.userId = userId; + this.roomId = roomId; + this.userSig = userSig; + this.strRoomId = strRoomId; + this.privateMapKey = privateMapKey; + this.role = role; + this.businessInfo = businessInfo; + this.streamId = streamId; + this.userDefineRecordId = userDefineRecordId; + } +} +/** + * 视频编码参数
+ * 该设置决定了远端用户看到的画面质量(同时也是云端录制出的视频文件的画面质量)。 + * @param {TRTCVideoResolution} videoResolution - 【字段含义】 视频分辨率
+ * 【推荐取值】
+ * - 视频通话建议选择360 × 640及以下分辨率,resMode 选择 Portrait。
+ * - 手机直播建议选择 540 × 960,resMode 选择 Portrait。
+ * - Window 和 iMac 建议选择 640 × 360 及以上分辨率,resMode 选择 Landscape。 + * 【特别说明】 TRTCVideoResolution 默认只能横屏模式的分辨率,例如640 × 360。
+ * 如需使用竖屏分辨率,请指定 resMode 为 Portrait,例如640 × 360结合 Portrait 则为360 × 640。
+ * @param {TRTCVideoResolutionMode} resMode - 【字段含义】分辨率模式(横屏分辨率 - 竖屏分辨率)
+ * 【推荐取值】手机直播建议选择 Portrait,Window 和 Mac 建议选择 Landscape。
+ * 【特别说明】如果 videoResolution 指定分辨率 640 × 360,resMode 指定模式为 Portrait,则最终编码出的分辨率为360 × 640。
+ * @param {Number} videoFps - 【字段含义】视频采集帧率
+ * 【推荐取值】15fps 或 20fps,10fps 以下会有轻微卡顿感,5fps 以下卡顿感明显,20fps 以上的帧率则过于浪费(电影的帧率也只有 24fps)。
+ * 【特别说明】很多 Android 手机的前置摄像头并不支持15fps以上的采集帧率,部分过于突出美颜功能的 Android 手机前置摄像头的采集帧率可能低于10fps。
+ * @param {Number} videoBitrate - 【字段含义】视频上行码率
+ * 【推荐取值】推荐设置请参考本文件前半部分 TRTCVideoResolution 定义处的注释说明
+ * 【特别说明】码率太低会导致视频中有很多的马赛克
+ * @param {Number} minVideoBitrate -【字段含义】最低视频码率,SDK 会在网络不佳的情况下主动降低视频码率,最低会降至 minVideoBitrate 所设定的数值。 + * 【推荐取值】
+ * - 如果您追求“允许卡顿但要保持清晰”的效果,可以设置 minVideoBitrate 为 videoBitrate 的 60%; + * - 如果您追求“允许模糊但要保持流畅”的效果,可以设置 minVideoBitrate 为 200kbps; + * - 如果您将 videoBitrate 和 minVideoBitrate 设置为同一个值,等价于关闭 SDK 的自适应调节能力; + * - 默认值:0,此时最低码率由 SDK 根据分辨率情况,自动设置合适的数值。
+ * 【特别说明】
+ * - 当您把分辨率设置的比较高时,minVideoBitrate 不适合设置的太低,否则会出现画面模糊和大范围的马赛克宏块。 + * 比如把分辨率设置为 720p,把码率设置为 200kbps,那么编码出的画面将会出现大范围区域性马赛克。 + * @param {Boolean} enableAdjustRes - 【字段含义】是否允许调整分辨率
+ * 【推荐取值】
+ * - 手机直播建议选择 NO。
+ * - 视频通话模式,若更关注流畅性,建议选择 YES,此时若遇到带宽有限的弱网,SDK 会自动降低分辨率以保障更好的流畅度(仅针对 TRTCVideoStreamTypeBig 生效)。 + * - 默认值:NO。
+ * 【特别说明】若有录制需求,选择 YES 时,请确保通话过程中,调整分辨率不会影响您的录制效果。
+ */ +export class TRTCVideoEncParam { + constructor(videoResolution = TRTCVideoResolution.TRTCVideoResolution_640_360, resMode = TRTCVideoResolutionMode.TRTCVideoResolutionModePortrait, videoFps = 15, videoBitrate = 550, minVideoBitrate = 0, enableAdjustRes = false) { + this.videoResolution = videoResolution; + this.videoResolutionMode = resMode; + this.videoFps = videoFps; + this.videoBitrate = videoBitrate; + this.minVideoBitrate = minVideoBitrate; + this.enableAdjustRes = enableAdjustRes; + } +} +; +/** + * 画面渲染参数
+ * 您可以通过设置此参数来控制画面的旋转、填充、镜像模式 + * @param {TRTCVideoRotation} rotation - 【字段含义】视频画面旋转方向 + * @param {TRTCVideoFillMode} fillMode - 【字段含义】视频画面填充模式 + * @param {TRTCVideoMirrorType} mirrorType - 【字段含义】画面渲染镜像类型 + */ +export class TRTCRenderParams { + constructor(rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fit, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Disable) { + this.rotation = rotation; + this.fillMode = fillMode; + this.mirrorType = mirrorType; + } +} +/** + * 音频路由(即声音的播放模式)
+ * @enum {Number} + */ +const TRTCAudioRoute_HACK_JSDOC = { + /** 使用扬声器播放(即“免提”),扬声器位于手机底部,声音偏大,适合外放音乐 */ + TRTCAudioRouteSpeaker: 0, + /** 使用听筒播放,听筒位于手机顶部,声音偏小,适合需要保护隐私的通话场景 */ + TRTCAudioRouteEarpiece: 1, +}; +export var TRTCAudioRoute; +(function (TRTCAudioRoute) { + TRTCAudioRoute[TRTCAudioRoute["TRTCAudioRouteSpeaker"] = 0] = "TRTCAudioRouteSpeaker"; + TRTCAudioRoute[TRTCAudioRoute["TRTCAudioRouteEarpiece"] = 1] = "TRTCAudioRouteEarpiece"; +})(TRTCAudioRoute || (TRTCAudioRoute = {})); +///////////////////////////////////////////////////////////////////////////////// +// +// 【其它参数】 +// +///////////////////////////////////////////////////////////////////////////////// +export var TRTCShareSource; +(function (TRTCShareSource) { + TRTCShareSource["InApp"] = "InApp"; + TRTCShareSource["ByReplaykit"] = "ByReplaykit"; +})(TRTCShareSource || (TRTCShareSource = {})); diff --git a/TrtcCloud/lib/constants.js b/TrtcCloud/lib/constants.js new file mode 100644 index 0000000..fca320d --- /dev/null +++ b/TrtcCloud/lib/constants.js @@ -0,0 +1,10 @@ +export const NAME = { + ANDROID: 'android', + IOS: 'ios', + STRING: 'string', + FUNCTION: 'function', + BOOLEAN: 'boolean', + NUMBER: 'number', + LOG_PREFIX: '【UniApp-JS】', +}; +export const errorCodeUrl = 'https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/ErrorCode.html'; diff --git a/TrtcCloud/lib/index.js b/TrtcCloud/lib/index.js new file mode 100644 index 0000000..6722a01 --- /dev/null +++ b/TrtcCloud/lib/index.js @@ -0,0 +1,883 @@ +import TrtcCloudImpl from './TrtcCloudImpl'; +import { TRTCVideoStreamType, } from './TrtcDefines'; +const version = '1.2.0'; +export * from './TrtcDefines'; +/** + * TrtcCloud + * + * @class TrtcCloud + */ +export default class TrtcCloud { + /** + * 创建 TrtcCloud 单例 + * + * @static + * @memberof TrtcCloud + * @example + * TrtcCloud.createInstance(); + */ + static createInstance() { + console.log('----------------------------------------------------------------'); + console.log(` SDK ${version} `); + console.log('----------------------------------------------------------------'); + return TrtcCloudImpl._createInstance(); + } + /** + * 销毁 TrtcCloud 单例 + * + * @static + * @memberof TrtcCloud + * @example + * TrtcCloud.destroyInstance(); + */ + static destroyInstance() { + return TrtcCloudImpl._destroyInstance(); + } + /** + * 设置 TrtcCloud 事件监听 + * + * @param {String} event 事件名称 + * @param {Function} callback 事件回调 + * @memberof TrtcCloud + * + * @example + * this.trtcCloud = TrtcCloud.createInstance(); // 创建 trtcCloud 实例 + * this.trtcCloud.on('onEnterRoom', (res) => {}); + */ + on(event, callback) { + return TrtcCloudImpl._getInstance().on(event, callback); + } + /** + * 取消事件绑定
+ * + * @param {String} event 事件名称,传入通配符 '*' 会解除所有事件绑定。 + * @memberof TrtcCloud + * @example + * this.trtcCloud.off('onEnterRoom'); + * + * this.trtcCloud.off('*'); // 取消所有绑定的事件 + */ + off(event) { + return TrtcCloudImpl._getInstance().off(event); + } + /** + * 进房
+ * 调用接口后,您会收到来自 TRTCCallback 中的 [onEnterRoom(result)]{@link TRTCCallback#onEnterRoom} 回调 + * 如果加入成功,result 会是一个正数(result > 0),表示加入房间所消耗的时间,单位是毫秒(ms)。
+ * 如果加入失败,result 会是一个负数(result < 0),表示进房失败的错误码。 + * + * * 参数 scene 的枚举值如下: + * - {@link TRTCAppSceneVideoCall}:
+ * 视频通话场景,支持720P、1080P高清画质,单个房间最多支持300人同时在线,最高支持50人同时发言。
+ * 适合:[1对1视频通话]、[300人视频会议]、[在线问诊]、[视频聊天]、[远程面试]等。
+ * - {@link TRTCAppSceneAudioCall}:
+ * 语音通话场景,支持 48kHz,支持双声道。单个房间最多支持300人同时在线,最高支持50人同时发言。
+ * 适合:[1对1语音通话]、[300人语音会议]、[语音聊天]、[语音会议]、[在线狼人杀]等。
+ * - {@link TRTCAppSceneLIVE}:
+ * 视频互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。
+ * 适合:[视频低延时直播]、[十万人互动课堂]、[视频直播 PK]、[视频相亲房]、[互动课堂]、[远程培训]、[超大型会议]等。
+ * - {@link TRTCAppSceneVoiceChatRoom}:
+ * 语音互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。
+ * 适合:[语音低延时直播]、[语音直播连麦]、[语聊房]、[K 歌房]、[FM 电台]等。
+ * + * **Note:** + * 1. 当 scene 选择为 TRTCAppSceneLIVE 或 TRTCAppSceneVoiceChatRoom 时,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色。 + * 2. 不管进房是否成功,enterRoom 都必须与 exitRoom 配对使用,在调用 `exitRoom` 前再次调用 `enterRoom` 函数会导致不可预期的错误问题。 + * + * @param {TRTCParams} params - 进房参数 + * @param {Number} params.sdkAppId - 应用标识(必填) + * @param {String} params.userId - 用户标识(必填) + * @param {String} params.userSig - 用户签名(必填) + * @param {Number} params.roomId - 房间号码, roomId 和 strRoomId 必须填一个, 若您选用 strRoomId,则 roomId 需要填写为0。 + * @param {String} params.strRoomId - 字符串房间号码 [选填],在同一个房间内的用户可以看到彼此并进行视频通话, roomId 和 strRoomId 必须填一个。若两者都填,则优先选择 roomId + * @param {TRTCRoleType} params.role - 直播场景下的角色,默认值:主播 + * - TRTCRoleAnchor: 主播,可以上行视频和音频,一个房间里最多支持50个主播同时上行音视频。 + * - TRTCRoleAudience: 观众,只能观看,不能上行视频和音频,一个房间里的观众人数没有上限。 + * @param {String=} params.privateMapKey - 房间签名(非必填) + * @param {String=} params.businessInfo - 业务数据(非必填) + * @param {String=} params.streamId - 自定义 CDN 播放地址(非必填) + * @param {String=} params.userDefineRecordId - 设置云端录制完成后的回调消息中的 "userdefinerecordid" 字段内容,便于您更方便的识别录制回调(非必填) + * @param {TRTCAppScene} scene 应用场景,目前支持视频通话(TRTCAppSceneVideoCall)、语音通话(TRTCAppSceneAudioCall)、在线直播(TRTCAppSceneLIVE)、语音聊天室(VTRTCAppSceneVoiceChatRoom)四种场景, + * 详见 [TrtcDefines] 中 TRTCAppScene 参数定义 + * + * @memberof TrtcCloud + * @example + * import { TRTCAppScene } from '@/TrtcCloud/lib/TrtcDefines'; + * this.trtcCloud = TrtcCloud.createInstance(); // 创建实例,只需创建一次 + * const params = { + * sdkAppId: 0, + * userId: 'xxx', + * roomId: 12345, + * userSig: 'xxx' + * }; + * this.trtcCloud.enterRoom(params, TRTCAppScene.TRTCAppSceneVideoCall); + */ + enterRoom(params, scene) { + return TrtcCloudImpl._getInstance().enterRoom(params, scene); + } + /** + * 退房
+ * 执行退出房间的相关逻辑释放资源后,SDK 会通过 `onExitRoom()` 回调通知到您 + * + * **Note:** + * 1. 如果您要再次调用 `enterRoom()` 或者切换到其它的音视频 SDK,请等待 `onExitRoom()` 回调到来后再执行相关操作,否则可能会遇到如摄像头、麦克风设备被强占等各种异常问题。 + * + * @memberof TrtcCloud + * @example + * this.trtcCloud.exitRoom(); + */ + exitRoom() { + return TrtcCloudImpl._getInstance().exitRoom(); + } + /** + * 切换角色,仅适用于直播场景(TRTCAppSceneLIVE 和 TRTCAppSceneVoiceChatRoom) + * + * 在直播场景下,一个用户可能需要在“观众”和“主播”之间来回切换。 + * 您可以在进房前通过 TRTCParams 中的 role 字段确定角色,也可以通过 switchRole 在进房后切换角色。 + * + * @param {TRTCRoleType} role - 目标角色,默认为主播 + * - TRTCRoleAnchor: 主播,可以上行视频和音频,一个房间里最多支持50个主播同时上行音视频。 + * - TRTCRoleAudience: 观众,只能观看,不能上行视频和音频,一个房间里的观众人数没有上限。 + * + * @memberof TrtcCloud + * @example + * import { TRTCRoleType } from '@/TrtcCloud/lib/TrtcDefines'; + * this.trtcCloud.switchRole(TRTCRoleType.TRTCRoleAudience); + */ + switchRole(role) { + return TrtcCloudImpl._getInstance().switchRole(role); + } + /** + * 开启本地视频的预览画面
+ * 当开始渲染首帧摄像头画面时,您会收到 `onFirstVideoFrame(null)` 回调 + * + * @param {Boolean} isFrontCamera 前置、后置摄像头,true:前置摄像头;false:后置摄像头,**默认为 true** + * @param {String=} viewId 用于承载视频画面的渲染控件,使用原生插件中的 TRTCCloudUniPlugin-TXLocalViewComponent component,需要提供 viewId 属性值,例如 viewId=userId + * @memberof TrtcCloud + * @example + * // 预览本地画面 + * const viewId = this.userId; + * this.trtcCloud.startLocalPreview(true, viewId); + */ + startLocalPreview(isFrontCamera = true, viewId) { + return TrtcCloudImpl._getInstance().startLocalPreview(isFrontCamera, viewId); + } + /** + * 设置视频编码器的编码参数 + * - 该设置能够决定远端用户看到的画面质量,同时也能决定云端录制出的视频文件的画面质量。 + * @param {TRTCVideoEncParam} param 用于设置视频编码器的相关参数 + * @memberof TrtcCloud + * @example + * + * import { TRTCVideoResolution, TRTCVideoResolutionMode, TRTCVideoEncParam } from '@/TrtcCloud/lib/TrtcDefines'; + * const videoResolution = TRTCVideoResolution.TRTCVideoResolution_480_360; + * const videoResolutionMode = TRTCVideoResolutionMode.TRTCVideoResolutionModeLandscape; // 横屏采集 + * const videoFps = 15; + * const videoBitrate = 900; + * const minVideoBitrate = 200; + * const enableAdjustRes = false; + * // const param = new TRTCVideoEncParam(videoResolution, videoResolutionMode, videoFps, videoBitrate, minVideoBitrate, enableAdjustRes); // v1.1.0 方式 + * + * const param = { // v1.2.0 以上版本支持的方式 + * videoResolution, + * videoResolutionMode, + * videoFps, + * videoBitrate, + * minVideoBitrate, + * enableAdjustRes, + * }; + * + * this.trtcCloud.setVideoEncoderParam(param); + */ + setVideoEncoderParam(param) { + return TrtcCloudImpl._getInstance().setVideoEncoderParam(param); + } + /** + * 切换前置或后置摄像头 + * + * @param {Boolean} isFrontCamera 前置、后置摄像头,true:前置摄像头;false:后置摄像头 + * @memberof TrtcCloud + * @example + * // 切换前置或后置摄像头 + * const isFrontCamera = true; + * this.trtcCloud.switchCamera(isFrontCamera); + */ + switchCamera(isFrontCamera) { + return TrtcCloudImpl._getInstance().switchCamera(isFrontCamera); + } + /** + * 停止本地视频采集及预览 + * + * @memberof TrtcCloud + * @example + * this.trtcCloud.stopLocalPreview(); + */ + stopLocalPreview() { + return TrtcCloudImpl._getInstance().stopLocalPreview(); + } + /** + * 设置本地画面的渲染参数,可设置的参数包括有:画面的旋转角度、填充模式以及左右镜像等。 + * @param {TRTCRenderParams} params - 本地图像的参数 + * @param {TRTCVideoRotation} params.rotation - 图像的顺时针旋转角度,支持90、180以及270旋转角度,默认值:TRTCVideoRotation.TRTCVideoRotation_0 + * @param {TRTCVideoFillMode} params.fillMode - 视频画面填充模式,填充(画面可能会被拉伸裁剪)或适应(画面可能会有黑边),默认值:TRTCVideoFillMode.TRTCVideoFillMode_Fill + * @param {TRTCVideoMirrorType} params.mirrorType - 画面镜像模式,默认值:TRTCVideoMirrorType.TRTCVideoMirrorType_Auto + * + * @memberof TrtcCloud + * @example + * import { TRTCVideoRotation, TRTCVideoFillMode, TRTCVideoMirrorType } from '@/TrtcCloud/lib/TrtcDefines'; + * const renderParams = { + * rotation: TRTCVideoRotation.TRTCVideoRotation_0, + * fillMode: TRTCVideoFillMode.TRTCVideoFillMode_Fill, + * mirrorType: TRTCVideoMirrorType.TRTCVideoMirrorType_Auto + * }; + * this.trtcCloud.setLocalRenderParams(renderParams); + */ + setLocalRenderParams(params) { + return TrtcCloudImpl._getInstance().setLocalRenderParams(params); + } + /** + * 暂停/恢复发布本地的视频流 + * + * 该接口可以暂停(或恢复)发布本地的视频画面,暂停之后,同一房间中的其他用户将无法继续看到自己画面。 该接口在指定 TRTCVideoStreamTypeBig 时等效于 start/stopLocalPreview 这两个接口,但具有更好的响应速度。 因为 start/stopLocalPreview 需要打开和关闭摄像头,而打开和关闭摄像头都是硬件设备相关的操作,非常耗时。 相比之下,muteLocalVideo 只需要在软件层面对数据流进行暂停或者放行即可,因此效率更高,也更适合需要频繁打开关闭的场景。 当暂停/恢复发布指定 TRTCVideoStreamTypeBig 后,同一房间中的其他用户将会收到 onUserVideoAvailable 回调通知。 当暂停/恢复发布指定 TRTCVideoStreamTypeSub 后,同一房间中的其他用户将会收到 onUserSubStreamAvailable 回调通知。 + * @param {TRTCVideoStreamType} streamType 要暂停/恢复的视频流类型(仅支持 TRTCVideoStreamTypeBig 和 TRTCVideoStreamTypeSub) + * @param {Boolean} mute - true:屏蔽;false:开启,默认值:false + * + * @memberof TrtcCloud + * @example + * this.trtcCloud.muteLocalVideo(TRTCVideoStreamType.TRTCVideoStreamTypeBig, true); + */ + muteLocalVideo(streamType, mute) { + return TrtcCloudImpl._getInstance().muteLocalVideo(streamType, mute); + } + /** + * 显示远端视频或辅流
+ * + * @param {String} userId 指定远端用户的 userId + * @param {TRTCVideoStreamType} streamType 指定要观看 userId 的视频流类型 + * - 高清大画面:TRTCVideoStreamType.TRTCVideoStreamTypeBig + * - 低清小画面:TRTCVideoStreamType.TRTCVideoStreamTypeSmall + * - 辅流(屏幕分享):TRTCVideoStreamType.TRTCVideoStreamTypeSub + * @param {String} viewId 用于承载视频画面的渲染控件,使用原生插件中的 TRTCCloudUniPlugin-TXRemoteViewComponent component,需要提供 viewId 属性值,例如 viewId=userId + * @memberof TrtcCloud + * @example + * import { TRTCVideoStreamType } from '@/TrtcCloud/lib/TrtcDefines'; + * const viewId = this.remoteUserId; + * this.trtcCloud.startRemoteView(userId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, viewId); + */ + startRemoteView(userId, streamType, viewId) { + return TrtcCloudImpl._getInstance().startRemoteView(userId, streamType, viewId); + } + /** + * 停止显示远端视频画面,同时不再拉取该远端用户的视频数据流
+ * 指定要停止观看的 userId 的视频流类型 + * + * @param {String} userId 指定的远端用户 ID + * @param {TRTCVideoStreamType} streamType + * - 高清大画面:TRTCVideoStreamType.TRTCVideoStreamTypeBig + * - 低清小画面:TRTCVideoStreamType.TRTCVideoStreamTypeSmall + * - 辅流(屏幕分享):TRTCVideoStreamType.TRTCVideoStreamTypeSub + * @memberof TrtcCloud + * @example + * import { TRTCVideoStreamType } from '@/TrtcCloud/lib/TrtcDefines'; + * this.trtcCloud.stopRemoteView(remoteUserId, TRTCVideoStreamType.TRTCVideoStreamTypeBig); + */ + stopRemoteView(userId, streamType) { + return TrtcCloudImpl._getInstance().stopRemoteView(userId, streamType); + } + /** + * 设置远端画面的渲染参数,可设置的参数包括有:画面的旋转角度、填充模式以及左右镜像等。 + * @param {String} userId 远端用户 ID + * @param {TRTCVideoStreamType} streamType 可以设置为主路画面(TRTCVideoStreamTypeBig)或辅路画面(TRTCVideoStreamTypeSub) + * @param {TRTCRenderParams} params - 图像的参数 + * @param {TRTCVideoRotation} params.rotation - 图像的顺时针旋转角度,支持90、180以及270旋转角度,默认值:TRTCVideoRotation.TRTCVideoRotation_0 + * @param {TRTCVideoFillMode} params.fillMode - 视频画面填充模式,填充(画面可能会被拉伸裁剪)或适应(画面可能会有黑边),默认值:TRTCVideoFillMode.TRTCVideoFillMode_Fill + * @param {TRTCVideoMirrorType} params.mirrorType - 画面镜像模式,默认值:TRTCVideoMirrorType.TRTCVideoMirrorType_Auto + * @memberof TrtcCloud + * @example + * import { TRTCVideoRotation, TRTCVideoFillMode, TRTCVideoMirrorType } from '@/TrtcCloud/lib/TrtcDefines'; + * const renderParams = { + * rotation: TRTCVideoRotation.TRTCVideoRotation_0, + * fillMode: TRTCVideoFillMode.TRTCVideoFillMode_Fill, + * mirrorType: TRTCVideoMirrorType.TRTCVideoMirrorType_Auto + * }; + * this.trtcCloud.setRemoteRenderParams(userId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, renderParams); + */ + setRemoteRenderParams(userId, streamType, params) { } + /** + * 视频画面截图 + * + * 您可以通过本接口截取本地的视频画面,远端用户的主路画面以及远端用户的辅路(屏幕分享)画面。 + * @param {String | null} userId 用户 ID,如指定 null 表示截取本地的视频画面 + * @param {TRTCVideoStreamType} streamType 视频流类型,可选择截取主路画面(TRTCVideoStreamTypeBig,常用于摄像头)或辅路画面(TRTCVideoStreamTypeSub,常用于屏幕分享) + * + * @memberof TrtcCloud + * @example + * import { TRTCVideoStreamType } from '@/TrtcCloud/lib/TrtcDefines'; + * this.trtcCloud.snapshotVideo(null, TRTCVideoStreamType.TRTCVideoStreamTypeBig); // 截取本地画面 + * this.trtcCloud.snapshotVideo(this.remoteUserId, TRTCVideoStreamType.TRTCVideoStreamTypeBig); // 截取远端指定用户画面 + */ + snapshotVideo(userId, streamType, listener) { + return TrtcCloudImpl._getInstance().snapshotVideo(userId, streamType, listener); + } + /** + * 开启本地音频的采集和上行, 并设置音频质量
+ * 该函数会启动麦克风采集,并将音频数据传输给房间里的其他用户。 SDK 不会默认开启本地音频采集和上行,您需要调用该函数开启,否则房间里的其他用户将无法听到您的声音
+ * 主播端的音质越高,观众端的听感越好,但传输所依赖的带宽也就越高,在带宽有限的场景下也更容易出现卡顿 + * + * @param {TRTCAudioQuality} quality 声音音质 + * - TRTCAudioQualitySpeech,流畅:采样率:16k;单声道;音频裸码率:16kbps;适合语音通话为主的场景,比如在线会议,语音通话。 + * - TRTCAudioQualityDefault,默认:采样率:48k;单声道;音频裸码率:50kbps;SDK 默认的音频质量,如无特殊需求推荐选择之。 + * - TRTCAudioQualityMusic,高音质:采样率:48k;双声道 + 全频带;音频裸码率:128kbps;适合需要高保真传输音乐的场景,比如在线K歌、音乐直播等 + * @memberof TrtcCloud + * @example + * import { TRTCAudioQuality } from '@/TrtcCloud/lib/TrtcDefines'; + * this.trtcCloud.startLocalAudio(TRTCAudioQuality.TRTCAudioQualityDefault); + */ + startLocalAudio(quality) { + return TrtcCloudImpl._getInstance().startLocalAudio(quality); + } + /** + * 关闭本地音频的采集和上行
+ * 当关闭本地音频的采集和上行,房间里的其它成员会收到 `onUserAudioAvailable(false)` 回调通知 + * + * @memberof TrtcCloud + * @example + * this.trtcCloud.stopLocalAudio(); + */ + stopLocalAudio() { + return TrtcCloudImpl._getInstance().stopLocalAudio(); + } + /** + * 静音本地的音频 + * + * 当静音本地音频后,房间里的其它成员会收到 onUserAudioAvailable(false) 回调通知。 + * 与 stopLocalAudio 不同之处在于,muteLocalAudio 并不会停止发送音视频数据,而是会继续发送码率极低的静音包。 + * 在对录制质量要求很高的场景中,选择 muteLocalAudio 是更好的选择,能录制出兼容性更好的 MP4 文件。 + * 这是由于 MP4 等视频文件格式,对于音频的连续性是要求很高的,简单粗暴地 stopLocalAudio 会导致录制出的 MP4 不易播放。 + * + * @param {Boolean} mute - true:屏蔽;false:开启,默认值:false + * + * @memberof TrtcCloud + * @example + * this.trtcCloud.muteLocalAudio(true); + */ + muteLocalAudio(mute) { + return TrtcCloudImpl._getInstance().muteLocalAudio(mute); + } + /** + * 静音掉某一个用户的声音,同时不再拉取该远端用户的音频数据流 + * + * @param {String} userId - 用户 ID + * @param {Boolean} mute - true:静音;false:非静音 + * + * @memberof TrtcCloud + * @example + * this.trtcCloud.muteRemoteAudio('denny', true); + */ + muteRemoteAudio(userId, mute) { + return TrtcCloudImpl._getInstance().muteRemoteAudio(userId, mute); + } + /** + * 静音掉所有用户的声音,同时不再拉取该远端用户的音频数据流 + * + * @param {Boolean} mute - true:静音;false:非静音 + * + * @memberof TrtcCloud + * @example + * this.trtcCloud.muteAllRemoteAudio(true); + */ + muteAllRemoteAudio(mute) { + return TrtcCloudImpl._getInstance().muteAllRemoteAudio(mute); + } + /** + * 设置音频路由 + * + * 设置“音频路由”,即设置声音是从手机的扬声器还是从听筒中播放出来,因此该接口仅适用于手机等移动端设备。 手机有两个扬声器:一个是位于手机顶部的听筒,一个是位于手机底部的立体声扬声器。 + * 设置音频路由为听筒时,声音比较小,只有将耳朵凑近才能听清楚,隐私性较好,适合用于接听电话。 设置音频路由为扬声器时,声音比较大,不用将手机贴脸也能听清,因此可以实现“免提”的功能。 + * + * @param {TRTCAudioRoute} route 音频路由,即声音由哪里输出(扬声器、听筒), 默认值:TRTCAudioRoute.TRTCAudioRouteSpeaker(扬声器), + * @memberof TrtcCloud + * @example + * import { TRTCAudioRoute } from '@/TrtcCloud/lib/TrtcDefines'; + * this.trtcCloud.setAudioRoute(TRTCAudioRoute.TRTCAudioRouteSpeaker); // TRTCAudioRoute.TRTCAudioRouteEarpiece (听筒) + */ + setAudioRoute(route) { + return TrtcCloudImpl._getInstance().setAudioRoute(route); + } + /** + * 启用或关闭音量大小提示 + * + * 开启此功能后,SDK 会在 onUserVoiceVolume() 中反馈对每一路声音音量大小值的评估。 + * + * **Note:** + * - 如需打开此功能,请在 startLocalAudio 之前调用才可以生效。 + * + * @param {Number} interval - 设置 onUserVoiceVolume 回调的触发间隔,单位为ms,最小间隔为100ms,如果小于等于0则会关闭回调,建议设置为300ms + * @memberof TrtcCloud + * @example + * this.trtcCloud.enableAudioVolumeEvaluation(300); + */ + enableAudioVolumeEvaluation(interval) { + return TrtcCloudImpl._getInstance().enableAudioVolumeEvaluation(interval); + } + ///////////////////////////////////////////////////////////////////////////////// + // + // 屏幕分享 + // + ///////////////////////////////////////////////////////////////////////////////// + /** + * 设置屏幕分享(即辅路)的视频编码参数 + * + * 该接口可以设定远端用户所看到的屏幕分享(即辅路)的画面质量,同时也能决定云端录制出的视频文件中屏幕分享的画面质量。 请注意如下两个接口的差异: + * - setVideoEncoderParam 用于设置主路画面(TRTCVideoStreamTypeBig,一般用于摄像头)的视频编码参数。 + * - setSubStreamEncoderParam 用于设置辅路画面(TRTCVideoStreamTypeSub,一般用于屏幕分享)的视频编码参数。 + * + * **Note:** + * - 即使您使用主路传输屏幕分享(在调用 startScreenCapture 时设置 type=TRTCVideoStreamTypeBig),依然要使用 setSubStreamEncoderParam 设定屏幕分享的编码参数,而不要使用 setVideoEncoderParam + * @param {TRTCVideoEncParam} param 辅流编码参数,详情请参考 TRTCVideoEncParam。 + * @memberof TrtcCloud + * @example + * const params = { + * videoResolution: TRTCVideoResolution.TRTCVideoResolution_640_360, + * videoResolutionMode: TRTCVideoResolutionMode.TRTCVideoResolutionModePortrait, + * videoFps: 15, + * videoBitrate: 900, + * minVideoBitrate: 200, + * enableAdjustRes: false, + * }; + * this.trtcCloud.setSubStreamEncoderParam(params); + */ + setSubStreamEncoderParam(param) { + return TrtcCloudImpl._getInstance().setSubStreamEncoderParam(param); + } + /** + * 启动屏幕分享 + * + * **Note:** + * - 一个用户同时最多只能上传一条主路(TRTCVideoStreamTypeBig)画面和一条辅路(TRTCVideoStreamTypeSub)画面, + * 默认情况下,屏幕分享使用辅路画面,如果使用主路画面,建议您提前停止摄像头采集(stopLocalPreview)避免相互冲突。 + * - **仅支持 iOS 13.0 及以上系统,进行应用内的屏幕分享** + * + * @param {TRTCVideoStreamType} streamType 屏幕分享使用的线路,可以设置为主路(TRTCVideoStreamTypeBig)或者辅路(TRTCVideoStreamTypeSub),推荐使用 + * @param {TRTCVideoEncParam} encParams 屏幕分享的画面编码参数,可以设置为 null,表示让 SDK 选择最佳的编码参数(分辨率、码率等)。即使在调用 startScreenCapture 时设置 type=TRTCVideoStreamTypeBig,依然可以使用此接口更新屏幕分享的编码参数。 + * @memberof TrtcCloud + * @example + * import { TRTCVideoResolution, TRTCVideoResolutionMode, TRTCVideoStreamType} from '@/TrtcCloud/lib/TrtcDefines'; + * const encParams = { + * videoResolution: TRTCVideoResolution.TRTCVideoResolution_640_360, + * videoResolutionMode: TRTCVideoResolutionMode.TRTCVideoResolutionModePortrait, + * videoFps: 15, + * videoBitrate: 900, + * minVideoBitrate: 200, + * enableAdjustRes: false, + * }; + * this.trtcCloud.startScreenCapture(TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams); + */ + startScreenCapture(streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams = null) { + return TrtcCloudImpl._getInstance().startScreenCapture(streamType, encParams); + } + /** + * 停止屏幕分享 + * @memberof TrtcCloud + * @example + * this.trtcCloud.stopScreenCapture(); + */ + stopScreenCapture() { + return TrtcCloudImpl._getInstance().stopScreenCapture(); + } + /** + * 暂停屏幕分享 + * @memberof TrtcCloud + * @example + * this.trtcCloud.pauseScreenCapture(); + */ + pauseScreenCapture() { + return TrtcCloudImpl._getInstance().pauseScreenCapture(); + } + /** + * 恢复屏幕分享 + * @memberof TrtcCloud + * @example + * this.trtcCloud.resumeScreenCapture(); + */ + resumeScreenCapture() { + return TrtcCloudImpl._getInstance().resumeScreenCapture(); + } + ///////////////////////////////////////////////////////////////////////////////// + // + // 美颜 + 水印 + // + ///////////////////////////////////////////////////////////////////////////////// + /** + * 设置美颜(磨皮)算法 + * TRTC 内置多种不同的磨皮算法,您可以选择最适合您产品定位的方案 + * + * **Note:** + * - 设置美颜前,先调用 `setBeautyLevel` 设置美颜级别。否则美颜级别为 0 表示关闭美颜 + * + * @param {TRTCBeautyStyle} beautyStyle 美颜风格,TRTCBeautyStyleSmooth:光滑;TRTCBeautyStyleNature:自然;TRTCBeautyStylePitu:优图 + * @memberof TrtcCloud + * @example + * import { TRTCBeautyStyle } from '@/TrtcCloud/lib/TrtcDefines'; + * const beautyLevel = 5; // 美颜级别,取值范围0 - 9; 0表示关闭,9表示效果最明显。 + * this.trtcCloud.setBeautyLevel(beautyLevel); + * this.trtcCloud.setBeautyStyle(TRTCBeautyStyle.TRTCBeautyStyleSmooth); + */ + setBeautyStyle(beautyStyle) { + return TrtcCloudImpl._getInstance().setBeautyStyle(beautyStyle); + } + /** + * 设置美颜级别 + * @param {Number} beautyLevel 美颜级别,取值范围0 - 9; 0表示关闭,9表示效果最明显。 + * + * @memberof TrtcCloud + * @example + * const beautyLevel = 5; // 美颜级别,取值范围0 - 9; 0表示关闭,9表示效果最明显。 + * this.trtcCloud.setBeautyLevel(beautyLevel); + */ + setBeautyLevel(beautyLevel) { + return TrtcCloudImpl._getInstance().setBeautyLevel(beautyLevel); + } + ///////////////////////////////////////////////////////////////////////////////// + // + // 背景音效 + // + ///////////////////////////////////////////////////////////////////////////////// + /** + * 开始播放背景音乐 + * 每个音乐都需要您指定具体的 ID,您可以通过该 ID 对音乐的开始、停止、音量等进行设置。
+ * **Note:** + * - 如果要多次播放同一首背景音乐,请不要每次播放都分配一个新的 ID,我们推荐使用相同的 ID。 + * - 若您希望同时播放多首不同的音乐,请为不同的音乐分配不同的 ID 进行播放。 + * - 如果使用同一个 ID 播放不同音乐,SDK 会先停止播放旧的音乐,再播放新的音乐。 + * + * **Note:**
+ * 在 uni-app 中 path 如何获取。 + * - 使用 cdn 地址,例如:`path = https://web.sdk.qcloud.com/component/TUIKit/assets/uni-app/calling-bell-1.mp3;` + * - 使用本地绝对路径。 + * 1. 通过 [uni.saveFile](https://zh.uniapp.dcloud.io/api/file/file.html#savefile) 获取保存后的相对路径(建议这种路径)。 + * 2. 将上一步的相对路径转成绝对路径,[plus.io.convertLocalFileSystemURL](https://www.html5plus.org/doc/zh_cn/io.html#plus.io.convertLocalFileSystemURL)。 + * + * @param {AudioMusicParam} musicParam 音乐参数 + * @param {Number} musicParam.id 音乐 ID + * @param {String} musicParam.path 音效文件的完整路径或 URL 地址。支持的音频格式包括 MP3、AAC、M4A、WAV + * @param {Number} musicParam.loopCount 音乐循环播放的次数。取值范围为0 - 任意正整数,默认值:0。0表示播放音乐一次;1表示播放音乐两次;以此类推 + * @param {Boolean} musicParam.publish 是否将音乐传到远端。true:音乐在本地播放的同时,远端用户也能听到该音乐;false:主播只能在本地听到该音乐,远端观众听不到。默认值:false。 + * @param {Boolean} musicParam.isShortFile 播放的是否为短音乐文件。true:需要重复播放的短音乐文件;false:正常的音乐文件。默认值:false + * @param {Number} musicParam.startTimeMS 音乐开始播放时间点,单位: 毫秒。 + * @param {Number} musicParam.endTimeMS 音乐结束播放时间点,单位: 毫秒,0 表示播放至文件结尾。 + * @memberof TrtcCloud + * @example + * import { AudioMusicParam } from '@/TrtcCloud/lib/TrtcDefines'; + * const musicParam = { + * id: 1, + * path: '', + * loopCount: 1, + * publish: true, + * isShortFile: false, + * startTimeMS: 0, + * endTimeMS: 0, + * }; + * this.trtcCloud.startPlayMusic(musicParam); + */ + startPlayMusic(musicParam) { + return TrtcCloudImpl._getInstance().startPlayMusic(musicParam); + } + /** + * 停止播放背景音乐 + * @param {Number} id 音乐 ID + * + * @memberof TrtcCloud + * @example + * const musicId = 5; + * this.trtcCloud.stopPlayMusic(musicId); + */ + stopPlayMusic(id) { + return TrtcCloudImpl._getInstance().stopPlayMusic(id); + } + /** + * 暂停播放背景音乐 + * @param {Number} id 音乐 ID + * @memberof TrtcCloud + * @example + * const musicId = 5; + * this.trtcCloud.pausePlayMusic(musicId); + */ + pausePlayMusic(id) { + return TrtcCloudImpl._getInstance().pausePlayMusic(id); + } + /** + * 恢复播放背景音乐 + * @param {Number} id 音乐 ID + * @memberof TrtcCloud + * @example + * const musicId = 5; + * this.trtcCloud.resumePlayMusic(musicId); + */ + resumePlayMusic(id) { + return TrtcCloudImpl._getInstance().resumePlayMusic(id); + } + ///////////////////////////////////////////////////////////////////////////////// + // + // 设置 TRTCCallback 回调 + // + ///////////////////////////////////////////////////////////////////////////////// + /** + * 设置 TrtcCloud 回调 + * + * @example + * // 创建/使用/销毁 TrtcCloud 对象的示例代码: + * import TrtcCloud from '@/TrtcCloud/lib/index'; + * this.trtcCloud = new TrtcCloud(); + * + * // 添加事件监听的方法,事件关键字详见下方”通用事件回调“ + * this.trtcCloud.on('onEnterRoom', (result) => { + * if (result > 0) { + * console.log(`enter room success, spend ${result}ms`); + * } else { + * console.log(`enter room failed, error code = ${result}`); + * } + * }); + * + * @namespace TRTCCallback + */ + ///////////////////////////////////////////////////////////////////////////////// + // + // (一)事件回调 + // + ///////////////////////////////////////////////////////////////////////////////// + /** + * 错误回调,表示 SDK 不可恢复的错误,一定要监听并分情况给用户适当的界面提示
+ * @event TRTCCallback#onError + * @param {Number} code 错误码,[详见](https://cloud.tencent.com/document/product/647/38308#.E9.94.99.E8.AF.AF.E7.A0.81.E8.A1.A8) + * @param {String} message 错误信息 + * @param {Object} extraInfo 扩展信息字段,个别错误码可能会带额外的信息帮助定位问题 + */ + onError(code, message, extraInfo) { } + /** + * 警告回调,用于告知您一些非严重性问题,例如出现卡顿或者可恢复的解码失败
+ * @event TRTCCallback#onWarning + * @param {Number} code 警告码,[详见](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8) + * @param {String} message 警告信息 + * @param {Object} extraInfo 扩展信息字段,个别警告码可能会带额外的信息帮助定位问题 + */ + onWarning(code, message, extraInfo) { } + /** + * 进房后的回调
+ * 调用 `enterRoom()` 接口执行进房操作后,会收到 `onEnterRoom(result)` 回调
+ * 如果加入成功,result 会是一个正数(result > 0),代表加入房间的时间消耗,单位是毫秒(ms)。
+ * 如果加入失败,result 会是一个负数(result < 0),代表进房失败的错误码。 + * + * @event TRTCCallback#onEnterRoom + * @param {Number} result 进房耗时 + */ + onEnterRoom(result) { } + /** + * 离开房间的事件回调
+ * 调用 `exitRoom()` 接口会执行退出房间的相关逻辑,例如释放音视频设备资源和编解码器资源等。待资源释放完毕,会通过 `onExitRoom()` 回调通知到您
+ * + * **Note:** + * - 如果您要再次调用 `enterRoom()` 或者切换到其他的音视频 SDK,请等待 `onExitRoom()` 回调到来之后再执行相关操作。 否则可能会遇到音频设备被占用等各种异常问题 + * + * @event TRTCCallback#onExitRoom + * @param {Number} reason 离开房间原因,0:主动调用 exitRoom 退房;1:被服务器踢出当前房间;2:当前房间整个被解散 + */ + onExitRoom(reason) { } + /** + * 切换角色的事件回调
+ * 调用 TRTCCloud 中的 switchRole() 接口会切换主播和观众的角色,该操作会伴随一个线路切换的过程, 待 SDK 切换完成后,会抛出 onSwitchRole() 事件回调 + * + * @event TRTCCallback#onSwitchRole + * @param {Number} code 错误码,[详见](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8) + * @param {String} message 错误信息 + */ + onSwitchRole(code, message) { } + /** + * 开始渲染本地或远程用户的首帧画面
+ * 如果 userId 为 null,代表开始渲染本地采集的摄像头画面,需要您先调用 `startLocalPreview` 触发。 如果 userId 不为 null,代表开始渲染远程用户的首帧画面,需要您先调用 `startRemoteView` 触发
+ * 只有当您调用 `startLocalPreview()、startRemoteView() 或 startRemoteSubStreamView()` 之后,才会触发该回调 + * + * @event TRTCCallback#onFirstVideoFrame + * @param {String} userId 本地或远程用户 ID,如果 userId === null 代表本地,userId !== null 代表远程 + * @param {TRTCVideoStreamType} streamType 视频流类型:摄像头或屏幕分享 + * @param {Number} width 画面宽度 + * @param {Number} height 画面高度 + */ + onFirstVideoFrame(userId, streamType, width, height) { } + /** + * 开始播放远程用户的首帧音频(本地声音暂不通知)
+ * 如果 userId 为 null,代表开始渲染本地采集的摄像头画面,需要您先调用 `startLocalPreview` 触发。 如果 userId 不为 null,代表开始渲染远程用户的首帧画面,需要您先调用 `startRemoteView` 触发
+ * 只有当您调用 `startLocalPreview()、startRemoteView() 或 startRemoteSubStreamView()` 之后,才会触发该回调 + * + * @event TRTCCallback#onFirstAudioFrame + * @param {String} userId 远程用户 ID + */ + onFirstAudioFrame(userId) { } + /** + * 截图完成时回调
+ * @event TRTCCallback#onSnapshotComplete + * @param {String} base64Data 截图对应的 base64 数据 + * @param {String} message 错误信息 + */ + onSnapshotComplete(base64Data, message) { } + /** + * 麦克风准备就绪 + */ + onMicDidReady() { } + /** + * 摄像头准备就绪 + */ + onCameraDidReady() { } + /** + * 网络质量:该回调每2秒触发一次,统计当前网络的上行和下行质量
+ * userId 为本地用户 ID 代表自己当前的视频质量 + * + * @param {String} localQuality 上行网络质量 + * @param {String} remoteQuality 下行网络质量 + */ + onNetworkQuality(localQuality, remoteList) { } + /** + * 有用户加入当前房间
+ * 出于性能方面的考虑,在两种不同的应用场景下,该通知的行为会有差别:
+ * 通话场景(TRTCAppScene.TRTCAppSceneVideoCall 和 TRTCAppScene.TRTCAppSceneAudioCall):该场景下用户没有角色的区别,任何用户进入房间都会触发该通知。
+ * 直播场景(TRTCAppScene.TRTCAppSceneLIVE 和 TRTCAppScene.TRTCAppSceneVoiceChatRoom ):该场景不限制观众的数量,如果任何用户进出都抛出回调会引起很大的性能损耗,所以该场景下只有主播进入房间时才会触发该通知,观众进入房间不会触发该通知 + * + * @event TRTCCallback#onRemoteUserEnterRoom + * @param {String} userId 用户标识 ID + */ + onRemoteUserEnterRoom(userId) { } + /** + * 有用户离开当前房间
+ * 与 onRemoteUserEnterRoom 相对应,在两种不同的应用场景下,该通知的行为会有差别:
+ * 通话场景(TRTCAppScene.TRTCAppSceneVideoCall 和 TRTCAppScene.TRTCAppSceneAudioCall):该场景下用户没有角色的区别,任何用户进入房间都会触发该通知。
+ * 直播场景(TRTCAppScene.TRTCAppSceneLIVE 和 TRTCAppScene.TRTCAppSceneVoiceChatRoom ):该场景不限制观众的数量,如果任何用户进出都抛出回调会引起很大的性能损耗,所以该场景下只有主播进入房间时才会触发该通知,观众进入房间不会触发该通知 + * + * @event TRTCCallback#onRemoteUserLeaveRoom + * @param {String} userId 用户标识 ID + * @param {Number} reason 离开原因,0 表示用户主动退出房间,1 表示用户超时退出,2 表示被踢出房间 + */ + onRemoteUserLeaveRoom(userId, reason) { } + /** + * 首帧本地音频数据已经被送出
+ * 在 `enterRoom()` 并 `startLocalAudio()` 成功后开始麦克风采集,并将采集到的声音进行编码。 当 SDK 成功向云端送出第一帧音频数据后,会抛出这个回调事件 + * + * @event TRTCCallback#onSendFirstLocalAudioFrame + */ + onSendFirstLocalAudioFrame() { } + /** + * 首帧本地视频数据已经被送出
+ * SDK 会在 `enterRoom()` 并 `startLocalPreview()` 成功后开始摄像头采集,并将采集到的画面进行编码。 当 SDK 成功向云端送出第一帧视频数据后,会抛出这个回调事件 + * + * @event TRTCCallback#onSendFirstLocalVideoFrame + * @param {TRTCVideoStreamType} streamType 视频流类型,大画面、小画面或辅流画面(屏幕分享) + */ + onSendFirstLocalVideoFrame(streamType) { } + /** + * 技术指标统计回调
+ * 如果您是熟悉音视频领域相关术语,可以通过这个回调获取 SDK 的所有技术指标。 如果您是首次开发音视频相关项目,可以只关注 `onNetworkQuality` 回调 + * + * **Note:** + * - 每 2 秒回调一次 + * + * @param {Object} statics 状态数据 + */ + onStatistics(statics) { } + /** + * 远端用户是否存在可播放的音频数据
+ * @event TRTCCallback#onUserAudioAvailable + * @param {String} userId 用户标识 ID + * @param {Boolean} available 声音是否开启 + */ + onUserAudioAvailable(userId, available) { } + /** + * 远端用户是否存在可播放的主路画面(一般用于摄像头)
+ * 当您收到 `onUserVideoAvailable(userId, true)` 通知时,表示该路画面已经有可用的视频数据帧到达。 此时,您需要调用 `startRemoteView(userId)` 接口加载该用户的远程画面。 然后,您会收到名为 onFirstVideoFrame(userid) 的首帧画面渲染回调。
+ * 当您收到 `onUserVideoAvailable(userId, false)` 通知时,表示该路远程画面已经被关闭,可能由于该用户调用了 `muteLocalVideo()` 或 `stopLocalPreview()`。 + * + * @event TRTCCallback#onUserVideoAvailable + * @param {String} userId 用户标识 ID + * @param {Boolean} available 画面是否开启 + */ + onUserVideoAvailable(userId, available) { } + /** + * 用于提示音量大小的回调,包括每个 userId 的音量和远端总音量
+ * SDK 可以评估每一路音频的音量大小,并每隔一段时间抛出该事件回调,您可以根据音量大小在 UI 上做出相应的提示,比如“波形图”或“音量槽”。 要完成这个功能, 您需要先调用 enableAudioVolumeEvaluation 开启这个能力并设定事件抛出的时间间隔。 需要补充说明的是,无论当前房间中是否有人说话,SDK 都会按照您设定的时间间隔定时抛出此事件回调,只不过当没有人说话时,userVolumes 为空,totalVolume 为 0。 + * + * **Note:** + * - userVolumes 为一个数组,对于数组中的每一个元素,当 userId 为空时表示本地麦克风采集的音量大小,当 userId 不为空时代表远端用户的音量大小 + * + * @event TRTCCallback#onUserVoiceVolume + * @param {Array} userVolumes 是一个数组,用于承载所有正在说话的用户的音量大小,取值范围 0 - 100 + * @param {Number} totalVolume 所有远端用户的总音量大小, 取值范围 0 - 100 + */ + onUserVoiceVolume(userVolumes, totalVolume) { } + /** + * 屏幕分享开启的事件回调
+ * 当您通过 startScreenCapture 等相关接口启动屏幕分享时,SDK 便会抛出此事件回调 + * @event TRTCCallback#onScreenCaptureStarted + */ + onScreenCaptureStarted() { } + /** + * 屏幕分享停止的事件回调
+ * 当您通过 stopScreenCapture 停止屏幕分享时,SDK 便会抛出此事件回调 + * @event TRTCCallback#onScreenCaptureStopped + * @param {Number} reason 停止原因,0:用户主动停止;1:屏幕窗口关闭导致停止;2:表示屏幕分享的显示屏状态变更(如接口被拔出、投影模式变更等) + */ + onScreenCaptureStopped(reason) { } + /** + * 屏幕分享停止的事件回调
+ * 当您通过 pauseScreenCapture 停止屏幕分享时,SDK 便会抛出此事件回调 + * @event TRTCCallback#onScreenCapturePaused + * @param {Number} reason 停止原因,0:用户主动停止;1:屏幕窗口关闭导致停止;2:表示屏幕分享的显示屏状态变更(如接口被拔出、投影模式变更等) + */ + onScreenCapturePaused(reason) { } + /** + * 屏幕分享恢复的事件回调
+ * 当您通过 resumeScreenCapture 恢复屏幕分享时,SDK 便会抛出此事件回调 + * @event TRTCCallback#onScreenCaptureResumed + */ + onScreenCaptureResumed() { } + /** + * 某远端用户发布/取消了辅路视频画面
+ * “辅路画面”一般被用于承载屏幕分享的画面。当您收到 onUserSubStreamAvailable(userId, true) 通知时,表示该路画面已经有可播放的视频帧到达。 此时,您需要调用 startRemoteView 接口订阅该用户的远程画面,订阅成功后,您会继续收到该用户的首帧画面渲染回调 onFirstVideoFrame(userId) + * + * **Note:** + * - 拉取 Web 端(用 [WebRTC](https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/index.html) 实现屏幕分享)的屏幕分享,收不到 onUserSubStreamAvailable 事件。因为 [WebRTC](https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/index.html) 推的屏幕分享也是主流 + * @param {String} userId 用户 ID + * @param {Boolean} available 是否可用,true 表示辅流可用 + * @event TRTCCallback#onUserSubStreamAvailable + */ + onUserSubStreamAvailable(userId, available) { } + /** + * 用户视频大小发生改变回调。
+ * 当您收到 onUserVideoSizeChanged(userId, streamtype, newWidth, newHeight) 通知时,表示该路画面大小发生了调整,调整的原因可能是该用户调用了 setVideoEncoderParam 或者 setSubStreamEncoderParam 重新设置了画面尺寸。 + * @param {String} userId 用户 ID + * @param {TRTCVideoStreamType} streamType 视频流类型,仅支持 TRTCVideoStreamTypeBig 和 TRTCVideoStreamTypeSub + * @param {Number} newWidth 视频流的宽度(像素) + * @param {Number} newHeight 视频流的高度(像素) + * @event TRTCCallback#onUserVideoSizeChanged + */ + onUserVideoSizeChanged(userId, streamType, newWidth, newHeight) { } + /** + * 背景音乐开始播放 + * @param {Number} id 播放的 id + * @param {Number} errCode 播放的状态码 + * @event TRTCCallback#onStart + */ + onStart(id, errCode) { } + /** + * 背景音乐的播放进度 + * @param {Number} id 播放的 id + * @param {Number} curPtsMS 当前播放的位置 + * @param {Number} durationMS 当前音频总时长 + * @event TRTCCallback#onPlayProgress + */ + onPlayProgress(id, curPtsMS, durationMS) { } + /** + * 背景音乐已经播放完毕 + * @param {Number} id 播放的 id + * @param {Number} errCode 播放结束的状态码 + * @event TRTCCallback#onComplete + */ + onComplete(id, errCode) { } +} diff --git a/TrtcCloud/permission.js b/TrtcCloud/permission.js new file mode 100644 index 0000000..2b45f1a --- /dev/null +++ b/TrtcCloud/permission.js @@ -0,0 +1,279 @@ +/** + * 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启 + */ +var isIos +// #ifdef APP-PLUS +isIos = (plus.os.name == "iOS"); +// #endif + +// 判断推送权限是否开启 +function judgeIosPermissionPush() { + var result = false; + var UIApplication = plus.ios.import("UIApplication"); + var app = UIApplication.sharedApplication(); + var enabledTypes = 0; + if (app.currentUserNotificationSettings) { + var settings = app.currentUserNotificationSettings(); + enabledTypes = settings.plusGetAttribute("types"); + console.log("enabledTypes1:" + enabledTypes); + if (enabledTypes == 0) { + console.log("推送权限没有开启"); + } else { + result = true; + console.log("已经开启推送功能!") + } + plus.ios.deleteObject(settings); + } else { + enabledTypes = app.enabledRemoteNotificationTypes(); + if (enabledTypes == 0) { + console.log("推送权限没有开启!"); + } else { + result = true; + console.log("已经开启推送功能!") + } + console.log("enabledTypes2:" + enabledTypes); + } + plus.ios.deleteObject(app); + plus.ios.deleteObject(UIApplication); + return result; +} + +// 判断定位权限是否开启 +function judgeIosPermissionLocation() { + var result = false; + var cllocationManger = plus.ios.import("CLLocationManager"); + var status = cllocationManger.authorizationStatus(); + result = (status != 2) + console.log("定位权限开启:" + result); + // 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation + /* var enable = cllocationManger.locationServicesEnabled(); + var status = cllocationManger.authorizationStatus(); + console.log("enable:" + enable); + console.log("status:" + status); + if (enable && status != 2) { + result = true; + console.log("手机定位服务已开启且已授予定位权限"); + } else { + console.log("手机系统的定位没有打开或未给予定位权限"); + } */ + plus.ios.deleteObject(cllocationManger); + return result; +} +// 判断麦克风权限是否开启 +function judgeIosPermissionRecord() { + var result = false; + var avaudiosession = plus.ios.import("AVAudioSession"); + var avaudio = avaudiosession.sharedInstance(); + var permissionStatus = avaudio.recordPermission(); + console.log("permissionStatus:" + permissionStatus); + if (permissionStatus == 1684369017 || permissionStatus == 1970168948) { + console.log("麦克风权限没有开启"); + } else { + result = true; + console.log("麦克风权限已经开启"); + } + plus.ios.deleteObject(avaudiosession); + return result; +} + +// 判断相机权限是否开启 +function judgeIosPermissionCamera() { + var result = false; + var AVCaptureDevice = plus.ios.import("AVCaptureDevice"); + var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide'); + console.log("authStatus:" + authStatus); + if (authStatus == 3) { + result = true; + console.log("相机权限已经开启"); + } else { + console.log("相机权限没有开启"); + } + plus.ios.deleteObject(AVCaptureDevice); + return result; +} + +// 判断相册权限是否开启 +function judgeIosPermissionPhotoLibrary() { + var result = false; + var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary"); + var authStatus = PHPhotoLibrary.authorizationStatus(); + console.log("authStatus:" + authStatus); + if (authStatus == 3) { + result = true; + console.log("相册权限已经开启"); + } else { + console.log("相册权限没有开启"); + } + plus.ios.deleteObject(PHPhotoLibrary); + return result; +} + +// 判断通讯录权限是否开启 +function judgeIosPermissionContact() { + var result = false; + var CNContactStore = plus.ios.import("CNContactStore"); + var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0); + if (cnAuthStatus == 3) { + result = true; + console.log("通讯录权限已经开启"); + } else { + console.log("通讯录权限没有开启"); + } + plus.ios.deleteObject(CNContactStore); + return result; +} + +// 判断日历权限是否开启 +function judgeIosPermissionCalendar() { + var result = false; + var EKEventStore = plus.ios.import("EKEventStore"); + var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0); + if (ekAuthStatus == 3) { + result = true; + console.log("日历权限已经开启"); + } else { + console.log("日历权限没有开启"); + } + plus.ios.deleteObject(EKEventStore); + return result; +} + +// 判断备忘录权限是否开启 +function judgeIosPermissionMemo() { + var result = false; + var EKEventStore = plus.ios.import("EKEventStore"); + var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1); + if (ekAuthStatus == 3) { + result = true; + console.log("备忘录权限已经开启"); + } else { + console.log("备忘录权限没有开启"); + } + plus.ios.deleteObject(EKEventStore); + return result; +} + +// Android权限查询 +function requestAndroidPermission(permissionID) { + return new Promise((resolve, reject) => { + plus.android.requestPermissions( + [permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装 + function(resultObj) { + var result = 0; + for (var i = 0; i < resultObj.granted.length; i++) { + var grantedPermission = resultObj.granted[i]; + console.log('已获取的权限:' + grantedPermission); + result = 1 + } + for (var i = 0; i < resultObj.deniedPresent.length; i++) { + var deniedPresentPermission = resultObj.deniedPresent[i]; + console.log('拒绝本次申请的权限:' + deniedPresentPermission); + result = 0 + } + for (var i = 0; i < resultObj.deniedAlways.length; i++) { + console.log(resultObj) + var deniedAlwaysPermission = resultObj.deniedAlways[i]; + console.log('永久拒绝申请的权限:' + deniedAlwaysPermission); + result = -1 + } + resolve(result); + // 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限 + // if (result != 1) { + // gotoAppPermissionSetting() + // } + }, + function(error) { + console.log('申请权限错误:' + error.code + " = " + error.message); + resolve({ + code: error.code, + message: error.message + }); + } + ); + }); +} + +// 使用一个方法,根据参数判断权限 +function judgeIosPermission(permissionID) { + if (permissionID == "location") { + return judgeIosPermissionLocation() + } else if (permissionID == "camera") { + return judgeIosPermissionCamera() + } else if (permissionID == "photoLibrary") { + return judgeIosPermissionPhotoLibrary() + } else if (permissionID == "record") { + return judgeIosPermissionRecord() + } else if (permissionID == "push") { + return judgeIosPermissionPush() + } else if (permissionID == "contact") { + return judgeIosPermissionContact() + } else if (permissionID == "calendar") { + return judgeIosPermissionCalendar() + } else if (permissionID == "memo") { + return judgeIosPermissionMemo() + } + return false; +} + +// 跳转到**应用**的权限页面 +function gotoAppPermissionSetting() { + if (isIos) { + var UIApplication = plus.ios.import("UIApplication"); + var application2 = UIApplication.sharedApplication(); + var NSURL2 = plus.ios.import("NSURL"); + // var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES"); + var setting2 = NSURL2.URLWithString("app-settings:"); + application2.openURL(setting2); + + plus.ios.deleteObject(setting2); + plus.ios.deleteObject(NSURL2); + plus.ios.deleteObject(application2); + } else { + // console.log(plus.device.vendor); + var Intent = plus.android.importClass("android.content.Intent"); + var Settings = plus.android.importClass("android.provider.Settings"); + var Uri = plus.android.importClass("android.net.Uri"); + var mainActivity = plus.android.runtimeMainActivity(); + var intent = new Intent(); + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + var uri = Uri.fromParts("package", mainActivity.getPackageName(), null); + intent.setData(uri); + mainActivity.startActivity(intent); + } +} + +// 检查系统的设备服务是否开启 +// var checkSystemEnableLocation = async function () { +function checkSystemEnableLocation() { + if (isIos) { + var result = false; + var cllocationManger = plus.ios.import("CLLocationManager"); + var result = cllocationManger.locationServicesEnabled(); + console.log("系统定位开启:" + result); + plus.ios.deleteObject(cllocationManger); + return result; + } else { + var context = plus.android.importClass("android.content.Context"); + var locationManager = plus.android.importClass("android.location.LocationManager"); + var main = plus.android.runtimeMainActivity(); + var mainSvr = main.getSystemService(context.LOCATION_SERVICE); + var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER); + console.log("系统定位开启:" + result); + return result + } +} + +// module.exports = { +// judgeIosPermission: judgeIosPermission, +// requestAndroidPermission: requestAndroidPermission, +// checkSystemEnableLocation: checkSystemEnableLocation, +// gotoAppPermissionSetting: gotoAppPermissionSetting +// } + +// HBuilder 选择 vue3 时, 上面的打包无法通过 import 进行引入 +export default { + judgeIosPermission: judgeIosPermission, + requestAndroidPermission: requestAndroidPermission, + checkSystemEnableLocation: checkSystemEnableLocation, + gotoAppPermissionSetting: gotoAppPermissionSetting +}; \ No newline at end of file diff --git a/TrtcCloud/view/TrtcLocalView.nvue b/TrtcCloud/view/TrtcLocalView.nvue new file mode 100644 index 0000000..72711d5 --- /dev/null +++ b/TrtcCloud/view/TrtcLocalView.nvue @@ -0,0 +1,19 @@ + + + + + diff --git a/TrtcCloud/view/TrtcRemoteView.nvue b/TrtcCloud/view/TrtcRemoteView.nvue new file mode 100644 index 0000000..e9b3fc9 --- /dev/null +++ b/TrtcCloud/view/TrtcRemoteView.nvue @@ -0,0 +1,23 @@ + + + + + diff --git a/androidPrivacy.json b/androidPrivacy.json new file mode 100644 index 0000000..12df862 --- /dev/null +++ b/androidPrivacy.json @@ -0,0 +1,3 @@ +{ + "prompt": "template" +} diff --git a/manifest.json b/manifest.json index e022a92..3114413 100644 --- a/manifest.json +++ b/manifest.json @@ -2,8 +2,8 @@ "name" : "xinelu-doctor-app", "appid" : "__UNI__9BA7A08", "description" : "", - "versionName" : "1.0.0", - "versionCode" : "100", + "versionName" : "1.0.3", + "versionCode" : 103, "transformPx" : false, /* 5+App特有相关 */ "app-plus" : { @@ -17,26 +17,36 @@ "delay" : 0 }, /* 模块配置 */ - "modules" : {}, + "modules" : { + "Camera" : {} + }, /* 应用发布信息 */ "distribute" : { /* android打包配置 */ "android" : { "permissions" : [ - "", - "", - "", - "", - "", + "", "", "", + "", "", - "", - "", + "", "", - "", "", - "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", "" ] }, @@ -47,6 +57,25 @@ /* SDK配置 */ "sdkConfigs" : { "ad" : {} + }, + "splashscreen" : { + "useOriginalMsgbox" : true + } + }, + "nativePlugins" : { + "TRTCCloudUniPlugin-TRTCCloudImpl" : { + "__plugin_info__" : { + "name" : "【官方】腾讯云实时音视频SDK", + "description" : "uni-app TRTC SDK 是腾讯云实时音视频通讯解决方案在 uni-app 上的 SDK,提供实时音视频服务", + "platforms" : "Android,iOS", + "url" : "https://ext.dcloud.net.cn/plugin?id=7774", + "android_package_name" : "uni.UNI9BA7A08", + "ios_bundle_id" : "", + "isCloud" : true, + "bought" : 1, + "pid" : "7774", + "parameters" : {} + } } } }, diff --git a/pages.json b/pages.json index 8e496d5..dde3392 100644 --- a/pages.json +++ b/pages.json @@ -67,11 +67,17 @@ } }, { - "path" : "pages/Industrialbutler/Industrialbutler", - "style" : - { - "navigationBarTitleText" : "视频通话", - "enablePullDownRefresh" : false + "path": "pages/Industrialbutler/Industrialbutler", + "style": { + "navigationBarTitleText": "视频通话", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/Industrialbutler/video", + "style": { + "navigationBarTitleText": "视频通话", + "enablePullDownRefresh": false } } ], diff --git a/pages/Industrialbutler/Industrialbutler.vue b/pages/Industrialbutler/Industrialbutler.vue index e501cd1..3abd435 100644 --- a/pages/Industrialbutler/Industrialbutler.vue +++ b/pages/Industrialbutler/Industrialbutler.vue @@ -1,6 +1,9 @@ @@ -21,10 +24,10 @@ return { src: '', datalist: '', - userSig: '', //获取userSig - roomId: '', //获取roomId userId: '', userName: '', //医生Name + roomId: '', + userSig: '', }; }, onLoad(options) { @@ -34,31 +37,37 @@ this.userName = res.data.personName this.getUserSig() }) - - }, - onShow() { - }, + onShow() {}, methods: { + govideo() { + uni.navigateTo({ + url: `./video?roomId=${this.roomId}&userId=${this.userId}&userName=${this.userName}&userSig=${this.userSig}` + }) + }, getUserSig() { // 获取userSig getUserSig(this.userId).then(res => { this.userSig = res.data // 获取roomId consultation(this.datalist.goodsOrderId).then(resp => { + this.roomId = resp.msg if (resp.code == 200) { - this.roomId = resp.msg - this.src = - `https://msg.xinyilu.cn​​​​​?userId=${this.userId}&userName=${this.userName}&userSig=${this.userSig}&roomId=${this.roomId}` + var urlStr = encodeURI( + `https://msg.xinyilu.cn​​​​​?userId=${this.userId}&userName=${this.userName}&userSig=${res.data}&roomId=${resp.msg}` + ) + // plus.runtime.openURL(urlStr, function(res) { + // console.log(res); + // }); + // this.src = + // `https://msg.xinyilu.cn​​​​​?userId=${this.userId}&userName=${this.userName}&userSig=${res.data}&roomId=${resp.msg}` } else if (resp.code == 500) { this.$refs.uToast.show({ title: resp.msg, type: 'error', duration: '1500' }) - } - console.log(this.src, '99') }) }) }, diff --git a/pages/Industrialbutler/video.nvue b/pages/Industrialbutler/video.nvue new file mode 100644 index 0000000..b7aeb7d --- /dev/null +++ b/pages/Industrialbutler/video.nvue @@ -0,0 +1,332 @@ + + + + \ No newline at end of file diff --git a/pages/homepage/homepage.vue b/pages/homepage/homepage.vue index c88e7dc..a309e1a 100644 --- a/pages/homepage/homepage.vue +++ b/pages/homepage/homepage.vue @@ -245,11 +245,9 @@ }, // 视频通话 govideo(item) { - console.log(item) uni.navigateTo({ url: `/pages/Industrialbutler/Industrialbutler?item=${JSON.stringify(item)}` }) - }, info() { this.query.pageNum = 1 @@ -260,10 +258,10 @@ this.missionlist = res.rows this.missiontotal = res.total }) - consultationInfolist(this.formdata).then(res => { - this.listinfo = res.rows - this.listtotal = res.rows - }) + // consultationInfolist(this.formdata).then(res => { + // this.listinfo = res.rows + // this.listtotal = res.rows + // }) }, tabschange(index) { this.tabscurrent = index; diff --git a/pages/login/login.vue b/pages/login/login.vue index fbc3c71..dc1d9dc 100644 --- a/pages/login/login.vue +++ b/pages/login/login.vue @@ -24,7 +24,6 @@ 登录 - @@ -39,11 +38,10 @@ data() { return { title: 'Hello', - personAccount: '', - personPassword: '', + personAccount: 'wangxiaoyan', + personPassword: 'Ww851108.', form: { name: '', - } } }, diff --git a/static/leave.png b/static/leave.png new file mode 100644 index 0000000..5ecea5f Binary files /dev/null and b/static/leave.png differ diff --git a/utils/utils.js b/utils/utils.js new file mode 100644 index 0000000..3bc184a --- /dev/null +++ b/utils/utils.js @@ -0,0 +1,49 @@ +/* + * @Description: 通用函数 + * @Date: 2022-03-10 15:17:05 + * @LastEditTime: 2022-03-29 15:20:26 + */ + +/** + * 从 window.location.href 中获取指定key的value + * @param {*} key 要获取的 key + * @returns window.location.href 中指定key对应的value + * @example + * const value = getUrlParam(key); + */ +export function getUrlParam(key) { + const url = decodeURI(window.location.href.replace(/^[^?]*\?/, '')); + const regexp = new RegExp(`(^|&)${key}=([^&#]*)(&|$|)`, 'i'); + const paramMatch = url.match(regexp); + + return paramMatch ? paramMatch[2] : null; +} + +export function clearUrlParam() { + location.href = location.href.slice(0, location.href.indexOf('?') > 0 ? location.href.indexOf('?') : location.href.length); +} + +export function isUndefined(value) { + return value === 'undefined'; +} + +/** + * 获取语言 + * @returns language + */ +export function getLanguage() { + let language = localStorage.getItem('trtc-quick-vue2-language') || getUrlParam('lang') || navigator.language || 'zh'; + language = language.replace(/_/, '-').toLowerCase(); + + if (language === 'zh-cn' || language === 'zh') { + language = 'zh'; + } else if (language === 'en' || language === 'en-us' || language === 'en-GB') { + language = 'en'; + } + return language; +} + +/** + * 当前浏览器是否为移动端浏览器 + */ +export const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);