Please excuse our look. We're just getting started here.
Want to learn more about Twilio Forums? Check out our FAQ page here.Twilio Video JavaScript V2 - Aspect Ratio Defaults to 640 480

Hello,
Twilio Video JavaScript defaults to Width 640 and Height 480 although the code specifies 1280 and 720 for a HD laptop camera and for a 1980 & 1080p camera.
Has anyone seen that bug?
What to do?
Regards
Answers
-
How are you specifying the resolution in your code?
-
Hello Nash,
To connect to a small Twilio room I use the following code:
const token = await this.getAuthToken(participant);
room = await connect(token, {
name,
tracks,
video: { height: 720, frameRate: 24, width: 1280 },
aspectRatio:1.77777777778,
bandwidthProfile: {
video: {
mode: 'collaboration',
dominantSpeakerPriority: 'high',
}
},
dominantSpeaker: true,
preferredVideoCodecs:[{codec:'VP8',simulcast:false}],
networkQuality: {local:1, remote: 1}
} as ConnectOptions);
-
And this the report from Google Chrome developer tools:
{group: "quality", name: "stats-report", payload: {,…}, timestamp: 1645474146332, type: "event",…}
group: "quality"
name: "stats-report"
payload: {,…}
audioTrackStats: [{trackId: "8a3f9e5f-5fa5-41e1-af67-2557dde51b10", trackSid: "MT0cf01aac8b084ed8ef689aaef447149f",…}]
localAudioTrackStats: [{trackId: "15e75dec-9cc2-4c5b-bcd8-154bb190d2ca", trackSid: "MT4b2e5c126b6c3761f6d9346452e45e03",…}]
localVideoTrackStats: [{trackId: "076178c1-04a7-48ea-aabc-466ef172c73d", trackSid: "MT37db7447b49b2ddf9f37afc9ab8f40f4",…}]
0: {trackId: "076178c1-04a7-48ea-aabc-466ef172c73d", trackSid: "MT37db7447b49b2ddf9f37afc9ab8f40f4",…}
bytesSent: 120467586
captureDimensions: null
captureFrameRate: null
codec: "VP8"
dimensions: {width: 640, height: 480}
height: 480
width: 640
frameRate: 31
packetsLost: 560
packetsSent: 113870
roundTripTime: 86
ssrc: "700454453"
timestamp: 1645474146328
trackId: "076178c1-04a7-48ea-aabc-466ef172c73d"
trackSid: "MT37db7447b49b2ddf9f37afc9ab8f40f4"
peerConnectionId: "fe83f4c5-15a0-4483-a1a6-798c145b9b2a"
videoTrackStats: [{trackId: "b87f2b3b-02d8-496d-a9aa-9a391b32ee0d", trackSid: "MT43846f4fe1ec246d73cb32bae4cc5a13",…}]
0: {trackId: "b87f2b3b-02d8-496d-a9aa-9a391b32ee0d", trackSid: "MT43846f4fe1ec246d73cb32bae4cc5a13",…}
bytesReceived: 88212458
codec: "VP8"
dimensions: {width: 640, height: 480}
height: 480
width: 640
frameRate: null
packetsLost: 191
packetsReceived: 83794
ssrc: "2004995826"
timestamp: 1645474146328
trackId: "b87f2b3b-02d8-496d-a9aa-9a391b32ee0d"
trackSid: "MT43846f4fe1ec246d73cb32bae4cc5a13"
session: "902cf5ec-f6af-4ea2-a919-cd8af01805d9"
timestamp: 1645474146332
type: "event"
version: 1
-
To create a room I use
const tracks = await Promise.all([createLocalAudioTrack(),createLocalVideoTrack()]);
-
Do I need to pass video arguments on createLocalVideoTrack or the connect I sent before is sufficient?
-
I can see you're passing both a
tracks
option to the connect options as well as avideo
option.tracks
will overridevideo
, so how are you getting those tracks initially? -
I think I started asking my question before you posted your last update.
If you are creating the video tracks before you connect to the room using in
createLocalVideoTrack
then you will need to pass the media constraints that you want to that function.While you are working on this, I would likely expand the video media constraints to make it easier for browsers to fulfil your request while also giving you a range to work within. You can do this by using min, max, and ideal to set the boundaries for the resolution you want. For example:
const videoTrack = await createLocalVideoTrack({ height: { ideal: 720, min: 480, max: 1080 }, width: { ideal: 1280, min: 640, max: 1920 }, aspectRatio: 1.77777777778, frameRate: 24 });
Do make sure you handle the
OverconstrainedError
in case you are in a browser that cannot handle the constraints you are asking for. That is normally a problem when using exact constraints, rather than min, max, and ideal, but it's good to handle just in case. -
Thank you so much. I'll try your solution and let you know.
All the best
-
Hello,
I applied the changes but the height and width are still the same.
Here is the code I used.
private async createRoom(room: IRoom) {
this.camera.finalizePreview();
const tracks = await Promise.all([createLocalAudioTrack(),createLocalVideoTrack(
{
height: { ideal: 720, min: 480, max: 1080 },
width: { ideal: 1280, min: 640, max: 1920 },
aspectRatio: 1.77777777778,
frameRate: 24
}
)]);
this.settings.showPreviewCamera();
this.activeRoom = await this.videoChatService.joinOrCreateRoom(room.name.toString(), room.participant, tracks);
this.participants.initialize(this.activeRoom.participants);
this.registerRoomEvents();
this.createChatConversation(room);
}
Part of VideoChatService ===================
async joinOrCreateRoom(name: string, participant: string, tracks: LocalTrack[]) {
let room: Room = null;
try {
const token = await this.getAuthToken(participant);
room = await connect(token, {
name,
tracks,
dominantSpeaker: true,
} as ConnectOptions);
} catch (error) {
console.error(`Unable to connect to Room: ${error.message}`);
} finally {
if (room) {
console.log(room);
this.roomBroadcast.next(true);
}
}
return room;
}
================Part of Google Chrome Dev Tools showing the height and width used by Chrome:
- payload: {,…}
- audioTrackStats: [{trackId: "826de08a-49fa-4cdb-b837-214f0523ff07", trackSid: "MTc8f7d39575117ff7befcd732cf7c04b9",…}]
- localAudioTrackStats: [{trackId: "00eaa676-796c-4eae-a125-d08b89c4db06", trackSid: "MT8e1b6ca490e537d0f2950d76f27d1026",…}]
- localVideoTrackStats: [{trackId: "20946190-2d1a-4122-9288-b98e1089fc1f", trackSid: "MT0c60c2f69ee6ce60e01eaf03e5c6b04b",…}]
- peerConnectionId: "0f00a030-4491-49bd-8b37-853c8a2b7b1a"
- videoTrackStats: [{trackId: "cc60b124-d8dc-4941-8dff-50ac088ff658", trackSid: "MTdc44ff77b7ae2e86d0a5a353f07f1f99",…}]
- 0: {trackId: "cc60b124-d8dc-4941-8dff-50ac088ff658", trackSid: "MTdc44ff77b7ae2e86d0a5a353f07f1f99",…}
- bytesReceived: 374129
- codec: "VP8"
- dimensions: {width: 640, height: 480}
- frameRate: null
- packetsLost: 0
- packetsReceived: 370
- ssrc: "1062797222"
- timestamp: 1645491172331
- trackId: "cc60b124-d8dc-4941-8dff-50ac088ff658"
- trackSid: "MTdc44ff77b7ae2e86d0a5a353f07f1f99"
- session: "385f39e4-b6cf-492c-b1dd-c1d5839d86b6"
- timestamp: 1645491172346
- type: "event"
- version: 1
-
I did a new test setting the min to 720 for height and 1280 for width and ended with an Overconstrained error.
height: { ideal: 720, min: 480, max: 1080 },
width: { ideal: 1280, min: 640, max: 1920 },
======================
main-es2015.3ce8703b9199aa632c7d.js:1 ERROR Error: Uncaught (in promise): OverconstrainedError: {}
at T (polyfills-es2015.0e5f8ae0f93963ba3cc4.js:1:33748)
at polyfills-es2015.0e5f8ae0f93963ba3cc4.js:1:32827
at a (main-es2015.3ce8703b9199aa632c7d.js:1:2863746)
at u.invoke (polyfills-es2015.0e5f8ae0f93963ba3cc4.js:1:24369)
at Object.onInvoke (main-es2015.3ce8703b9199aa632c7d.js:1:2224348)
at u.invoke (polyfills-es2015.0e5f8ae0f93963ba3cc4.js:1:24309)
at a.run (polyfills-es2015.0e5f8ae0f93963ba3cc4.js:1:19781)
at polyfills-es2015.0e5f8ae0f93963ba3cc4.js:1:34544
at u.invokeTask (polyfills-es2015.0e5f8ae0f93963ba3cc4.js:1:24987)
at Object.onInvokeTask (main-es2015.3ce8703b9199aa632c7d.js:1:2224164)
-
Hello,
It's working now with the configuration you proposed.
Thank you very much.
-
That was a bit of a journey! I'm glad it's working now. I was going to suggest that perhaps the camera you are requesting this from did not support more than 640x480, but if you got it to work it must have been something else.
I'd love to understand what happened here, so if you know and don't mind, could you share why your first attempt with the new constraints didn't work and what you did to make it work?
-
Hello Nash,
The first attempt failed simply because we create a local video track from two "places" in our code depending on the business logic.
We forgot to update the second "place" where we use createLocalVideoTrack.
The instructions are the same and are the ones you sent.
It's working well now.
Many thanks for your help.
-
Ah awesome. Glad it's working and you discovered what was going on!
-
Hello @pnash ,
My webcam remains active after stopping it with the following Angular code.
public closeMeeting(aRoom: Room): void {
this.aRoom.localParticipant.videoTracks.forEach((publication) => {
publication.unpublish();
publication.track.stop();
});
this.aRoom.disconnect();
this.aRoom = null;
}
Thanks you for your help
Bod
Categories
- 83 All Categories
- 19 SIGNAL 2021
- 376 Product Discussions
- 7 Community - Announcements
- 2 Changelog
- 4 Forum UI Updates
- 8 Welcome Guide
- 6 Community - Events
- 2 Twilio Relay Developer Conference 2021 Mega Thread
- 1 External Community Events
- 25 Inspiration
- 17 Community - Other Discussions
- 1 Community- Twilio Startups