This has been bugging me for a while now, I am using this generic script to create a player
var player = new YT.Player(videoArray[0], { videoId : videoArray[0], events : { 'onStateChange' : onPlayerStateChange } });
I have the callback function set up with just a simple console.log the problem is when I change the state of a player the console throws
https://www.youtube.com/get_video?noflv=1&video_id=ghUA.... GET 404 from the file html5player-en_US-vfloyxzv5.js:39 witch I asume is loaded by the YouTube Iframe API.
Any ideeas or posibile solutions will be greatly apreciated.
Sadly, this is one of the numerous little things you'll have to cope with using the Youtube Player API. I don't think there is any solution, and we can only wait for a Youtube fix.
A bug report has already been created, feel free to vote for it.
Youtube player is updated every tuesday. Hopefully, this will be fixed someday.
I found out what I was doing wrong, I am posting this maybe it will help someone along the way.
Since the videoArray was holding jQuery object, I used this piece of code to get it all working.
if(isYouTubeVideo) {
videoID = iframeSrc.substr(baseUrlLength);
}
videoArray[i] = {};
videoArray[i].id = videoID;
jQuery.ajax({
dataType: 'JSON',
url: 'https://gdata.youtube.com/feeds/api/videos/' + videoID + '?v=2&alt=json'
})
.done(function(data) {
videoArray[i].title = data.entry.title.$t;
});
jQuery(this).attr('id', videoID);
playerArray[i] = new YT.Player(videoArray[i].id, { event : //Events here})
I hope this helps someone :)
I get this for certain videos. In my experience, the get_video 404 doesn't matter - the video still loads correctly.
There is one random caveat though; if you're running this on an iPhone connected to Mac Safari Web Inspector, the 404 causes the video to stop loading. This caused me hours of fun!
Related
Solved this myself and it made me feel silly. What I was looking to do is not properly referenced in the API article. Giving the solution for others looking to achieve this.
The solution is:-
I've found the solution myself and boy do I feel silly. It's not referenced correctly in the YouTube Player API.
After many hours of playing with it, here is the solution.
// Skip dead videos
function onPlayerError(event) {
window.location.reload(true);
}
This requires you have the following in the YouTube Player calls:-
'onError' : onPlayerError
I am loading an array of video id's into the player, sometimes thousands (randomly). I have been trying to figure out a way to reload the page if x video shoots out an error.
The YouTube Player API lists only a couple error codes:-
https://developers.google.com/youtube/iframe_api_reference#Events
However, this does not cover private/copyright videos.
As is when a video ends I reload the page to randomly load a new video with:-
function onPlayerStateChange(event) {
if(event.data === 0) {
window.location.reload(true);
}
}
I have tried the below to no avail:-
// skip copyright videos
function onPlayerError(errorCode) {
if(errorCode == auth) {
window.location.reload(true);
}
}
The error code here is what I pulled out of the debug info for a copyright video (its the same for private). However, this is not in the API, thus does not work.
I also tried the following:-
// skip by numeric code
function onPlayerError(errorCode) {
if(errorCode == 100) {
window.location.reload(true);
}
}
Which is a valid error code and should work, but doesn't seem to want to.
I've tried a few other methods as well thinking I could read the API info and force a function, seems not. Have also tried fiddling with PlayerState.
Before anyone asks. No, I cannot use playlist embeds.
If anyone could help out, I'd really appreciate it!
Thanks
I'm new to javascript and I've created a kinda successful extension on chrome for dubtrack I've been trying to figure out for quite awhile how to make my injected script run in real time and grab the latest youtube music video url any help would be much appreciated my extension is very basic and it's not for profit I just made it to play around with javascript and jquery.
Here's the section of code that I'd like to have function in real time.
$('#grab').click(function() {
function getId(url) {
var regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
var match = url.match(regExp);
if (match && match[2].length == 11) {
return match[2];
} else {
return 'error';
}
}
src = $('iframe').attr('src');
setInterval(function() {
src = $('iframe').attr('src');
}, 10000);
window.open('http://youtubeinmp3.com/fetch/?video=http://www.youtube.com/watch?v=' + getId(src), '_blank');
});
Relevant links
GitHub
Chrome Extension
Thank you for taking the time to read my question.
You're bad at explaining (and might want to edit the question to reflect what you want), but basically the problem is this:
You have a YouTube embed in the page, with a particular video ID in src.
When the video changes, that happens without updating the src (by using YT embed API).
Therefore, if you try to grab just the src, it's not the latest video but the first you loaded.
As an extension, I see two ways of trying to solve it:
You could try to initialize the YT API yourself to get a player reference. I don't know if it will break the code of Dubtrack.
You could inject a script in the iframe as well that would somehow extract the video being played in a way other than relying on src.
It's an open problem how to solve it, and the fact that you're basically providing "just" a bookmarklet may be an obstacle.
Basically I want the user to record a sound with the SoundCloud recorder and once they click save, the sound they just recorded will be embedded on to my webpage.
I use the SC.record() method to get the recording. This is my function for where I save the recordings... Right now nothing is embedded when I try to run it
$('#save a').click(function(e) {
var currentURL ="";
e.preventDefault();
SC.connect({
connected: function() {
$('.status').html('Uploading...');
SC.recordUpload({
track: {
title: 'whatever',
sharing: 'public'
}
}, function(track) {
currentURL = '"'+track.permalink_url+'"';
$('#SCtracks').append('<li id='+currentURL+'>'+currentURL+'</li>');
SC.oEmbed(currentURL, {color: "ff0066"}, document.getElementById(currentURL));
});
}
});
});
But if I go in and call SC.oEmbed with a URL to a recording I made earlier it works fine.
So I think I might be trying to embed the recording before it is fully uploaded, but I don't know where else I could put that statement.
Thanks
This answered my question. I guess you have to just keep checking the state until it is for sure done. If someone know a quicker way please answer
okay So I'm trying to leverage the video.js project as it's seems pretty amazing!
anyways, im writing my first script that interacts with the api which can be found below. it's basically just supposed to output the current play time to the div current_time , the id of video tag is my_stream anyways here's all my javascript ... the problem im having is playLength=0 and current time never updates when video is playing and remains at 0 (ie. is never more then 0 ) im not sure what im doing wrong here ... the api rules i followed can also be found here video.js api docs
function current_time(){
_V_("my_stream").ready(function(){
var myPlayer = this;
// EXAMPLE:
var playLength = myPlayer.duration();
do
{
var position = myPlayer.currentTime();
var myTextArea = document.getElementById('time_count');
myTextArea.innerHTML = position;
}
while(position < playLength);
});
}
window.onload = current_time
anyhelp from any one who's implemented anything with the api or just see something dumb i've done would be greatly appreciated, thanks!
You're assigning the duration to playLength before playback begins. If that's zero when you assign it, it will remain zero. Check the note in the API doc "NOTE: The video must have started loading before the duration can be known, and in the case of Flash, may not be known until the video starts playing."
It looks like you're only concerned about the duration to work out when the video is playing. It would be far better just to use the timeupdate event instead.
var myPlayer;
var myTextArea = document.getElementById('time_count');
videojs('my_stream').ready(function(){
myPlayer = this;
myPlayer.addEvent('timeupdate', onProgress);
});
function onProgress() {
myTextArea.innerHTML = myPlayer.currentTime();
}
This should execute after the DOM has loaded (with window.onload, or jQuery's $(document).ready()), or go in a script tag in the body after the video and #time_count elements.
I Have sort-of solved this problem bymyself by modifying the code I Had written so it now works like so
function current_time(){
_V_("my_stream").ready(function(){
var myPlayer = this;
var playLength = myPlayer.duration();
var position = myPlayer.currentTime();
var myTextArea = document.getElementById('time_count');
myTextArea.innerHTML = position + "/" + playLength;
t=setTimeout(function() {current_time()},2000);
});
}
... although it seems stupid to poll duration continuosly, I actually don't need this value going forward in development, however both populate properly now once the video is playing so it's kinda a solution. I'm not going to except my own answer right away to see if anyone can solve this a better way, or if you can explain why video.js changes the id tag and how to properly deal with it i'll give you an up vote and accept your answer if it all makes sense to me.
Help, please? It appears that my callback function isn't being called...back. I'm using jQuery, and Flash 8. To access the Flash object, I'm using the jquery swfobject plugin, c.f. (http://jquery.thewikies.com/swfobject/examples). If you think that I'm not accessing the SWF properly in the first place, please recommend code as to how I would do that. Thanks!
JavaScript Code:
$("#songplayer").flash("callCueSong(" + songid + ")");
Flash Code:
import flash.external.*;
ExternalInterface.addCallback('callCueSong', null, cueSong);
stop();
pause = false;
pp_btn.hitArea = pause_hit_area;
love_btn.hitArea = love_hit_area;
_root.display_txt.backgroundColor = 0xffffff;
function cueSong(songid) {
trace('Cueing track ' + songid);
_root.sid = songid;
_root.sound_mc.songStarter('sent', false);
}
MovieClip.prototype.songStarter = function(next_direction, feedback) {
// code goes here
}
My code was working. I was simply uploading the wrong SWF, and not publishing to the right location. I discovered it by putting the following debug code, uploading, and noting that although it appeared in the local debug console, it did not appear in Flash Tracer
trace("Availability: " + ExternalInterface.available);
Also, I changed security on the Flash. In the HTML, I put "AllowScriptAccess" as "always", and in the SWF, I put:
System.security.allowDomain('http://www.mydomain.com', 'http://mydomain.com', 'mydomain.com', 'amazonaws.com');
Thanks for looking! Hope you have luck in the future.