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!
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.