Extends
Methods
initialize() → {Promise}
初始化本地音视频流对象
Note
- 该接口不支持在 http 协议下使用,请使用 https 协议部署您的网站。Privacy and security
错误信息:
错误名 | 描述 | 处理建议 |
---|---|---|
NotFoundError | 找不到满足请求参数的媒体类型(包括:音频、视频、屏幕分享)。例如:PC 没有摄像头,但是请求浏览器获取视频流,则会报此错误。 | 建议在通话开始前引导用户检查通话所需的摄像头或麦克风等外设,若没有摄像头且需要进行语音通话,可在 TRTC.createStream({ audio: true, video: false }) 指明仅采集麦克风。 |
NotAllowedError | 用户拒绝了当前的浏览器实例的访问音频、视频、屏幕分享请求。 | 提示用户不授权摄像头/麦克风访问无法进行音视频通话 |
NotReadableError | 尽管用户已经授权使用相应的设备,但是由于操作系统上某个硬件、浏览器或者网页层面发生的错误导致设备无法被访问。 | 根据浏览器的报错信息处理,并提示用户: “暂时无法访问摄像头/麦克风,请确保当前没有其他应用请求访问摄像头/麦克风,并重试” |
OverconstrainedError | cameraId/microphoneId 参数的值无效 | 确保 cameraId/microphoneId 传值正确且有效 |
AbortError | 由于某些未知原因导致设备无法被使用 |
Example
// 例如:处理 NotReadableError 错误
localStream.initialize().then(() => {
// 本地流初始化成功,发布本地流
client.publish(localStream).then(() => {
// 本地流发布成功
})
}).catch((error) => {
// 本地流初始化失败
switch (error.name) {
case 'NotReadableError':
// 提示用户:暂时无法访问摄像头/麦克风,请确保当前没有其他应用请求访问摄像头/麦克风,并重试。
break;
default:
console.error(error);
break;
}
})
Throws:
Returns:
- Type
- Promise
(async) setAudioProfile(profile)
设置音频 Profile
- v4.15.14+ 版本支持动态调用,在其之前版本需要在调用 initialize() 之前调用。
Example
localStream.setAudioProfile('high');
localStream.initialize().then(() => {
// localStream was initialized success
});
Parameters:
Name | Type | Description | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
profile |
string |
音频 Profile
|
(async) setVideoProfile(profile) → {Promise}
设置视频 Profile
Note
- v4.8.4 及其之后版本,该方法支持动态调用
- v4.8.4 之前版本,该方法需要在 initialize() 之前调用。
- 动态调用支持 Chrome 68+, Safari 12.1+, Firefox 64+, Edge 80+
- 请勿在 client.publish 接口未调用结束(Promise 处于 pending 状态)时调用该接口,否则设置可能会不生效。
- 对于自定义采集的流(使用 videoSource 创建的 Stream),该接口只能设置 bitrate,无法设置分辨率及帧率,需由业务侧自行控制。
- 动态调用时,若设置了摄像头不支持的 profile,浏览器有可能会停止采集并抛出错误。
建议在用户进房前,检测当前摄像头支持的分辨率,避免传入摄像头不支持的 profile。 - 自 2023 年 4 月 1 日起,使用 2k 4k 的分辨率进行推流需开通 TRTC 包月套餐 尊享版及更高版本。
Examples
// 使用预定义Profile设置
localStream.setVideoProfile('480p');
localStream.initialize().then(() => {
// local stream was initialized successfully.
});
// 使用自定义视频Profile设置
localStream.setVideoProfile({
width: 360, // 视频宽度
height: 360, // 视频高度
frameRate: 10, // 帧率
bitrate: 400 // 比特率 kbps
});
localStream.initialize().then(() => {
// local stream was initialized successfully.
});
// 动态设置 profile
localStream.setVideoProfile('480p');
await localStream.initialize();
await client.publish(localStream);
try {
await localStream.setVideoProfile('1080p');
} catch(error) {
if (error.name === 'OverconstrainedError') {
console.error('当前摄像头不支持该 profile');
// 设置失败,当前摄像头已停止采集,需要恢复采集
const stream = TRTC.createStream({ video: true, audio: false });
await stream.initialize();
localStream.replaceTrack(stream.getVideoTrack());
} else {
console.error('当前浏览器不支持动态调用该接口');
}
}
// 推流后更新码率
client.publish(localStream).then(() => {
localStream.setVideoProfile({ bitrate: 1500 });
})
// 获取实际采集的分辨率和帧率
const videoTrack = localStream.getVideoTrack();
if (videoTrack) {
const settings = videoTrack.getSettings();
console.log(`分辨率:${settings.width} * ${settings.height}, 帧率:${settings.frameRate}`)
}
// 获取实际推流的视频码率参考:https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/Client.html#getLocalVideoStats
Parameters:
Name | Type | Description | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
profile |
string | object |
视频 Profile
|
Returns:
- Type
- Promise
setScreenProfile(profile)
设置屏幕分享 Profile
该方法需要在调用 initialize() 之前调用。
Example
// 指定 Profile
localStream.setScreenProfile('1080p');
localStream.initialize().then(() => {
// local stream was initialized successfully
});
// 指定自定义分辨率、帧率和码率
localStream.setScreenProfile({ width: 1920, height: 1080, frameRate: 5, bitrate: 1600 });
localStream.initialize().then(() => {
// local stream was initialized successfully
});
Parameters:
Name | Type | Description | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
profile |
string |
screen profile
|
setVideoContentHint(hint)
设置视频内容提示,用于提升在不同内容场景下的视频编码质量。
该方法需要在调用 initialize() 成功之后调用。
如果不调用该方法,浏览器会自动评估视频内容,并选择合适的提示配置进行编码。
Example
const localStream = TRTC.createStream({ userId, audio: false, screen: true });
localStream.initialize().then(() => {
// 如果屏幕分享内容包含图片、文本,使用 'detail' 提示
localStream.setVideoContentHint('detail');
// 如果屏幕分享内容只包含大量文本,使用 'text' 提示
// localStream.setVideoContentHint('text');
client.publish(localStream);
});
Parameters:
Name | Type | Description |
---|---|---|
hint |
string |
内容提示,参考 MediaStreamTrack.contentHint
|
(async) switchDevice(type, deviceId) → {Promise}
切换媒体输入设备
调用该方法可以更换本地流的媒体输入设备:
- 音频输入设备,例如更换本地流(v4.11.9+ 支持设置了
audio:true
的屏幕分享流)的麦克风。 - 视频输入设备,例如更换本地流的摄像头。
Note:
- 该方法仅适用于采集了摄像头和麦克风的本地流,以及采集了麦克风的本地屏幕分享流。即:自定义采集流不支持调用该接口,开启系统音频采集的屏幕分享流不支持调用该接口。
- 若该本地流已经被发布,该方法会自动更新发往远端的音视频流,此时,远端会收到
Client.on('stream-updated')
事件通知。 - 支持 Chrome 65+、Safari 11+、Firefox 56+、Edge 80+ 浏览器。
- 请勿在 publish 接口调用完成前,调用该接口。否则可能导致接口调用异常。
- 在部分具有多后摄的华为设备中,调用
localStream.switchDevice('video', 'environment')
切换后摄时, 浏览器会默认切换到的第一个后摄。但是第一个后摄可能不是主摄像头,可能是长焦、广角、微距镜头。
目前暂无办法准确判断镜头是否为主摄,针对该类问题,可以让用户根据 TRTC.getCameras() 返回的摄像头列表, 手动选择设备进行切换。
Example
// 切换本地流的摄像头
const localStream = TRTC.createStream({ userId, audio: true, video: true });
await localStream.initialize()
await client.publish(localStream);
const cameras = await TRTC.getCameras();
await localStream.switchDevice('video', cameras[0].deviceId)
//
// 切换本地屏幕分享流的麦克风,前提需要初始属性 audio 为 true,v4.11.9+支持
const localStream = TRTC.createStream({ userId, audio: true, screen: true });
await localStream.initialize()
client.publish(localStream);
const microphones = await TRTC.getMicrophones();
await localStream.switchDevice('video', microphones[0].deviceId)
Parameters:
Name | Type | Description |
---|---|---|
type |
string |
媒体类型
|
deviceId |
string |
设备标识
|
Returns:
- Type
- Promise
(async) addTrack(track)
添加音频或视频轨道
调用该方法将音频或视频轨道添加到本地流,若该本地流已经被发布,则会自动更新发往远端的音视频流,此时远端会收到 Client.on('stream-updated')
事件通知。
新的音视频轨道可以通过 TRTC.createStream()/getAudioTrack()|getVideoTrack() 获取,
或者直接通过 getUserMedia()、captureStream() 获取。
Note
- 一个 Stream 对象中最多只能同时包含一路音频轨道和一路视频轨道。如果你想要更换同类型的轨道,请使用 replaceTrack()。
- 在增加视频轨道时,要求视频分辨率跟 setVideoProfile() 设置保持一致,否则会抛出异常。
- 请勿在 removeTrack 或 publish 接口调用完成前,调用该接口。否则可能导致接口调用异常。
Example
const localStream = TRTC.createStream({ userId, audio: true, video: false });
localStream.initialize().then(() => {
// 分布本地流(只有从麦克风采集的音频流)
client.publish(localStream);
});
// ...
// 开启视频通话
const videoStream = TRTC.createStream({ userId, audio: false, video: true });
videoStream.initialize().then(() => {
const videoTrack = videoStream.getVideoTrack();
// 将从摄像头采集的视频轨道插入当前已发布的本地流对象LocalStream
localStream.addTrack(videoTrack).then(() => {
// 视频通话开启成功,远端流将会收到‘stream-updated’通知
});
});
//
Parameters:
Name | Type | Description |
---|---|---|
track |
MediaStreamTrack |
音频或视频轨道 |
Throws:
RtcError
(async) removeTrack(track)
移除视频轨道
调用该方法会移除本地流中的视频轨道,若本地流已经被发布,则会自动更新发往远端的视频流,此时远端会收到 Client.on('stream-updated')
事件通知。
NOTE
- 一个已经发布的Stream对象中至少要有一个媒体轨道,如果你想完全删除本地流中的音视频轨道,请直接通过 unpublish() 取消发布,
然后再通过 close() 关闭本地流。
- 请勿在 addTrack 或 publish 接口调用完成前,调用该接口。否则可能导致接口调用异常。
- 视频轨道移除后,hasVideo() 将返回
false
。 - v4.15.0+ 支持 remove audioTrack,也支持同时 remove videoTrack 和 audioTrack。支持的浏览器版本:Chrome 69+, Safari 11+, Firefox 59+, Edge 79+。
Example
// 关闭视频通话示例,对应addTrack接口的开启视频通话示例
const videoTrack = localStream.getVideoTrack();
if (videoTrack) {
localStream.removeTrack(videoTrack).then(() => {
// 关闭视频通话成功,停止videoTrack并释放摄像头资源
videoTrack.stop();
});
}
Parameters:
Name | Type | Description |
---|---|---|
track |
MediaStreamTrack |
视频轨道,track 通过 getVideoTrack() 获取。 |
Throws:
RtcError
(async) replaceTrack(track)
更换音频或视频轨道
调用该方法更换本地流中的同类型轨道,若本地流已经被发布,该方法会自动更新发往远端的音视频流,此时远端会收到 Client.on('stream-updated')
事件通知。
新的音视频轨道可以通过 TRTC.createStream()/getAudioTrack()|getVideoTrack() 获取,
或者直接通过 getUserMedia()、captureStream() 获取。
Note:
- 如果需要更换媒体输入设备,推荐使用 switchDevice()。
- 在更换视频轨道时,要求视频分辨率跟 setVideoProfile() 设置保持一致,否则会抛出异常。
- 支持 Chrome 65+、Safari 11+、Firefox 56+、Edge 80+ 浏览器。
- 请勿在 publish 接口调用完成前,调用该接口。否则可能导致接口调用异常。
Parameters:
Name | Type | Description |
---|---|---|
track |
MediaStreamTrack |
音频或视频轨道 |
Throws:
RtcError
setAudioCaptureVolume(volumeopt) → {Boolean}
设置麦克风采集音量
支持 Chrome 65+、Safari 11+、Firefox 56+、Edge 80+ 浏览器。
- Since:
-
- v4.14.0
Example
// 采集声音减少一半
localStream.setAudioCaptureVolume(50);
// 采集声音设置为 0,相当于静音。
localStream.setAudioCaptureVolume(0);
// 采集声音增大50%。
localStream.setAudioCaptureVolume(150);
const result = localStream.setAudioCaptureVolume(50);
if (!result && localStream.hasAudio()) {
// 当前浏览器不支持设置麦克风采集音量
}
Parameters:
Name | Type | Attributes | Default | Description |
---|---|---|---|---|
volume |
Number |
<optional> |
100
|
建议取值 0 - 100。默认采集音量为100,设置大于 100 可增大采集音量,但有爆音风险,请谨慎使用。 |
Returns:
true 为设置成功,false 为设置失败。
可能原因:
- LocalStream 没有采集麦克风
- 参数 volume 小于0
- 当前浏览器不支持调用该接口
- Type
- Boolean
(async) play(elementId, optionsopt) → {Promise}
播放该音视频流
该方法会自动创建 <audio> 和 <video> 标签并在指定的标签上播放音频和视频,同时该标签会被添加到页面中名为 elementId
的 div 容器。
换句说,Stream 内部会自动创建相应的音频播放器和视频播放器来播放相应的音频和视频。
NOTE
- Inherited From:
Example
// v4.8.4 以下版本, 请使用以下方式捕捉并处理 0x4043 错误
stream.play('remote').then(() => {
// autoplay success
}).catch((error) => {
const errorCode = error.getCode();
if (errorCode === 0x4043) {
// PLAY_NOT_ALLOWED,引导用户手势操作并调用 stream.resume 恢复音视频播放
// stream.resume()
}
});
// v4.8.4 及其以上版本, 强烈建议使用 stream 监听 error 的方式捕捉并处理 0x4043 错误
stream.play('remote').catch(error => {});
stream.on('error', error => {
const errorCode = error.getCode();
if (errorCode === 0x4043) {
// PLAY_NOT_ALLOWED,引导用户手势操作并调用 stream.resume 恢复音视频播放
// stream.resume()
}
})
Parameters:
Name | Type | Attributes | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
elementId |
string | HTMLDivElement |
在 DOM 中的某个 <div> 标签 ID 或者 HTMLDivElement 对象,该方法会在指定的 elementId 元素中创建音视频标签来播放音视频流。
|
|||||||||||||
options |
object |
<optional> |
播放选项 Properties
|
Throws:
Returns:
- Type
- Promise
stop()
停止播放音视频流
该方法还会将由 play() 创建的音视频标签从 HTML 页面中删除。
- Inherited From:
(async) resume() → {Promise}
恢复播放音视频
NOTE
- Inherited From:
Example
stream.on('player-state-changed', event => {
if (event.state === 'PAUSED') {
// resume audio/video playback
stream.resume();
}
});
Throws:
Returns:
- Type
- Promise
close()
关闭音视频流
使用场景:
- 本地流
LocalStream
调用该方法会停止播放及停止采集。因此若您想停止采集摄像头及麦克风,可以调用该方法。 - 远端流
RemoteStream
一般无需调用该方法。该方法会停止播放并关闭音视频 track。若您不想继续订阅远端流,请使用 Client.unsubscribe。
- Overrides:
muteAudio() → {boolean}
禁用音频轨道,且保留音频轨道,通常用于本地流临时静音。
- 本地流
LocalStream
调用该方法会停止发送音频,远端会触发Client.on('mute-audio')
事件。 - 远端流
RemoteStream
调用该方法会停止解码播放音频,但是仍然接收音频数据,若您不想接收视频数据,请使用 Client.unsubscribe 取消订阅,或者 Client.subscribe 只订阅视频。
- Overrides:
Returns:
- true 禁用音频轨道成功。
- false 禁用音频轨道失败,因为没有音频轨道。
- Type
- boolean
muteVideo() → {boolean}
禁用视频轨道,且保留视频轨道,通常用于本地流临时禁画。
- 本地流
LocalStream
调用该方法会停止发送视频,远端会触发Client.on('mute-video')
事件。
如果视频是从摄像头采集,此时摄像头灯仍然是亮着的。若想完全禁用视频轨道(即关闭摄像头),
可以使用 removeTrack() 删除视频轨道然后调用 MediaStreamTrack.stop() 关闭视频轨道(关闭摄像头)。 - 远端流
RemoteStream
调用该方法会停止解码播放视频,但是仍然接收视频数据,若您不想接收视频数据,请使用 Client.unsubscribe 取消订阅,或者 Client.subscribe 只订阅音频。
- Overrides:
Returns:
- true 禁用视频轨道成功
- false 禁用视频轨道失败,因为没有视频轨道。
- Type
- boolean
unmuteAudio() → {boolean}
启用音频轨道
- 存在音频轨道的情况下,本地流
LocalStream
在调用 muteAudio() 后,用该方法重新启用音频,这时远端会触发Client.on('unmute-audio')
事件。 - 远端流
RemoteStream
在调用 muteAudio() 后,用该方法恢复解码播放音频。
- Overrides:
Returns:
- true 启用音频轨道成功。
- false 没有音频轨道,启用失败。
- Type
- boolean
unmuteVideo() → {boolean}
启用视频轨道
- 存在视频轨道的情况下,本地流
LocalStream
在调用 muteVideo() 后,用该方法重新启用视频轨道,这时远端会触发Client.on('unmute-video')
事件。 - 远端流
RemoteStream
在调用 muteVideo() 后,用该方法恢复解码播放视频。
- Overrides:
Returns:
- true 启用视频轨道成功。
- false 没有视频轨道,启用失败。
- Type
- boolean
getId() → {string}
获取 Stream 唯一标识ID
- Inherited From:
Returns:
Id 流唯一标识
- Type
- string
getUserId() → {string}
获取该流所属的用户ID
- Inherited From:
Returns:
userId 用户ID
- Type
- string
(async) setAudioOutput(deviceId)
设置声音输出设备
- 移动端不支持设置扬声器。
- Inherited From:
Parameters:
Name | Type | Description |
---|---|---|
deviceId |
string |
设备标识,通过 TRTC.getSpeakers() 获取。 |
getAudioLevel() → {number}
获取当前音量大小
只有当本地流或远端流中有音频数据才有效,在获取音量前需要先 播放 该音视频流。
- Inherited From:
Example
setInterval(() => {
const level = stream.getAudioLevel();
if (level >= 0.1) {
console.log(`user ${stream.getUserId()} is speaking`);
}
}, 200);
Returns:
audioLevel 音量大小
- 返回值在(0.0, 1.0)之间,通常认为值大于0.1为用户正在说话。
- Type
- number
hasAudio() → {boolean}
是否包含音频轨道
- 如果需要获取
Stream mute
状态,需要监听Client.on('mute-audio')
事件做进一步处理。
- Inherited From:
Returns:
- Type
- boolean
hasVideo() → {boolean}
是否包含视频轨道
- 如果需要获取
Stream mute
状态,需要监听Client.on('mute-video')
事件做进一步处理。
- Inherited From:
Returns:
- Type
- boolean
getAudioTrack() → (nullable) {MediaStreamTrack}
获取音频轨道
- Inherited From:
Returns:
音频轨道
- Type
- MediaStreamTrack
getVideoTrack() → (nullable) {MediaStreamTrack}
获取视频轨道
- Inherited From:
Returns:
视频轨道
- Type
- MediaStreamTrack
getVideoFrame() → (nullable) {String}
获取当前视频帧
NOTE
- 该方法需要在 play() 后调用,并且 Stream 中有视频流才有效
- Inherited From:
Example
// 截取当前视频帧
const frame = stream.getVideoFrame();
if (frame) {
const img = document.createElement('img');
img.src = frame;
}
Returns:
'image/png' 类型的 dataURL
- Type
- String
on(eventName, handler, context)
监听 Stream 事件
详细事件列表请参见:StreamEvent
- Inherited From:
Example
function onPlayerStateChange(event) {
console.log(`${event.type} player is ${event.state}`);
}
stream.on('player-state-changed', onPlayerStateChange);
Parameters:
Name | Type | Description |
---|---|---|
eventName |
string |
事件名称 |
handler |
function |
事件处理方法 |
context |
object |
上下文对象 |
off(eventName, handler, context)
取消监听 Stream 事件
- Inherited From:
Example
function onPlayerStateChange(event) {
console.log(`${event.type} player is ${event.state}`);
}
stream.on('player-state-changed', onPlayerStateChange);
stream.off('player-state-changed', onPlayerStateChange);
Parameters:
Name | Type | Description |
---|---|---|
eventName |
string |
事件名称,传入通配符 '*' 会解除所有事件绑定。 |
handler |
function |
事件处理方法 |
context |
object |
上下文对象 |