LocalStream

LocalStream

LocalStream,created by TRTC.createStream().

Extends

Methods

initialize() → {Promise}

Initialize local audio/video stream objects.

NOTE

  • This API cannot be used in HTTP. Please use HTTPS to deploy your website. For more information, please see Privacy and security.
    Error Info:
Error Message Description Solution
NotFoundError The media (audio, video, or screen sharing) specified by the request parameter are not found. This error occurs if, for example, the PC has no cameras but the browser is asked to obtain a video stream. Remind users to check peripherals such as cameras and mics before making a call. If a user does not have a camera and wants to make an audio call, use TRTC.createStream({ audio: true, video: false }) to make the SDK capture audio only.
NotAllowedError The user has rejected the current browser instance’s request to access the camera/mic or share screens. Remind the user that audio/video calls are not possible without camera/mic access.
NotReadableError The user has been granted access to the requested device, but the device is still inaccessible due to a hardware, browser, or web page error. Handle the error according to the error message returned and prompt the user: "The camera/mic cannot be accessed. Please make sure that no other applications are requesting access and try again."
OverConstrainedError The cameraId/microphoneId value is invalid. Make sure that the cameraId/microphoneId value passed in is valid.
AbortError The device cannot be accessed due to an unknown reason.

Reference: getUserMedia exception and getDisplayMedia exception

Example
// Handle the `NotReadableError` error
localStream.initialize().then(() => {
  // Publish the local stream after successful local stream initialization
  client.publish(localStream).then(() => {
  // Publishing the local stream is successful
  })
}).catch((error) => {
  // Failed to initialize local stream
   switch (error.name) {
     case 'NotReadableError':
       // Send this message to the user: "The camera/mic cannot be accessed. Please make sure that no other applications are requesting access and try again."
       break;
     default:
       console.error(error);
       break;
   }
})
Returns:
Type
Promise

setAudioProfile(profile)

Set audio profile
This API works only if it is called before initialize().

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

Audio Profile

Audio Profile Sample Rate Sound Channel Bitrate (Kbps)
standard 48000 Mono-channel 40
high 48000 Mono-channel 128
standard-stereo 48000 Dual-channel 64
high-stereo 48000 Dual-channel 192
The default audio profile is standard.

(async) setVideoProfile(profile) → {Promise}

Set video profile
NOTE

  • For v4.8.4 and later versions, this API supports dynamic calling.
  • For versions earlier than v4.8.4, this API works only if it is called before initialize().
  • Dynamic calling is supported in Chrome 68+, Safari 12.1+, Firefox 64+, and Edge 80+.
  • Do not call this API during a push.
  • For streams captured via custom capturing (streams created via videoSource), this API does not support dynamic calling. It supports dynamic calling only for streams captured via camera.
  • If a profile not supported by the current camera is configured for dynamic calling, the browser may stop capturing and throw an error. You are advised to check the resolution supported by the current camera before entering the room to avoid passing in a profile that is not supported by the camera.
  • From 1 April 2023, streaming at 2k 4k resolution requires TRTC Monthly Package Premium and higher.
Examples
// Use predefined profile settings
localStream.setVideoProfile('480p');
localStream.initialize().then(() => {
  // Local stream initialized successfully
});
// Use custom video profile settings
localStream.setVideoProfile({
  width: 360, // Video width
  height: 360, // Video height
  frameRate: 10, // Frame rate
  bitrate: 400 // Bitrate (Kbps)
});
localStream.initialize().then(() => {
  // Local stream initialized successfully
});
// Dynamically set a profile
localStream.setVideoProfile('480p');
await localStream.initialize();
await client.publish(localStream);
try {
   await localStream.setVideoProfile('1080p');
} catch(error) {
  if (error.name === 'OverconstrainedError') {
     console.error('The current camera does not support the profile');
     // Setting failed. Capturing via the current camera is stopped and needs to be resumed
     const stream = TRTC.createStream({ video: true, audio: false });
     await stream.initialize();
     localStream.replaceTrack(stream.getVideoTrack());
  } else {
     console.error('The current browser does not support dynamic calling of this API');
  }
}
// Update the bitrate after push
client.publish(localStream).then(() => {
   localStream.setVideoProfile({ bitrate: 1500 });
})
// Get the resolution and frame rate for actual capturing
const videoTrack = localStream.getVideoTrack();
if (videoTrack) {
   const settings = videoTrack.getSettings();
   console.log(`Resolution: ${settings.width} * ${settings.height}; frame rate: ${settings.frameRate}`)
}
// Get the video bitrate for actual push. Reference: https://web.sdk.qcloud.com/trtc/webrtc/doc/en/Client.html#getLocalVideoStats
Parameters:
Name Type Description
profile string | object

Video profile

Video Profile Resolution (W x H) Frame Rate (fps) Bitrate (Kbps) Note
120p 160 x 120 15 200
120p_2 160 x 120 15 100 4.12.7+ supports
180p 320 x 180 15 350
180p_2 320 x 180 15 150 4.12.7+ supports
240p 320 x 240 15 400
240p_2 320 x 240 15 200 4.12.7+ supports
360p 640 x 360 15 800
360p_2 640 x 360 15 400 4.12.7+ supports
480p 640 x 480 15 900
480p_2 640 x 480 15 500 4.12.7+ supports
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 does not support the 1080p profile.
  • Firefox does not support custom video frame rates and it supports only the frame rate of 30 fps by default.
  • The target resolution of a profile may be unattainable due to device and browser restrictions, in which case the browser will adjust the resolution to make it as close as possible to the target.
  • If the video profiles listed above do not meet your requirements, you can configure a custom profile.
  • The default profile:
    • 480p in versions before 4.12.7.
    • 480p_2 in versions after 4.12.7 (includes 4.12.7).
Returns:
Type
Promise

setScreenProfile(profile)

Set screen sharing profile

This API works only if it is called before initialize().

Example
// Specify a profile
localStream.setScreenProfile('1080p');
localStream.initialize().then(() => {
  // Local stream initialized successfully
});
// Specify a custom resolution, frame rate, and bitrate
localStream.setScreenProfile({ width: 1920, height: 1080, frameRate: 5, bitrate: 1600 });
localStream.initialize().then(() => {
  // Local stream initialized successfully
});
Parameters:
Name Type Description
profile string

Screen profile

Screen Profile Resolution (W x H) Frame Rate (fps) Bitrate (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
  • The screen sharing profile is 1080p by default.
  • If the profiles listed above do not meet your requirements, you can specify a custom resolution, frame rate, and bitrate.

setVideoContentHint(hint)

Set video content hint. This API is mainly used to improve video encoding quality in different scenarios.
This API works only if it is called after initialize().

Example
const localStream = TRTC.createStream({ userId, audio: false, screen: true });
localStream.initialize().then(() => {
  // If the main content for the current screen sharing is general web pages
  localStream.setVideoContentHint('detail');
  // If the main content for the current screen sharing contains a lot of text
  // localStream.setVideoContentHint('text');
  client.publish(localStream);
});
Parameters:
Name Type Description
hint string

Content hint. For more information, see MediaStreamTrack.contentHint.

  • 'motion': the local video is content, film, or video game captured from a camera.
  • 'detail': the local video is a PowerPoint file or a web page with text content, drawings, or artistic lines. This hint is used by default for screen sharing.
  • 'text': the local video is a PowerPoint file or web page with text content.

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

Switch the media input device.

You can call this API to change the media input device for local streams:

  • Audio input device, such as mic
  • Video input device, such as camera

NOTE

  • This API works for local audio/video streams captured from mics and cameras or streams captured through mics and screen sharing. It does not work for streams captured via screen sharing with system audio or custom capturing.
  • If local streams are published, this API, when called, will automatically update the audio/video streams sent to remote devices. In that case, the remote devices will receive the Client.on('stream-updated') event notification.
  • Supported browsers are Chrome 65+, Safari 11+, Firefox 56+, and Edge 80+.
  • Do not call this API before the publish API call is completed. Otherwise, an API call exception may occur.
  • For some Huawei devices with multiple rear cameras, when you call localStream.switchDevice('video', 'environment') to switch to the rear camera mode, the browser is switched to the first rear camera by default. However, the first camera may not be the main camera, and it might be a telephoto, wide-angle, or macro lens.

Currently, there is no way to accurately determine whether the lens is the main camera. To address this problem, you can call getCameras() to get the list of cameras and manually select the device to be switched to.

Example
await client.publish(localStream);
const cameras = await TRTC.getCameras();
await localStream.switchDevice('video', cameras[0].deviceId)
Parameters:
Name Type Description
type string

Media type

  • 'audio'
  • 'video'
deviceId string

Device ID

  • For a camera, you can call getCameras() to get its device ID. On a mobile device, you can set deviceId to 'user' or 'environment' to switch to the front or rear camera respectively.
  • For a mic, you can call getMicrophones() to get its device ID.
Returns:
Type
Promise

(async) addTrack(track)

Add an audio or video track.

You can call this API to add audio/video tracks to local streams. If local streams are published, this API, when called, will automatically update the audio/video streams sent to remote devices. In that case, the remote devices will receive the Client.on('stream-updated') event notification.

You can get the new audio/video track via createStream()/ getAudioTrack()| getVideoTrack() or directly via getUserMedia() and captureStream().

NOTE

  • A stream object can contain at most one audio track and one video track. If you want to replace a track with one of the same type, please use replaceTrack().
  • When adding a video track, make sure that the video resolution is consistent with that specified in setVideoProfile(). Otherwise, an exception will be thrown.
  • Do not call this API before the removeTrack or publish API call is completed. Otherwise, an API call exception may occur.
Example
const localStream = TRTC.createStream({ userId, audio: true, video: false });
localStream.initialize().then(() => {
  // Publish local stream (only the audio stream captured from the mic)
  client.publish(localStream);
});
// ...
// Enable video call
const videoStream = TRTC.createStream({ userId, audio: false, video: true });
videoStream.initialize().then(() => {
  const videoTrack = videoStream.getVideoTrack();
  // Insert the video track captured from the camera into the currently published local stream object `LocalStream`
  localStream.addTrack(videoTrack).then(() => {
    // When video call is enabled successfully, the remote device will receive the `stream-updated` notification
  });
});
//
Parameters:
Name Type Description
track MediaStreamTrack

Audio/Video track

Throws:

RtcErr

(async) removeTrack(track)

Remove video tracks.

You can call this API to remove video tracks from local streams. If the local streams are published, this API, when called, will automatically update the video streams sent to remote devices. In that case, the remote devices will receive the Client.on('stream-updated') event notification.

Note that a published Stream object must contain at least one media track. If you want to completely remove audio and video tracks from local streams, call unpublish() to unpublish the local streams and then call close() to close the local streams.
NOTE

  • Currently, audio tracks cannot be removed. To disable audio, call muteAudio().
  • Do not call this API before the addTrack or publish API call is completed. Otherwise, an API call exception may occur.
  • After the video track is removed, hasVideo() will return false.
  • Remove audioTrack is supported since v4.15.0+, also you can remove both video & audio track at same time. Supported browsers: Chrome 69+, Safari 11+, Firefox 59+, Edge 79+.
Example
// Disable video call, corresponding to the example of video call enabling via the `addTrack` API
const videoTrack = localStream.getVideoTrack();
if (videoTrack) {
  localStream.removeTrack(videoTrack).then(() => {
    // Video call disabled successfully. Stop `videoTrack` and release the camera resource
    videoTrack.stop();
  });
}
Parameters:
Name Type Description
track MediaStreamTrack

Video track, obtained via getVideoTrack()

Throws:

RtcErr

(async) replaceTrack(track)

Replace audio/video tracks

You can call this API to replace tracks of the same type in local streams. If the local streams are published, this API, when called, will automatically update the audio/video streams sent to remote devices. In that case, the remote devices will receive the Client.on('stream-updated') event notification.

You can get the new audio/video track via createStream()/ getAudioTrack()| getVideoTrack() or directly via getUserMedia() and captureStream().

NOTE

  • If you need to change the media input device, you are advised to use switchDevice().
  • When replacing a video track, make sure that the video resolution is consistent with that specified in setVideoProfile(). Otherwise, an exception will be thrown.
  • Supported browsers are Chrome 65+, Safari 11+, Firefox 56+, and Edge 80+.
  • Do not call this API before the publish API call is completed. Otherwise, an API call exception may occur.
Parameters:
Name Type Description
track MediaStreamTrack

Audio/Video track

Throws:

RtcErr

setAudioCaptureVolume(volumeopt) → {Boolean}

Set microphone capture volume

Supports Chrome 65+、Safari 11+、Firefox 56+、Edge 80+

Since:
  • v4.14.0
Example
// set the capture volume in half
localStream.setAudioCaptureVolume(50);
// set the capture volume to 0
localStream.setAudioCaptureVolume(0);
// increase the capture volume by 1.5 times
localStream.setAudioCaptureVolume(150);
const result = localStream.setAudioCaptureVolume(50);
if (!result && localStream.hasAudio()) {
 // not supported in current browser.
}
Parameters:
Name Type Attributes Default Description
volume Number <optional>
100

Recommended value is 0 - 100. The default capture volume is 100. If it is set greater than 100, the capture volume can be increased, but there is a risk of popping sound. Please use it with caution.

Returns:

true means volume is set successfully, false means set capture volume failed.
Reasons:

  1. LocalStream did not capture microphone
  2. volume value is smaller than 0
  3. not supported in current browser
Type
Boolean

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

Play the audio/video stream
This API creates an

  • Due to browsers’ autoplay policy, a PLAY_NOT_ALLOWED error may be returned when you call this API. In that case, display a window on the UI and, in the callback for the window’s clicking event, call resume() to resume audio/video playback.
Inherited From:
Example
// For versions earlier than v4.8.4, capture and handle the 0x4043 error as follows.
stream.play('remote').then(() => {
  // autoplay success
}).catch((error) => {
  const errorCode = error.getCode();
  if (errorCode === 0x4043) {
    // If the `PLAY_NOT_ALLOWED` error occurs, display a window on the UI and, in the callback for the window’s clicking event, call `stream.resume` to resume audio/video playback.
    // stream.resume()
  }
});
// For v4.8.4 and later versions, we strongly recommend that you use the error callback of `Stream` to capture and handle the 0x4043 error.
stream.play('remote').catch(error => {});
stream.on('error', error => {
  const errorCode = error.getCode();
  if (errorCode === 0x4043) {
    // If the `PLAY_NOT_ALLOWED` error occurs, display a window on the UI and, in the callback for the window’s clicking event, call `stream.resume` to resume audio/video playback.
    // stream.resume()
  }
})
Parameters:
Name Type Attributes Description
elementId string | HTMLDivElement

HTML <div> stag ID or HTMLDivElement object in DOM. This method will create video/audio tag in elementId to play stream.

options object <optional>

Playback options

Properties
Name Type Description
objectFit string

Video fill mode. For details, see the CSS object-fit property.

  • 'contain': The video image is scaled as large as its long side can go. The blank area is filled with black bars. This mode ensures that the image is displayed in whole.
  • 'cover': The video image is scaled as large as the short side can go. The image fills the entire screen, but may be cropped.
  • 'fill': Ensures that the viewport is filled and the video content is displayed in its entirety, but does not guarantee that the video size remains proportional. The width and height of the video will be stretched to match the size of the viewport. (This option value is supported since v4.12.1)

The cover mode is used by default to play the video stream and the contain mode is used by default to the screen sharing stream.

muted boolean

Whether muting is required.

  • For local streams, muted defaults to true, preventing playback of sounds captured from the microphone.
mirror boolean

Whether to enable video mirroring preview. (This option is supported since v4.12.1)Note

  • For local video stream, mirror preview is enabled by default. It is recommended to enable mirroring when using the front camera and disable mirroring when using the rear camera.
  • For remote video stream, mirror preview is disabled by default.
  • For screen sharing streams, enabling mirror preview is not supported.
  • This Property is only valid for local preview, pushing the stream is no mirroring effect.
Throws:
Returns:
Type
Promise

stop()

Stop playing an audio/video stream

This API will also delete the audio and video tags created via play() from the HTML page.

Inherited From:

(async) resume() → {Promise}

Resume playing an audio/video stream
NOTE

  • On some browsers, moving the div container passed in by play() may cause the audio and video players to pause. In that case, you need to call this API to resume playback.
  • If play() returns the PLAY_NOT_ALLOWED error due to the browser’s autoplay policy, display a window on the UI and, in the callback for the window’s clicking event, call this API to resume playback.
Inherited From:
Example
stream.on('player-state-changed', event => {
  if (event.state === 'PAUSED') {
    // resume audio/video playback
    stream.resume();
  }
});
Throws:
Returns:
Type
Promise

close()

Close an audio/video stream

For local streams, this API will turn the camera off and release the camera and mic.

Overrides:

muteAudio() → {boolean}

Disable the audio track of a stream and keep the audio track, usually for temporary muting of local streams.

  • For local streams, this API will stop audio sending, and remote users will receive the Client.on('mute-audio') callback.
  • For remote streams, after this API is called, the local user will stop playing the remote user’s audio but will continue to receive audio data from the user.
Overrides:
Returns:
  • true: The audio track is disabled successfully.
  • false: Failed to disable the audio track as it does not exist
Type
boolean

muteVideo() → {boolean}

Disable the video track of a stream

  • For local streams, this API will stop video sending, and remote users will receive the Client.on('mute-video') callback. If video is captured from the camera, the camera will not be turned off by this API. To turn the camera off, call removeTrack() to remove the video track and then. MediaStreamTrack.stop() to disable video (turn the camera off).
  • For remote streams, after this API is called, the local user will stop playing the remote user’s video but will continue to receive video data from the user. If you do not want to receive video data, use Client.unsubscribe to unsubscribe, or Client.subscribe to subscribe to video only.
Overrides:
Returns:
  • true: The video track is disabled successfully.
  • false: Failed to disable the video track as it does not exist.
Type
boolean

unmuteAudio() → {boolean}

Enable the audio track of a stream

For local streams, this API will trigger the Client.on('unmute-audio') callback for remote users.

The audio track is enabled by default. If it is disabled via muteAudio(), you can call this API to enable the audio track again.

Overrides:
Returns:
  • true: The audio track is enabled successfully.
  • false: Failed to enable the audio track as it does not exist.
Type
boolean

unmuteVideo() → {boolean}

Enable the video track of a stream

For local streams, this API will trigger the Client.on('unmute-video') callback for remote users.

The video track is enabled by default. If it is disabled via muteVideo(), you can call this API to enable the video track again.

Overrides:
Returns:
  • true: The video track is enabled successfully.
  • false: Failed to enable the video track as it does not exist.
Type
boolean

getId() → {string}

Get the unique ID of a stream

Inherited From:
Returns:

Id: unique ID of the stream

Type
string

getUserId() → {string}

Get the ID of the user to whom a stream belongs

Inherited From:
Returns:

userId: user ID

Type
string

(async) setAudioOutput(deviceId)

Set the audio output device

  • No support for mobile devices.
Inherited From:
Parameters:
Name Type Description
deviceId string

Device ID, which can be obtained via getSpeakers()

getAudioLevel() → {number}

Get the current volume
This API works only if there is audio data in the local stream or a remote stream. Before calling this API, you need to play the stream first.

Inherited From:
Example
setInterval(() => {
  const level = stream.getAudioLevel();
  if (level >= 0.1) {
    console.log(`user ${stream.getUserId()} is speaking`);
  }
}, 200);
Returns:

audioLevel: volume

  • Value range: 0.0-1.0. Generally, a user is considered to be speaking if the value is greater than 0.
Type
number

hasAudio() → {boolean}

Get whether a stream has an audio track

  • If you need to get the Stream mute state, you need to listen to the Client.on('mute-audio') event for further processing.
Inherited From:
Returns:
Type
boolean

hasVideo() → {boolean}

Get whether a stream has a video track

  • If you need to get the Stream mute state, you need to listen to the Client.on('mute-video') event for further processing.
Inherited From:
Returns:
Type
boolean

getAudioTrack() → {MediaStreamTrack}

Get the audio track of a stream

Inherited From:
Returns:

Audio tra

Type
MediaStreamTrack

getVideoTrack() → {MediaStreamTrack}

Get the video track of a stream

Inherited From:
Returns:

Video tra

Type
MediaStreamTrack

getVideoFrame() → {String}

Get the current video frame
NOTE

  • This API works only if it is called after play() and the stream contains video.
Inherited From:
Example
// Get the current video frame
const frame = stream.getVideoFrame();
if (frame) {
  const img = document.createElement('img');
  img.src = frame;
}
Returns:

dataURL of 'image/png' type

Type
String

on(eventName, handler, context)

Listen for Stream events
For the detailed event list, please see 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

Event name

handler function

Event handling method

context object

Context object

off(eventName, handler, context)

Stop listening for Stream events

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

Event name. If the wildcard '*' is passed in, all bound events will be unbound.

handler function

Event handling method

context object

Context object