How to wake up an inactive AudioTracks property

67 Views Asked by At

I could obtain the correct AudioTracks.length through a button click; however, I cannot obtain it without such an action. Please see my code below. I could obtain it at line (B) but cannot at (A). Why? How can I obtain it at (A)? I have a faint awareness that I don't understand something fundamental, but I'm in trouble because I don't know what it is. Please help me. Thank you so much for your kindness.

[My code]

<!DOCTYPE html>
<html>
    <body>
        <h3>Please use a browser supporting AudioTracks property. See [Note] for details.</h3>
        <video id="video" controls>
            <source src="https://www.w3schools.com/tags/mov_bbb.mp4"></source >
        </video>
        <button onclick="myFunction()">Click (myFunction)</button>
        <script>
            console.log("(A) = " + video.audioTracks.length );// (A) = 0
            function myFunction() {
                console.log("(B) = " + video.audioTracks.length );// (B) = 2
            }
        </script>
    </body>
</html>

[Note] The audioTracks property is not supported in any major browsers. It is supported in Chrome beta by enabling "enable-experimental-web-platform-features" in chrome:flags.

  1. Download Chrome beta Version 107.
  2. Type "chrome://flags/" in the address bar to see "Experiments" page.
  3. Enable "#enable-experimental-web-platform-features".

[Reference] https://caniuse.com/audiotracks

2

There are 2 best solutions below

1
Kaiido On BEST ANSWER

You need to wait for the resource is at least preloaded before you can try to read anything from it (be it audioTracks, but even .duration etc.).

So wait for either the loadedmetadata event, or even the canplay one.

const vid = document.querySelector("video");
vid.onloadedmetadata = (evt) => {
  console.log(vid.audioTracks);
};
<video controls>
  <source src="https://www.w3schools.com/tags/mov_bbb.mp4">
</video>

6
Jacob Malland On

I took a look at your code, and tried running it as such:

<!DOCTYPE html>
<html>
    <body>
        <h3>Please use a browser supporting AudioTracks property. See [Note] for details.</h3>
        <video id="video" controls>
            <source src="https://www.w3schools.com/tags/mov_bbb.mp4"></source >
        </video>
        <button onclick="myFunction()">Click (myFunction)</button>
        <script> 
            console.log("(A)"+document.getElementById("video").audioTracks);// (A) = 0
            function myFunction() {
                console.log("(B) = " + video.audioTracks.length );// (B) = 2
            }
        </script>
    </body>
</html>

NOTE: I did not realize I had to restart my browser to initiate this effect

@Kaiido is correct, all you need to do is wait for the metadata to load.

I changed your video element to this:

<video id="video" onloadedmetadata="myFunction()" controls=true>
            <source src="https://www.w3schools.com/tags/mov_bbb.mp4"></source >
</video>

Once the video loaded, it outputted (B) = 2 without my having to click the button.

If you are looking to run code, waiting until it has finished loading, you can use the onloadedmetadata feature, or if you have a bunch of elements you need to load, you can utilize window.requestNewAnimationFrame(runningFunc) to check to see if everything is loaded, or just recursively call the function until it is loaded.

I hope this answers your question, and clarifies any incorrect statements I made.