videojs / video.js

Video.js - open source HTML5 video player
https://videojs.com
Other
37.81k stars 7.43k forks source link

Changing audio and text tracks before playback starts doesn't cause change to the playback #8586

Open anthonyrivas opened 6 months ago

anthonyrivas commented 6 months ago

Description

When capturing track load and enabling a different track programmatically, it doesn't change the playback to use the selected track when play is called. But the menu does change to indicate that it is selected.

It DOES work as expected if playback starts first though.

Reduced test case includes examples of both behaviors.

Reduced test case

https://codepen.io/anthonyrivas/pen/LYqVaOm

Steps to reproduce

  1. Open reduced test case
  2. Uncomment "Doesn't work" section of JS code
  3. Click the play button
  4. Note that audio is in english, but the audio menu shows Dutch selected
  5. Comment "Doesn't work" section back out and uncomment "Works" section
  6. Click the play button
  7. Note the audio is in Dutch and shows as Dutch in the menu

Errors

No response

What version of Video.js are you using?

8.10.0

Video.js plugins used.

No response

What browser(s) including version(s) does this occur with?

Chrome 121

What OS(es) and version(s) does this occur with?

Mac 13.6.3

amtins commented 6 months ago

@anthonyrivas I was unable to reproduce the problem described in point 4. Does the following code solve it?

player.on('loadedmetadata', () => {
  Array.from(player.audioTracks()).forEach(track => (track.enabled = track.language === 'nl'))
});

During the loadedmetadata event, the player should be able to change the language of the audio/subtitle.

However, if I remember correctly, there seems to be an exception for Safari, in which case the loadeddata event should be preferred.

anthonyrivas commented 6 months ago

Looks like that may show some promise as a solution for our team. The reason we were using track events was because of safari, so the loadeddata event may be helpful for us.

anthonyrivas commented 6 months ago

One thing we have experienced that we believe is a side-effect of this bug is that sometime audio plays momentarily in the default language before switching to the preferred audio track.

mister-ben commented 6 months ago

I did reproduce just now. Possibly enabling/disabling on every addtrack in quick succession is causing some race condition. A little debounce would be better here. Or just wait for another event as above.

const debouncedHandler = videojs.fn.debounce((e) => {
  Array.from(player.audioTracks()).forEach((track) => {
    track.enabled = track.label === 'Dutch';
  });
}, 50);

player.ready(() => { player.audioTracks().addEventListener('addtrack', debouncedHandler);
});

You need to use addEventListener with track lists. Where native tracks are used (Safari) the native track list won't have Video.js's on.