LocalStream

LocalStream

LocalStream 本地音视频流,通过 createStream() 创建。

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 由于某些未知原因导致设备无法被使用

参考:getUserMedia 异常getDisplayMedia 异常

Example
// 例如:处理 NotReadableError 错误
localStream.initialize().then(() => {
  // 本地流初始化成功,发布本地流
  client.publish(localStream).then(() => {
  // 本地流发布成功
  })
}).catch((error) => {
  // 本地流初始化失败
   switch (error.name) {
     case 'NotReadableError':
       // 提示用户:暂时无法访问摄像头/麦克风,请确保当前没有其他应用请求访问摄像头/麦克风,并重试。
       break;
     default:
       console.error(error);
       break;
   }
})
Returns:
Type
Promise

setAudioProfile(profile)

设置音频 Profile
该方法需要在调用 initialize() 之前调用。

Example
localStream.setAudioProfile('high');
localStream.initialize().then(() => {
  // localStream was initialized success
});
Parameters:
Name Type Description
profile string

音频 Profile

音频 Profile 采样率 声道 码率 (kbps)
standard 48000 单声道 40
high 48000 单声道 128

默认使用 standard

(async) setVideoProfile(profile) → {Promise}

设置视频 Profile

Note

  • v4.8.4 及其之后版本,该方法支持动态调用
  • v4.8.4 之前版本,该方法需要在 initialize() 之前调用。
  • 动态调用支持 Chrome 68+, Safari 12.1+, Firefox 64+, Edge 80+
  • 请避免在推流过程中调用该方法
  • 自定义采集的流(使用 videoSource 创建的 Stream)不支持动态调用,仅支持摄像头采集的流
  • 动态调用时,若设置了摄像头不支持的 profile,浏览器有可能会停止采集并抛出错误
    建议在用户进房前,检测当前摄像头支持的分辨率,避免传入摄像头不支持的 profile。
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

视频 Profile 分辨率(宽 x 高) 帧率(fps) 码率(kbps)
120p 160 x 120 15 200
180p 320 x 180 15 350
240p 320 x 240 15 400
360p 640 x 360 15 800
480p 640 x 480 15 900
720p 1280 x 720 15 1500
1080p 1920 x 1080 15 2000
1440p 2560 x 1440 30 4860
4K 3840 x 2160 30 9000
  • iOS Safari 不支持采集 1080p
  • Firefox 不支持自定义视频帧率(默认为 30fps)。
  • 由于设备和浏览器的限制,视频分辨率不一定能够完全匹配,在这种情况下,浏览器会自动调整分辨率使其接近 Profile 对应的分辨率。
  • 如果以上视频 Profile 不符合您的要求,您可以设置自定义 Profile。
  • 默认使用 480p
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

屏幕 Profile 分辨率(宽 x 高) 帧率(fps) 码率 (kbps)
480p 640 x 480 5 900
480p_2 640 x 480 30 1000
720p 1280 x 720 5 1200
720p_2 1280 x 720 30 3000
1080p 1920 x 1080 5 1600
1080p_2 1920 x 1080 30 4000
  • 屏幕分享默认使用 1080p
  • 若以上 Profile 不能满足您的业务需求,您也可以指定自定义的分辨率、帧率和码率。

setVideoContentHint(hint)

设置视频内容提示,主要用于提升在不同场景下的视频编码质量。
该方法需要在调用 initialize() 成功之后调用。

Example
const localStream = TRTC.createStream({ userId, audio: false, screen: true });
localStream.initialize().then(() => {
  // 若当前屏幕分享的主要内容是一般网页
  localStream.setVideoContentHint('detail');

  // 若当前屏幕分享的主要内容中含有大量的文字
  // localStream.setVideoContentHint('text');

  client.publish(localStream);
});
Parameters:
Name Type Description
hint string

内容提示,参考 MediaStreamTrack.contentHint

  • 'motion':本地流视频内容为从摄像头采集的内容、电影或者视频游戏等。
  • 'detail':本地视频内容为 ppt、带有文本内容、绘画或艺术线条的网页。一般屏幕分享默认使用这个提示。
  • 'text':本地视频内容主要是含有文本的 ppt 或网页等。

(async) switchDevice(type, deviceId) → {Promise}

切换媒体输入设备

调用该方法可更换本地流的媒体输入设备:

  • 音频输入设备,如麦克风。
  • 视频输入设备,如摄像头。

Note:

  • 该方法仅适用于从摄像头和麦克风采集音视频的本地流。即:屏幕分享及自定义采集流不支持调用该接口。
  • 若该本地流已经被发布,该方法会自动更新发往远端的音视频流,此时,远端会收到 Client.on('stream-updated') 事件通知。
  • 支持 Chrome 65+、Safari 11+、Firefox 56+、Edge 80+ 浏览器。
  • 请勿在 publish 接口调用完成前,调用该接口。否则可能导致接口调用异常。
Example
await client.publish(localStream);
const cameras = await TRTC.getCameras();
await localStream.switchDevice('video', cameras[0].deviceId)
Parameters:
Name Type Description
type string

媒体类型

  • 'audio' 音频
  • 'video' 视频
deviceId string

设备标识

  • 摄像头设备标识通过 getCameras() 获取。
    在移动设备上,可以通过设置 deviceId 为 'user' 和 'environment' 来切换前置和后置摄像头。
  • 麦克风设备标识通过 getMicrophones() 获取。
Returns:
Type
Promise

(async) addTrack(track)

添加音频或视频轨道

调用该方法将音频或视频轨道添加到本地流,若该本地流已经被发布,则会自动更新发往远端的音视频流,此时远端会收到 Client.on('stream-updated') 事件通知。

新的音视频轨道可以通过 createStream()/getAudioTrack()|getVideoTrack() 获取, 或者直接通过 getUserMedia()captureStream() 获取。

Note

  • 一个 Stream 对象中最多只能同时包含一路音频轨道和一路视频轨道。如果你想要更换同类型的轨道,请使用 replaceTrack()
  • 在增加视频轨道时,要求视频分辨率跟 setVideoProfile() 设置保持一致,否则会抛出异常。
  • 请勿在 removeTrackpublish 接口调用完成前,调用该接口。否则可能导致接口调用异常。
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') 事件通知。

请注意,一个已经发布的Stream对象中至少要有一个媒体轨道,如果你想完全删除本地流中的音视频轨道,请直接通过 unpublish() 取消发布, 然后再通过 close() 关闭本地流。
NOTE

  • 目前尚不支持移除音频轨道,若想禁用音频,可通过调用 muteAudio() 实现。
  • 请勿在 addTrackpublish 接口调用完成前,调用该接口。否则可能导致接口调用异常。
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') 事件通知。

新的音视频轨道可以通过 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

(async) play(elementId, optionsopt) → {Promise}

播放该音视频流
该方法会自动创建 <audio> 和 <video> 标签并在指定的标签上播放音频和视频,同时该标签会被添加到页面中名为 elementId 的 div 容器。
换句说,Stream 内部会自动创建相应的音频播放器和视频播放器来播放相应的音频和视频。

NOTE

  • 由于浏览器自动播放策略的影响,调用该接口可能会返回 PLAY_NOT_ALLOWED 错误, 此时需要引导用户通过手势操作调用 resume() 恢复音视频播放。
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

HTML <div> 标签 ID 或者 HTMLDivElement 对象,该方法内部自动创建的音视频标签将被添加到该容器中。

options object <optional>

播放选项

Properties
Name Type Description
objectFit string

视频画面显示模式,参考 CSS object-fit 属性

  • 'contain' 优先保证视频内容全部显示。视频尺寸等比缩放,直至视频窗口的一边与视窗边框对齐。如果视频尺寸与显示视窗尺寸不一致,在保持长宽比的前提下,将视频进行缩放后填满视窗,缩放后的视频四周会有一圈黑边。
  • 'cover' 优先保证视窗被填满。视频尺寸等比缩放,直至整个视窗被视频填满。如果视频长宽与显示窗口不同,则视频流会按照显示视窗的比例进行周边裁剪或图像拉伸后填满视窗。

    对于本地流,播放视频流默认使用 cover 模式,屏幕共享默认使用 contain 模式。
muted boolean

是否需要 mute 声音,对于本地流通常需要 mute 声音以防止播放从麦克风采集回来的声音。

Throws:
Returns:
Type
Promise

stop()

停止播放音视频流

该方法还会将由 play() 创建的音视频标签从 HTML 页面中删除。

Inherited From:

(async) resume() → {Promise}

恢复播放音视频
NOTE

  • 在某些版本浏览器上移动传入 play() 的 div 容器可能会导致音视频播放器进入 ‘PAUSED’ 状态,此时 需要调用该接口恢复播放。
  • 由于浏览器自动播放策略的限制,在 play() 返回 PLAY_NOT_ALLOWED 错误后需要引导用户通过手势 调用该接口恢复播放。
Inherited From:
Example
stream.on('player-state-changed', event => {
  if (event.state === 'PAUSED') {
    // resume audio/video playback
    stream.resume();
  }
});
Throws:
Returns:
Type
Promise

close()

关闭音视频流

对于本地流,该方法会关闭摄像头并释放摄像头和麦克风访问权限。

Overrides:

muteAudio() → {boolean}

禁用音频轨道

  • 对于本地流,调用该方法会停止发送音频,远端会触发 Client.on('mute-audio') 事件。
  • 对于远端流,调用该方法会停止播放音频,但是仍然接收音频数据。
Overrides:
Returns:
  • true 禁用音频轨道成功。
  • false 禁用音频轨道失败,因为没有音频轨道。
Type
boolean

muteVideo() → {boolean}

禁用视频轨道

  • 对于本地流,调用该方法会停止发送视频,远端会触发 Client.on('mute-video') 事件。
    如果视频是从摄像头采集,此时摄像头灯仍然是亮着的。若想完全禁用视频轨道(即关闭摄像头),
    可以使用 removeTrack() 删除视频轨道然后调用 MediaStreamTrack.stop() 关闭视频轨道(关闭摄像头)。
  • 对于远端流,调用该方法会停止播放视频,但是仍然接收视频数据.
Overrides:
Returns:
  • true 禁用视频轨道成功
  • false 禁用视频轨道失败,因为没有视频轨道。
Type
boolean

unmuteAudio() → {boolean}

启用音频轨道

对于本地流,调用该方法会触发远端 Client.on('unmute-audio') 事件。

音频轨道默认是开启的,若你调用 muteAudio() 后可用该方法重新启用音频。

Overrides:
Returns:
  • true 启用音频轨道成功。
  • false 没有音频轨道,启用失败。
Type
boolean

unmuteVideo() → {boolean}

启用视频轨道

对于本地流,调用该方法会触发远端 Client.on('unmute-video') 事件。

视频轨道默认是开启的,若你调用 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

设备标识,通过 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}

是否包含音频轨道

Inherited From:
Returns:
Type
boolean

hasVideo() → {boolean}

是否包含视频轨道

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

上下文对象