Search code examples
youtubeyoutube-apiyoutube-data-apiyoutube-javascript-apiyoutube-iframe-api

Why are embedded Youtube videos saying Video Unavailable when they were working last week? No code changes and Youtube Data V3 API


I am streaming a bunch of music videos from my webpage.

I wrote a script to pick Youtube music videos that would be available for streaming. I used requests.get(url).json() to get a json of information for each video and then from there used this line of code

if url_get.json()['items'] != [] and url_get.json()['items'][0]['status']['uploadStatus'] == "processed" and url_get.json()['items'][0]['status']['embeddable'] == "true":

to decide if the Youtube video is streamable and I can embed it.

However, no matter which video I embed first, it's showing up as Video Unavailable when I test my webpage.

The same webpage code was actually working well last week. The script I kept changing.

I am not giving any API key to Youtube when embedding and streaming from my webpage, so I'm wondering why I'm still getting Video Unavailable despite having a check for if it's "embeddable" and "processed".

This is the relevant part of the script that I'm using:

#takes all files and checks if available to stream on youtube
ids = [id.strip("_arousal.csv") for id in glob.glob("*_arousal.csv")]
available_ids = []
unavailable_ids = []

for i in ids:
    url = f'https://www.googleapis.com/youtube/v3/videos?id={i}&part=status&key={your_api_key}'
    url_get = requests.get(url)
    print(url_get.json())
    if url_get.json()['items'] != [] and url_get.json()['items'][0]['status']['uploadStatus'] == "processed" and url_get.json()['items'][0]['status']['embeddable'] == "true":
        assign_score(i)
        available_ids.append(i)
    else:
        unavailable_ids.append(i)  

Here is the code that loads in the Youtube videos on my webpage:

  //-------------------------- step 3: instantiating javascript objects, data collection

  // 2. This code loads the IFrame Player API code asynchronously.
  var tag = document.createElement('script');

  tag.src = "https://www.youtube.com/iframe_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  // 3. This function creates an <iframe> (and YouTube player)
  //    after the API code downloads.
  var players = [];
  var i;
  function onYouTubeIframeAPIReady() {
    for (i = 0; i < num_media; i++) {
      if (document.getElementById('video_'+i.toString()) != null) {
        let end_time = 60; //show first minute, or for debugging purposes 10s
        if (randomized[i][1] < 60) {
          end_time = randomized[i][1]; //unless video is shorter than a minute
        }
        players.push(new YT.Player('video_'+i.toString(), {
          height: '315',
          width: '420',
          videoId: randomized[i][0],
          playerVars: {'controls':0, 'autoplay':0, 'fs':0, 'end': end_time},
          events: {
            'onError':onPlayerError,
            'onStateChange':onPlayerStateChange
          }
        }));
      } else {
        //music at trial i, just leave player[i] blank
        players.push(null);
      }
    }
  }

  //player.getDuration()?
  function onPlayerStateChange(event) {
    let id = event.target.getIframe().id.split("_")[1]; //string
    let num = parseInt(id, 10); //int
    let canvas = canvases[num];

    if (event.data == YT.PlayerState.ENDED) {
      clearInterval(canvas.data_collection);
      //double clearing the interval, b/c couldn't find documentation about what data_collection is set to after clearInterval
      canvas.data_collection = null;
      canvas.start_time = null;
      let stringv = "";
      let stringa = "";
      for (var i = 0; i < canvas.valences.length; i+=1) {
        stringv = stringv.concat(canvas.valences[i].join(',') + ";");
      }
      stringv.trimRight(";");
      for (var i = 0; i < canvas.arousals.length; i+=1) {
        stringa = stringa.concat(canvas.arousals[i].join(',') + ";");
      }
      stringa.trimRight(";");
      $( "#valences_"+id).attr('value', stringv);
      $( "#arousals_"+id ).attr('value', stringa);
      showSubmit(num);
    } else if (event.data == YT.PlayerState.BUFFERING) {
      clearInterval(canvas.data_collection); //don't record
      //double clearing the interval, b/c couldn't find documentation about what data_collection is set to after clearInterval
      canvas.data_collection = null;
    } else if (event.data == YT.PlayerState.PLAYING && canvas.data_collection == null) {
       //may need to check start_time and devise a timeout that would shift the sample to right times
       if (canvas.start_time == null) {
         canvas.start_time = new Date();
       }
       //setInterval doesn't record starting element, so I do that here
       canvas.valences.push([0, canvas.outputX]);
       canvas.arousals.push([0, canvas.outputY]);
       canvas.data_collection = setInterval(function(){ logKey(num); }, 500);
    } else if (event.data == YT.PlayerState.CUED) {
      //cued doesn't seem to be getting called
      canvas.start_time = new Date();
      canvas.valences.push([0, canvas.outputX]);
      canvas.arousals.push([0, canvas.outputY]);
      canvas.data_collection = setInterval(function(){ logKey(num); }, 500);
    } else if (event.data == YT.PlayerState.PAUSED) {
      //forces the user to keep watching and rating - no pauses allowed! :D
      event.target.playVideo();
    }

  }

  //throw out data if there is a player error???
  function onPlayerError() {
    let num = parseInt(event.target.getIframe().parentNode.split("_")[1], 10); //int
    let canvas = canvases[num];
    canvas.valences = [];
    canvas.arousals = [];
  }

Please let me know any advice on why the videos are still showing up as Video Unavailable. Thanks!


Solution

  • Usually, when a code was working and suddenly the YouTube Data API stops working correctly, the best option is report such problem in Issue Tracker - that's due it might some undocumented changes made in the API.

    Also, did you check in the browser if such videos are indeed unavailable? - sometimes, some videos are changed its properties and the API might not be updated or the user who owns the video decides allow (or not) embed its videos.