-
Notifications
You must be signed in to change notification settings - Fork 729
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ahoyapps 960 stop video on disconnect #401
Conversation
|
||
export default function useLocalTracks() { | ||
const [audioTrack, setAudioTrack] = useState<LocalAudioTrack>(); | ||
const [videoTrack, setVideoTrack] = useState<LocalVideoTrack>(); | ||
const [isAcquiringLocalTracks, setIsAcquiringLocalTracks] = useState(false); | ||
|
||
const localAudioDevices = useAudioInputDevices(); | ||
const localVideoDevices = useVideoInputDevices(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we use useAudioInputDevices
and useVideoInputDevices
here? Is it because we are calling useDevices
internally twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it because we are calling useDevices internally twice?
Yeah. So, there are two calls to useDevices
, which means that there are two separate calls to enumerateDevices
. It's a bit awkward since enumerateDevices
resolves asynchronously. Because it's async, the initial value returned by useDevices
is an empty array. So this is what happens when the app starts:
First:
const localAudioDevices = useAudioInputDevices(); // returns []
const localVideoDevices = useVideoInputDevices(); // returns []
Then:
const localAudioDevices = useAudioInputDevices(); // returns [{deviceId: 'my-audio-device-id'}]
const localVideoDevices = useVideoInputDevices(); // returns []
At this point, createLocalTracks()
is called due to the logic on this line. And because there are no video devices yet, the app is started without acquiring video.
Then:
const localAudioDevices = useAudioInputDevices(); // returns [{deviceId: 'my-audio-device-id'}]
const localVideoDevices = useVideoInputDevices(); // returns [{deviceId: 'my-video-device-id'}]
So it's a little awkward that the two hooks resolve at different times. I could probably update the logic on line 51, but there's also no reason to call enumerateDevices
more than once. So the change in the PR makes it so we get the list of audio devices and video devices at the exact same time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I get what was happening. Thanks for more details! I saw the same issue in the diagnostics app and ended up removing both useAudioInputDevices
and useVideoInputDevices
.
But for our use case in video app, this seems like a code smell since it's possible that we may run into this issue again if we or another developer use both of these hooks at the same time. What is your suggestion to prevent us from making this mistake in the future? My suggestion is, we can update both useAudioInputDevices
and useVideoInputDevices
such that when one is called, it waits for the other if the other is pending. Kinda like an async queue behavior. Personally, it feels cleaner this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's possible that we may run into this issue again if we or another developer use both of these hooks at the same time. What is your suggestion to prevent us from making this mistake in the future?
Honestly, I'm leaning toward removing the useAudioInputDevices
, useVideoInputDevices
, and useAudioOutputDevices
hooks altogether. I created them for the sake of convenience, but given the issue that arises when more than one of these hooks are used together (which I was unaware of when I made these hooks), they aren't really that convenient. Even without this issue, these hooks would save you one line of code at best. Since they don't provide much value, I think there's little harm in removing them.
Another idea would be to cache the initial value that is used when these hooks are called. Whenever any hook calls enumerateDevices
, it could update the cached initial value. So when any of these hooks are called, they are initialized with the most recent list of devices, instead of an empty array.
we can update both useAudioInputDevices and useVideoInputDevices such that when one is called, it waits for the other if the other is pending.
I don't think that this is necessary. When useAudioInputDevices
and useVideoInputDevices
are called one after another, it results in two immediate calls to enumerateDevices
. Calling enumerateDevices
twice in a row will virtually guarantee that their return values will be identical. Thus, when the first enumerateDevices
promise resolves, there is no need to wait for the second promise to resolve because we already have all the information that we need, and we know exactly what the value of the second promise will be. To me, using an async queue here feels a little bit like an anti-pattern. I think it would be best if enumerateDevices
is called only once inside useLocalTracks
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. It sounds like removing useAudioInputDevices, useVideoInputDevices, and useAudioOutputDevices hooks altogether is our best option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@charliesantos I redid the deviceHooks file as we discussed on Slack. It involved quite a few changes all over the place. This PR is a bit bigger now, but I do like the new useDevices
hook much more than what we had previously.
Consolidate six hooks into one, and rename file to useHooks.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
Contributing to Twilio
Pull Request Details
JIRA link(s):
Description
This PR fixes the following issues:
https://my-example-app-1234/room/my-test-room
). There is no ticket for this issue. This issue is solved by usinguseDevices
insideuseLocalTracks
instead of using bothuseLocalVideoDevices
anduseLocalAudioDevices
. This change means thatenumerateDevices
will be called once instead of twice, which fixes the issue.Burndown
Before review
npm test
Before merge