Youtube API's getDuration() function keeps returning 0 or "undefined"

4 weeks ago 25
ARTICLE AD BOX

I'm currently a beginner in JavaScript and I want to make a YouTube player for my personal website. I want the user to be able to click a button on the player and skip forward to the next or previous song. I also want the user to see the complete duration of the song, along with other details about it.

I tried using the player.getDuration() function which comes with YouTube's embed API, and assigning the value to the videoLength variable but no matter what I do, the value it returns is undefined or 0, which is it's initial value in my code. I believe the problem is that the player gets the video by using the loadVideoByUrl() function, instead of me passing the video id in the onYouTubeIframeAPIReady(). I would like to be able to have the video urls and other info about the songs in the object array so I can keep adding songs without the need of making a playlist on YouTube.

Here is the JavaScript code. It's not done, but I would like o figure this out before moving on.

/*Playlist defined as an array of objects*/ let songs = [ { "title": "Dollz Doll - Sasha Solo", "artist": "Bratz", "album": "Dollz Doll", "year": 2025, "url": "https://www.youtube-nocookie.com/embed/5mmSXIg6Ig4?si=hdDWCzDytQ-186Y3" }, { "title": "Think About It", "artist": "Bratz", "album": "Think About It", "year": 2025, "url": "https://www.youtube-nocookie.com/embed/lfYl_f8zo9Y?si=5aMcKkeIqR8TCciP" }, { "title": "Speed Drive", "artist": "Charli XCX", "album": "Barbie The Album", "year": 2023, "url": "https://www.youtube-nocookie.com/embed/TxZwCpgxttQ?si=Ymw_FXTfHlbODIkR" } ] let songsLength = songs.length; let i = 0; /*Selecting the elements*/ let songTitle = document.querySelector('h1'); let songArtist = document.getElementById('artist'); let songAlbum = document.getElementById('album'); let songYear = document.getElementById('release_year'); let btnToggle = document.getElementById('toggle'); let btnNext = document.getElementById('next'); let btnPrev = document.getElementById('previous'); let btnVolume = document.getElementById('volume_button'); let volumeBar = document.getElementById('volume_bar'); /*YT-api*/ let tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; let firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); let player; function onYouTubeIframeAPIReady() { player = new YT.Player('yt_video', { origin: 'https://dorianbay.neocities.org/', playerVars: { 'playsinline': 1, 'controls': 0 }, events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); } function onPlayerReady(event) { setSongInfo(i); } function onPlayerStateChange() { //work-in-progress } function setSongInfo(i) { player.loadVideoByUrl(songs[i].url); songTitle.textContent = songs[i].title; songArtist.textContent = 'Artist: ' + songs[i].artist; songAlbum.textContent = 'Album: ' + songs[i].album; songYear.textContent = 'Year of release: ' + songs[i].year; //videoLength is currently 0 let videoLength = player.getDuration(); document.getElementById('song_finish').innerHTML = videoLength; } function previousSong() { i--; if(i < 0) { i = songsLength - 1; } setSongInfo(i); } function nextSong() { i++; if (i >= songsLength) { i = 0; } setSongInfo(i); } songTitle.textContent = songs[0].title; songArtist.textContent = 'Artist: ' + songs[0].artist; songAlbum.textContent = 'Album: ' + songs[0].album; songYear.textContent = 'Year of release: ' + songs[0].year; btnPrev.addEventListener('click', previousSong); btnNext.addEventListener('click', nextSong);

And here is the HTML and CSS code:

<!DOCTYPE html> <html lang="eng"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>YouTube Player</title> <link href="../css/style.css" rel="stylesheet" type="text/css" media="all"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Pixelify+Sans:[email protected]&family=VT323&display=swap" rel="stylesheet"> <style> #mp3_purple, h1, button { color: var(--dark_purple); } #mp3_purple { display: grid; grid-template-columns: 1fr 1fr; background-color: var(--white); width: 850px; height: 350px; border: 0.3em solid var(--dark_purple); padding-left: 1em; } section:nth-child(2) { display: flex; flex-flow: column wrap; justify-content: center; align-items: center; gap: 0.5em; } #yt_video { width: 100%; height: 65%; } #info span { display: block; text-align: center; } h1 { margin-left: 0; text-shadow: none; -webkit-text-stroke: 0; text-align: left; } #listened { width: 80%; } #time_indic { display: flex; flex-flow: row nowrap; justify-content: space-between; } #listened progress { width: 100%; } progress { height: 5px; border-radius: 0; } button { background: none; border: none; } h1, button { font-size: 2em; } #volume { align-self: flex-start; padding-left: 2em; display: flex; flex-flow: row nowrap; align-items: center; } #volume button, #volume_bar { font-size: 0.6em; } </style> </head> <body> <div id="mp3_purple"> <section> <h1>Song title</h1> <div id="yt_video"></div> </section> <section> <div id="info"> <span id="artist">Artist:</span> <span id="album">Album:</span> <span id="release_year">Year of release:</span> </div> <div id="listened"> <progress max="100" value="50"></progress> <div id="time_indic"> <span id="song_start">00:00</span> <span id="song_finish">00:00</span> </div> </div> <div> <button id="previous">⏮</button> <button id="toggle">▶</button> <button id="next">⏭</button> </div> <div id="volume"> <button id="volume_button">🔈</button> <progress id="volume_bar" max="100" value="50" style="display: none;"></progress> </div> </section> </div> <script src="playlist.js"></script> </body> </html>
Read Entire Article