Skip to content

Conversation

rktguswjd
Copy link
Contributor

resolve #1434

Copy link

changeset-bot bot commented Mar 11, 2025

🦋 Changeset detected

Latest commit: e10afd6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
livekit-client Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant
Copy link

CLAassistant commented Mar 11, 2025

CLA assistant check
All committers have signed the CLA.

Copy link
Contributor

@lukasIO lukasIO left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, just one thing that needs fixing

constraints = this._constraints;
}
const { deviceId, ...otherConstraints } = this._constraints;
constraints = { ...this._constraints, ...(constraints ?? {}) };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this mutates the passed constraints, we'd want to create a separate local variable for this

Comment on lines 346 to 347
this._constraints = trackConstraints;

Copy link
Contributor Author

@rktguswjd rktguswjd Mar 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am modifying the order of operations in the restart method. I moved this._constraints = trackConstraints; before the setMediaStream call. Please review these changes!

The reason for this change is to prevent potential loss of deviceId information. Here's the current issue:

  1. If we get a new track without a specified deviceId
  2. Then in setMediaStreamTrack, we do this._constraints = newTrack.getConstraints(); (which might obtain a new deviceId)
  3. And then back in restart, we do this._constraints = trackConstraints;
  4. This could result in losing the deviceId information

Copy link
Contributor

@lukasIO lukasIO Mar 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do this._constraints = newTrack.getConstraints(); (which might obtain a new deviceId)

I don't believe this is true, getConstraints should always return the constraints that have been used to construct the mediastreamtrack, see https://w3c.github.io/mediacapture-main/#dom-constrainablepattern-getconstraints

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, maybe you're right and this

that were the argument to the most recent successful invocation

means that it's exclusively the last call to applyconstraints which would always be missing the device Id in our case.

Copy link
Contributor Author

@rktguswjd rktguswjd Mar 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you, and I think my explanation was incomplete.
I was concerned about cases where this._constraints's deviceId becomes undefined before creating newTrack, like this:

const trackConstraints = { ...this._constraints, ...constraints?? {} }
const { deviceId } = trackConstraints // deviceId is undefined
// omitted
const newTrack = await navigator.mediaDevices.getUserMedia({ audio: true }).getTracks()[0]
await this.setMediaStreamTrack(newTrack); //  this._constraints = { deviceId: "anything" }
this._constraints = trackConstraints; // this._constraints = { deviceId: undefined }

Even if such situations don't occur, I think there's no guarantee that trackConstraints and newTrack.getConstraints() will always be identical in the current code. Therefore, I believed it would be safer to assign newTrack.getConstraints() to this.constraints at the end.

If anything is unclear or if you disagree with my explanation, please let me know🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukasIO Do you agree with this change? While this is a different context from the original issue we were trying to solve, I had provided an additional suggestion. If it's not valid, we can rollback this :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, please revert this. If you have a reproduction of a case where this causes an actual problem feel free to open a separate issue/PR and I'll take a look :)

@rktguswjd rktguswjd requested a review from lukasIO March 12, 2025 07:06
if (!constraints) {
constraints = this._constraints;
}
const { deviceId, ...otherConstraints } = this._constraints;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rktguswjd thinking more about this I think the correct fix is simply to change this line to

      const { deviceId, ...otherConstraints } = constraints;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, I thought we needed to merge this._constraints with the given constraints. I see that wasn't the intention! I'll fix it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, if you can just revert that other change now, then we're good to go!

The reason the constraints are overridden after setMediaStreamTrack is because the constraints passed in by the user are the desired constraints. We want to reuse the desired constraints after, too. And as we don't merge any constraints together this should be sufficient

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the constraints passed in by the user are the desired constraints.

That makes sense! Thank you for clarifying the intention!

Copy link
Contributor

@lukasIO lukasIO left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for catching this!

@rktguswjd rktguswjd force-pushed the fix/local-track-restart branch from b93f0a7 to eb787d7 Compare March 12, 2025 15:59
@rktguswjd
Copy link
Contributor Author

@lukasIO Oh, sorry. I did a force push and the changeset commit disappeared🥲

@lukasIO
Copy link
Contributor

lukasIO commented Mar 12, 2025

no worries, I added it back in!

@lukasIO lukasIO merged commit 49cf56d into livekit:main Mar 12, 2025
3 checks passed
@github-actions github-actions bot mentioned this pull request Mar 12, 2025
svajunas-budrys pushed a commit to svajunas-budrys/client-sdk-js that referenced this pull request Jun 17, 2025
Co-authored-by: lukasIO <mail@lukasseiler.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

LocalTrack.restart() method ignores user-provided constraints
3 participants