Quantcast
Channel: Active questions tagged youtube-api - Stack Overflow
Viewing all articles
Browse latest Browse all 3831

YouTube iframe API "player is undefined"

$
0
0

I am making an application which uses the YouTube API to gather a grid of videos from a search string. When a thumbnail is clicked, player.loadVideoByID should run, opening it in a previously defined iFrame. I'm using the player object instead of iframe directly, as I need the timestamps for future functionality (note-taking).

However, I get the error "Uncaught TypeError: player is undefined". Why is that? Function scope?

Here is the relevant HTML:

<!DOCTYPE html><html><head><title>YouTube API</title><link rel="stylesheet" href="style.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.min.css"><script type = "text/javascript">            function showNote() {                document.getElementById('note-container').style.display = "block";        }</script></head><body><div class="header"><br><h1>YouTube API Search</h1><div class="search-bar"><input type="text" id="search" placeholder="Search for videos"><input type = "image" src = "search.png" id = "search-button"></button></div><div id="keywordPopup" class="popup" style="display: none;"><br><input type="text" id="customKeyword" placeholder="Enter custom keyword"><button id="submitKeyword">Submit</button><button id="cancelKeyword">Cancel</button></div><div class = "addKeyword"><button id="addKeywordButton" class="add-button">+</button></div><div class="category-buttons"><button class="category-button" data-category="Software Quality Assurance">Software Quality Assurance</button><button class="category-button" data-category="Computing">Computing</button></div></div><div class = "content"><br><div class="row"><div class="col-md-12"><div id="videos"></div></div></div></div><div id="loading" style="display: none"><p>Loading...</p></div><div id="error" style="display:none"><p>An error occurred while fetching videos.</p></div><div id="videoScreen" class="screen"><div class="screen-content"><span class="close" onclick="closeVideo()">&times;</span><iframe id="videoFrame" width="560" height="315" src="" frameborder="0" allowfullscreen></iframe><p><a download="info.txt" id="downloadlink"><img src="save.png" alt="Download" width="60px" height="60px"></a></p><input type = "image" style="width:60px;height:60px;" src = "note.png" onclick = "showNote()" id = "note-opener"></button></div><!--<div id="note-container" style = "display:none;"><h2>Video Notes</h2><ul id="notes-list"></ul><div style="background-color: #fff"><input type="text" id="note-text" placeholder="Add note" /><button id="add-note">Add Note</button></div><div style="background-color: #fff"><select id="video-selector"></select><button id="load-video">Load Video</button></div></div>*--></div><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script><script src="https://www.youtube.com/iframe_api"></script><script src="ytsearch.js"></script></body></html>

Here is the relevant JS script (excluding note-taking):

$(document).ready(function(){    var API_KEY = "AIzaSyAYUJirQE2io-hjqAce9IJCQw9D-F6aFNk";       var selectedCategories = [];    $(".category-button").click(function () {        $(this).toggleClass("selected");        var categoryKeyword = $(this).data("category");        var $searchInput = $("#search");        if ($(this).hasClass("selected")) {           selectedCategories.push(categoryKeyword);        } else {            selectedCategories = selectedCategories.filter(item => item !== categoryKeyword);        }        var combinedCategories = selectedCategories.join(" ");        if (combinedCategories !== "") {            $searchInput.val(combinedCategories);        } else {            $searchInput.val("");        }    });    $("#search-button").click(function () {        var search = $("#search").val();        var videoDuration = "short";        videoSearch(API_KEY, search, 12, videoDuration);    });    function videoSearch(key, search, maxResults, videoDuration) {        var player;        function onYouTubeIframeAPIReady() {            player = new YT.Player('videoFrame', {            playerVars: {'playsinline': 1            },            events: {'onReady': onPlayerReady,                }            });          }           function onPlayerReady(event){               event.target.playVideo();           }        $("#videos").empty();        $.get("https://www.googleapis.com/youtube/v3/search?key=" + key+"&type=video&part=snippet&maxResults=" + maxResults +"&q=" + search +"&videoDuration=" + videoDuration,         function(data){            //populateVideoSelector(data.items);            var videosContainer = $("<div class='row'></div>");            console.log(data);            data.items.forEach(function (item, index) {                var videoColumn = $("<div class='col-md-4'></div>");                var videoContainer = $("<div class='video-container'></div>");                // Create an image or link to represent the video thumbnail and trigger the pop-up                var thumbnail = $("<img src='" + item.snippet.thumbnails.medium.url +"' alt='Video Thumbnail'>");                thumbnail.on("click", function () {                        player.loadVideoById(item.id.videoId)                        //openVideo("https://www.youtube.com/embed/" + item.id.videoId +"?enablejsapi=1");                          (function () {                            var textFile = null,                              makeTextFile = function (text) {                                var data = new Blob([text], {type: 'text/plain'});                                // If we are replacing a previously generated file we need to                                // manually revoke the object URL to avoid memory leaks.                                if (textFile !== null) {                                  window.URL.revokeObjectURL(textFile);                                }                                textFile = window.URL.createObjectURL(data);                                return textFile;                              };                                var link = document.getElementById("downloadlink");                                link.href = makeTextFile("https://www.youtube.com/embed/" + item.id.videoId)})()                });                var videoTitle = $("<p class='video-title'></p>");                videoTitle.text(item.snippet.title);                videoContainer.append(thumbnail);                videoContainer.append(videoTitle);                videoColumn.append(videoContainer);                videosContainer.append(videoColumn);                if ((index + 1) % 3 === 0) {                    $("#videos").append(videosContainer);                    videosContainer = $("<div class='row'></div>");                }            });            window.videoData = data;            if (videosContainer.children().length > 0){                $("#videos").append(videosContainer);            }        })    }    var videoScreen = document.getElementById("videoScreen");    var videoFrame = document.getElementById("videoFrame");    function openVideo(videoUrl) {        videoFrame.src = videoUrl;        videoScreen.style.display = "block";    }    function closeVideo() {        videoFrame.src = "";        videoScreen.style.display = "none";    }    var closeBtn = document.querySelector(".close");    closeBtn.addEventListener("click", closeVideo);    window.onclick = function(event) {        if (event.target === videoScreen) {            closeVideo();        }    }    $("#addKeywordButton").click(function (){        $("#keywordPopup").css("display", "block");    });    $("#cancelKeyword").click(function (){        $("#keywordPopup").css("display", "none");    });    $("#submitKeyword").click(function () {        var customKeyword = $("#customKeyword").val();        if (customKeyword.trim() !== "") {            var newCategoryButton = $("<button class='category-button' data-category='" + customKeyword +"'>" + customKeyword +"</button>");            newCategoryButton.click(function () {                $(this).toggleClass("selected");                var $searchInput = $("#search");                if ($(this).hasClass("selected")) {                    $searchInput.val(customKeyword);                } else {                    $searchInput.val("");                }            });            $(".category-buttons").append(newCategoryButton);            $("#customKeyword").val("");            $("#keywordPopup").css("display", "none");        }    })});

Thank you.


Viewing all articles
Browse latest Browse all 3831

Trending Articles