Bones
Code Helper
Posts: 131
Bones said 0 great things
|
Post by Bones on Apr 9, 2011 17:24:07 GMT -8
Browsers Tested: Firefox, Internet Explorer, Chrome, Safari and Opera Edit: Didn't realize there were Proboards line wrapping issues with the posted code (lines too long) so fixed those and added in a missing swfobject dependency |
Description: This is an update to the original ytavatar code that ceased to work after Google acquired Youtube. Usage: Install in Global Footer then follow the instructions in the original code Example: If you wanted to use the video at http://youtube.com/watch?v=FB2WUSvQStg then the url to the default thumbnail for that video would be http://img.youtube.com/vi/FB2WUSvQStg/2.jpg. Set the height and width of the avatar as well since the video player will use those to define its own dimensions. All you need to do is take the ID of the video (the red part) and plug it into the image url to get the thumbnail. You could also try 1.jpg and 3.jpg to see if you like those images better but Youtube always uses 2.jpg which is usually a snapshot from a keyframe located in the middle of the video. You can also add extra videos that will play after the initial video by editing your website url field and adding v=videoID to the end of the url. Example:
- 1. main video I chose to use the "Kelly Rowland - Work" video (ht
tp://youtube.com/watch?v=FB2WUSvQStg) as my main avatar video so I plugged in the ID of the video into this url http://img.youtube.com/vi/FB2WUSvQStg/2.jpg to create my avatar image then set the width and height to 100.
- 2. extra videos I also wanted the "Mark Ronson - Just" video (ht
tp://youtube.com/watch?v=fxu5CUPRU-U) to play after the first video finished. Since I had no website set in my profile I used google.com/search (any will do) then added my second video like this http://google.com/search?v=fxu5CUPRU-U. If I wanted to add a third, fourth, etc I would keep adding: http://google.com/search?v=fxu5CUPRU-U&v=aeIOu123&v=BcDEf999
*If there is no "?" (question mark) in the url already then add one before adding your extra videos else just use an "&" (ampersand) when adding more videoIDs
Global Header<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> Global Footer<script> /* Youtube Avatar(updated Mar 20, 2011) - Eton */ /* GLOBAL FOOTER */ if(!window.AVATAR)window.AVATAR={}; if(!AVATAR.youtube)AVATAR.youtube={};AVATAR.youtube.downloaded={}; if(!AVATAR.youtube.plugins)AVATAR.youtube.plugins={preprocess:[],postprocess:[]} if(!window.console)window.console={log:function(){}, warn:function(){}, debug:function(){}, info:function(){}, error:function(){}, assert:function(){}}; window.console2= {debugLevel:(location.search.match(/\bytadebug=(\d+)/i)?parseInt(RegExp.$1):(document.cookie.match(/\bytadebug=(\d+)/i)? parseInt(RegExp.$1):-1)), levels:['log', 'error', 'warn','info', 'debug', 'assert']}; (function(){ var c=console2,d;c.deleg=function(){if(this<=c.debugLevel)console[c.levels[this]].apply(console,arguments);} for(d=0;c.levels[d];d++){c[c.levels[d]]=function(){c.deleg.apply(arguments.callee.d,arguments)};c[c.levels[d]].d=d;} })(); (function(){
var chromeless = { enabled:true ,url:"http://www.youtube.com/apiplayer?" ,play:"[play]" ,pause:"pause" ,mute:"[mute]" ,unmute:"unmute" ,volumeDown:"[-]" ,volumeUp:"[+]" ,volumeJump:10 ,playlistPrev:"[<<]" ,playlistNext:"[>>]" ,seperator:'\xa0' ,notify:{ enabled:true ,content:"<span style='font-size:150%;font-weight:bold;'>Now Playing (@category@) @duration@</span><div align='left' style='min-width:485px;max-width:560px;font-size:1em;max-height:550px;overflow:hidden;'>##selector##<br><div style='height:7px;background-color:transparent;width:100%;'><div style='height:7px;background-color:#FFE4C4;width:0%;' id='##ytid##_progressbar1'><div style='height:7px;background-color:red;width:0%;' id='##ytid##_progressbar'></div></div></div><img src='@thumbnail.sqDefault@' onload='this.style.display=(document.cookie.match(/noythqthumb=([^;]+)/)?RegExp.$1:\"inline\");' style='float:left;margin-right:4px;' title='[@id@]@tags@'><span style='background-color:#c9c9c;'>Views: @viewCount@<br>Favorites: @favoriteCount@<br>Rating: @rating@ (@likeCount@/@ratingCount@)<br>Comments: @commentCount@<br>Uploaded: @uploaded@<br>Uploader: <a target='_blank' href='http://www.youtube.com/user/@uploader@'>@uploader@</a><br>URL: <a target='_blank' href='@player.default@'>@title@</a></span><p style='clear:both;'>@description@</p></div>" ,duration:15000 } } var yt= window.AVATAR.youtube; yt.maxVideos=100 //maximum videos Youtube will send to an API client per segmented/single query (do not edit unless directed or have knowledge of a policy change) yt.videos={}; yt.currentDrop={id:'',index:0} yt.genID = function(){return arguments.callee.base+(arguments.callee.inc++);}; yt.genID.inc=0;yt.genID.base='youtubeAvatar'; yt.embeds={};yt.activePlayer=null; Date.prototype.setISO8601 = function (string) { var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" + "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" + "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"; var d = string.match(new RegExp(regexp));
var offset = 0; var date = new Date(d[1], 0, 1);
if (d[3]) { date.setMonth(d[3] - 1); } if (d[5]) { date.setDate(d[5]); } if (d[7]) { date.setHours(d[7]); } if (d[8]) { date.setMinutes(d[8]); } if (d[10]) { date.setSeconds(d[10]); } if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); } if (d[14]) { offset = (Number(d[16]) * 60) + Number(d[17]); offset *= ((d[15] == '-') ? 1 : -1); }
offset -= date.getTimezoneOffset(); time = (Number(date) + (offset * 60 * 1000)); this.setTime(Number(time)); } function count(o,i){var a,b=0,c=''; for(a in o){b++; if(i)c+=a+',';}if(c.length)console2.info(c);return b;} if(chromeless.enabled){ if(document.cookie.match(/\bytanopopup=1/))chromeless.notify.enabled=false; if(yt.plugins.preprocess.length) for(var a=0;a < yt.plugins.preprocess.length;a++) if("function" == typeof(yt.plugins.preprocess[a]))try{yt.plugins.preprocess[a],call(this)}catch(e){} window.onYouTubePlayerReady = function(playerId){ console2.debug('Processing %o ...',playerId); var ytPlayer = document.getElementById(playerId),a,b; AVATAR.youtube.activePlayer=ytPlayer; AVATAR.youtube.embeds[playerId]['obj']=ytPlayer; // ++++++++++++Status callback handler for this youtube player //unfortunate but YT JSAPI documentation only shows string param instead of function reference for callback (actionscript can use references wtf!!) window['on'+playerId+'Status']=function(sCode){ console2.debug('on'+arguments.callee.id+'Status() invoked') var ytp=document.getElementById(arguments.callee.id), ytc=document.getElementById(arguments.callee.id+"_control") ,ytemb=AVATAR.youtube.embeds[arguments.callee.id],playlist=ytemb['playlist'],states=['ended','playing','paused','buffering',,'cued'] if(!isNaN(sCode)){ytemb.state=sCode;console2.debug('%s event: video %s\nurl: %s',arguments.callee.id,((sCode==-1)?'Player Ready':states[sCode]),ytp.getVideoUrl());} switch(sCode){ case -1: //player loaded and ready case 0: //video ended if(playlist[ytemb.currentVideo+1]){ytemb.currentVideo++; }else{ ytemb.currentVideo=0;} AVATAR.youtube.currentDrop={id:arguments.callee.id+"_select",index:ytemb.currentVideo} AVATAR.youtube.loadVideo(arguments.callee.id); AVATAR.youtube.updCtrl('playlist',ytc.firstChild); break; case 1: //video playing if(!ytemb.playing){ytemb.playing=true; AVATAR.youtube.updCtrl('pause',ytc.firstChild);} if(ytemb.info && ytemb.info[playlist[ytemb.currentVideo]]) setTimeout(function(){ //innerHTML modifications to miniprofile by other codes can remove original control from DOM invalidating reference if(!ytemb.control || !ytemb.control.parentNode)ytemb.control=document.getElementById(ytemb.obj.id+"_control"); if(!(ytemb.control && ytemb.control.offsetWidth)){AVATAR.youtube.notify('Error getting video details');return} var o=ytemb.control; while(!(o.nodeName=="TD" && o.width=="20%" && o.nextSibling || o.nodeName=='BODY')) o=o.parentNode; AVATAR.youtube.currentDrop={index:ytemb.currentVideo,id:ytemb.obj.id+"_select"}; AVATAR.youtube.notify( AVATAR.youtube.showVideoInfo(playlist[ytemb.currentVideo]).replace(/##selector##/,ytemb.playlistdrop+'</select>').replace(/##ytid##/g, ytemb.obj.id), {timeout:chromeless.notify.duration,control:o.nextSibling} ) },2000); break; case 2: //video paused if(ytemb.playing){ytemb.playing=false; AVATAR.youtube.updCtrl('play',ytc.firstChild);} break; case 3: //video buffering break; case 4: //unknown break; case 5: //video cued if(!ytc){ var sep = chromeless.seperator; var ctrl=ytp.parentNode.insertBefore(document.createElement('div'),ytp.nextSibling); ctrl.innerHTML= '<a href="javascript:void(\'previous\')" onclick="AVATAR.youtube.prev(\''+ytp.id+'\',this)" title="previous video: '+playlist.length+' of '+playlist.length+'">'+chromeless.playlistPrev+'</a>'+sep +'<a href="javascript:void(\'play\')" onclick="AVATAR.youtube.play(\''+ytp.id+'\',this)">'+chromeless.play+'</a>' +'<a href="javascript:void(\'pause\')" onclick="AVATAR.youtube.pause(\''+ytp.id+'\',this)" style="display:none">'+chromeless.pause+'</a>'+sep +'<a href="javascript:void(\'next\')" onclick="AVATAR.youtube.next(\''+ytp.id+'\',this)" title="next video: 2 of '+playlist.length+'">'+chromeless.playlistNext+'</a>'+'<br>' +'<a href="javascript:void(\'volume down\')" onclick="AVATAR.youtube.volDown(\''+ytp.id+'\',this)" title="volume:'+ytp.getVolume()+'%" >'+chromeless.volumeDown+'</a>'+sep +'<a href="javascript:void(\'mute\')" onclick="AVATAR.youtube.mute(\''+ytp.id+'\',this)">'+chromeless.mute+'</a>' +'<a href="javascript:void(\'unmute\')" onclick="AVATAR.youtube.unmute(\''+ytp.id+'\',this)" style="display:none">'+chromeless.unmute+'</a>' +sep+'<a href="javascript:void(\'volume up\')" onclick="AVATAR.youtube.volUp(\''+ytp.id+'\',this)" title="volume:'+ytp.getVolume()+'%">'+chromeless.volumeUp+'</a>' ctrl.align="center"; ctrl.id= arguments.callee.id+"_control"; ytemb.control=ctrl; } break; default: /*Note: each player keeps own video playlist but to avoid duplicate requests each unique video is also added to a shared playlist@AVATAR.youtube.videos which serves as a cache(if metadata already downloaded use from cache instead of request on wire)*/ if(sCode.apiVersion && sCode.data){ console2.debug(arguments.callee.id+' received: %o',(sCode.data?(sCode.data.items?count(sCode.data.items):"["+sCode.data.id+"] "+sCode.data.title):(sCode.error?sCode.error.message:sCode))) if(sCode.data.items){ var videos,vidi for(var videos in sCode.data.items){ vidi=sCode.data.items[videos].video||sCode.data.items[videos]; AVATAR.youtube.videos[vidi.id]=vidi; if(!ytemb.info[vidi.id]){ ytemb.info[vidi.id]=vidi; ytemb.playlist.push(vidi.id); ytemb.playlistdrop+='<option value="'+vidi.id+'">'+vidi.title+'</option>'; } } if(ytemb.state==-1){ ytp.cueVideoById(ytemb.playlist[0],0,"default");ytemb.currentVideo=0;} console2.debug('playlist for %s : %o.count=%s',ytemb.obj.id,ytemb.playlist,ytemb.playlist.length); //maximum of 25 videos per call allowed, if more than 25 available then grab them (100 max ceiling) if(sCode.data.downloadedItems && sCode.data.totalItems && sCode.data.totalItems>sCode.data.downloadedItems && sCode.data.downloadedItems<AVATAR.youtube.maxVideos){ console2.debug('retrieving %s more videos for %s (videos %s - %s of %s)',sCode.data.itemsPerPage, arguments.callee.id, sCode.data.downloadedItems,(sCode.data.downloadedItems+ sCode.data.itemsPerPage),sCode.data.totalItems); //console2.log(sCode) AVATAR.youtube.downloadVideo(sCode.url,sCode.data.downloadedItems,arguments.callee.id); }else{ console2.debug('Finished downloading a total of %s out of %s',sCode.data.downloadedItems,sCode.data.totalItems,sCode) AVATAR.youtube.updPending(sCode.url); AVATAR.youtube.updCtrl('playlist',ytemb.control.firstChild); } }else{ //single video was requested ytemb.info[sCode.data.id]=sCode.data; AVATAR.youtube.videos[sCode.data.id]=sCode.data; ytemb.playlistdrop+='<option value="'+sCode.data.id+'">'+sCode.data.title+'</option>'; } } } } window['on'+playerId+'Status'].id=playerId; //closure erratic on callbacks in Safari so use prototype // +++++++++++++Errorhandler for this youtube player window['on'+playerId+'Error']=function(eCode){ var msg switch(eCode){ case 100: msg="video unavailable";break; case 101: case 150: msg="playback of this video disallowed for embedded players";break; default: msg="Error:"+eCode } var ytemb=AVATAR.youtube.embeds[arguments.callee.id],o=ytemb.control.offsetParent; if(!AVATAR.youtube.videos[ytemb.info[ytemb.playlist[ytemb.currentVideo]].id].status) AVATAR.youtube.videos[ytemb.info[ytemb.playlist[ytemb.currentVideo]].id].status={} AVATAR.youtube.videos[ytemb.info[ytemb.playlist[ytemb.currentVideo]].id].status.playFail=true; if(/Error:/.test(msg))AVATAR.youtube.notify(msg); else{ AVATAR.youtube.notify( AVATAR.youtube.showVideoInfo(ytemb.playlist[ytemb.currentVideo]).replace(/##selector##/,ytemb.playlistdrop+'</select>').replace(/##ytid##/g, ytemb.obj.id), {timeout:chromeless.notify.duration,control:o.nextSibling,error:msg} ); if(window.removePageSpan && ytemb.playing){ clearTimeout(removePageSpan); removePageSpan = setTimeout("window['on"+arguments.callee.id+"Status'](0)",3000); } } } window['on'+playerId+'Error'].id=playerId; //closure erratic on callbacks in Safari so use prototype //bind handlers ytPlayer.addEventListener("onStateChange", 'on'+playerId+'Status'); ytPlayer.addEventListener("onError", 'on'+playerId+'Error'); //load and download info for single-listed videos sourced from avatar and homepage if(AVATAR.youtube.embeds[playerId]['playlist'][0]){ AVATAR.youtube.embeds[playerId].currentVideo=0; ytPlayer.cueVideoById(AVATAR.youtube.embeds[playerId]['playlist'][0],parseInt(0),"default"); if(window.jQuery){ if(!AVATAR.youtube.embeds[playerId].info)AVATAR.youtube.embeds[playerId].info={}; for(a=0,b=window.AVATAR.youtube.embeds[playerId].playlist;a<b.length;a++){ if(!(window.AVATAR.youtube.videos[b[a]])){console2.log([playerId]+' fetching data for '+[b[a]]) var url="http://gdata.youtube.com/feeds/api/videos/"+b[a]+"?v=2&alt=jsonc"; if(!window.AVATAR.youtube.downloaded[url])AVATAR.youtube.downloadVideo(url,null,playerId) }else{ window.AVATAR.youtube.embeds[playerId].pending.push(b[a]) console2.log(playerId+' requesting CACHED data for '+b[a]) } } } } //download info for video lists saved on youtube (user favorites,user playlist,top_40, most_popular, etc.) var ytembed = window.AVATAR.youtube.embeds[playerId],ytname=ytembed.ytname,ytfave=ytembed.ytfave,ytplaylist=ytembed.ytplaylist,ytfeed=ytembed.ytfeed,vidurl console2.debug('%o video queue:%o.count=%s',playerId,ytembed.playlist,ytembed.playlist.length) if(window.jQuery && (ytfave || ytplaylist || ytfeed)){ if(ytname ) if(ytplaylist)ytplaylist = "playlists/"+ytplaylist+"?"; else if(ytfave) ytplaylist = "users/"+ytname+"/favorites?"; if(ytfeed) ytplaylist = "standardfeeds/"+ytfeed+"?"; vidurl="http://gdata.youtube.com/feeds/api/"+ytplaylist+"&v=2&alt=jsonc&format=5"; //check if not already downloaded or pending from a previous call to cut down network traffic if(!AVATAR.youtube.downloaded[vidurl]){ console2.log('%o fetching feed %s',playerId,vidurl); AVATAR.youtube.downloadVideo(vidurl,null,playerId); }else{ ytembed.pending.push(vidurl.split('?')[0]) console2.log('Skipped %o on %o (already downloaded)',vidurl,playerId); console2.debug('Pending queue updated for %o\n%o',playerId,ytembed.pending) } } } } yt.updPending= function (ident){ console2.info('Updating pendngs for resource:%o\nexists:%o',ident,!!AVATAR.youtube.downloaded[ident]) if(AVATAR.youtube.downloaded[ident]){ var embeds=AVATAR.youtube.embeds,embed, j for(var embed in embeds){ console2.info('Checking %o %o',embed,embeds[embed].pending); if(!AVATAR.youtube.downloaded[ident] || AVATAR.youtube.downloaded[ident].error){console2.error('[%o]Error retrieving cache data for %o',embed,ident);break;} for(j=0;j<embeds[embed].pending.length;j++){ if(embeds[embed].pending[j]==ident){console2.debug('Calling '+'on'+embed+'Status(%o,%o)',this,AVATAR.youtube.downloaded[ident]);window['on'+embed+'Status'].call(this,{apiVersion:2.0,data:AVATAR.youtube.downloaded[ident]});} } } } } yt.downloadVideo=function (url,startIndex,playerId){ var ac=arguments.callee; if(url && startIndex)url=url+(url.indexOf('?')==-1?'?&v=2&alt=jsonc&format=5':'')+'&start-index='+(startIndex+1); if(!url && startIndex && ac.url){ url=ac.url+'&start-index='+(startIndex+1); }else if(url){ac.url=url}else{console2.warn('Invalid Download URL:%s',url);return;} console2.log('JSONP request: %s',url,startIndex) if(!window.AVATAR.youtube.downloaded[url.replace(/&start-index=\d+/,'')]) window.AVATAR.youtube.downloaded[url.replace(/&start-index=\d+/,'')]={error:{message:"download pending",code:0}}; jQuery.ajax({ type:"GET", url:url, dataType:'jsonp', context:AVATAR.youtube.downloaded, beforeSend: function(xh){ xh.setRequestHeader("GData-Version", "2"); xh.setRequestHeader("Content-Type", "application/atom+xml"); xh.setRequestHeader("Accept-Language", "en-us,en; q=0.8"); xh.setRequestHeader("X-GData-Key", "key=AI39si4TkPy5j3_E-kKHx3hQIrzIZfbJ8qiPsA1_KpskkKcqrALLDzsWL3wyri2o5uVrwhIRcoyzYUCGYWLCY8kfsxpgmfwnog"); }, success: function(oJSON,status){ var jUrl=url.split('?')[0],iPaste,iCopy,vidCopy,vidPaste; console2.log('JSONP success received:%o',(oJSON.data?(oJSON.data.items?count(oJSON.data.items)+(oJSON.data.title?" items in "+oJSON.data.title:""):"["+oJSON.data.id+"] "+oJSON.data.title):(oJSON.error?oJSON.error.message:oJSON))); if(oJSON.error){AVATAR.youtube.notify('Error '+oJSON.error.code+' ('+oJSON.error.message+')'); console2.error('Error '+oJSON.error.code+' ('+oJSON.error.message+')'); return} if(!this[jUrl] || this[jUrl]&&this[jUrl].error){ this[jUrl]=oJSON.data; if(oJSON.data.items)this[jUrl].downloadedItems=Math.min(this[jUrl].totalItems,this[jUrl].itemsPerPage); }else{ vidCopy=oJSON.data; vidPaste=this[jUrl]; console2.debug('Combining %s new videos with %s videos already downloaded',count(vidCopy.items,1),count(vidPaste.items,1)); for(iCopy in vidCopy.items){ iPaste= vidCopy.items[iCopy].position?vidCopy.items[iCopy].position-1:count(vidPaste.items) vidPaste.items[iPaste]=vidCopy.items[iCopy]; vidPaste.downloadedItems++; } console2.debug('new total: %s',count(vidPaste.items,1)); vidCopy.downloadedItems=vidPaste.downloadedItems; } oJSON.url=url.split('?')[0]; window['on'+playerId+'Status'].call(AVATAR.youtube,oJSON); } }) } yt.load= function(){ if(location.search.match(/action=(display|search2|(user)?recent|(pm)?view|goto)/) && window.swfobject){ var mp=document.getElementsByTagName('td'),mplength=mp.length,av,embDIV,iter, iter1,iter2,id=[]; if((embDIV=document.getElementById('pagedropmenu'))) AVATAR.youtube.pageSpan={span:embDIV,onmouseout:embDIV.onmouseout,onmouseover:embDIV.onmouseover}; embDIV.style.margin="2px"; for(iter=0;iter<mplength;iter++){ if(mp[iter].width=="20%" && mp[iter].vAlign=="top" && (mp[iter].innerHTML.match(/Posts:\s\d/)||mp[iter].parentNode.className.match(/\btr_post\b/))){ if((av = mp[iter].getElementsByTagName('img')) && av[0]){ for(iter1 = av.length-1;iter1>=0;iter1--){ if(av[iter1].alt=='[avatar]'){ if(av[iter1].src.match(/img\.youtube\.com\/vi\/(.+?)\/\d\.jpg/i)){ embDIV=av[iter1].parentNode.insertBefore(document.createElement('div'),av[iter1]); embDIV.style.cssText="width:"+av[iter1].width+"px; height:"+av[iter1].height+"px; "; embDIV.id=yt.genID(); embDIV.appendChild(av[iter1]); yt.embeds[embDIV.id]={ obj:embDIV ,playlistdrop:"<select id='"+embDIV.id+"_select' onchange='var ay=AVATAR.youtube;ay.currentDrop.id=this.id; ay.index=this.options.selectedIndex; ay.goTo(\""+embDIV.id+"\",document.getElementById(\""+embDIV.id+"_control\").firstChild,this.selectedIndex)' style='width:100%'>" ,playlist:[] ,playing:false ,muted:false ,ytname:null ,ytplaylist:null ,ytfave:null ,ytfeed:null ,ytsearch:null ,pending:[] } yt.embeds[embDIV.id].playlist.push(RegExp.$1); for(iter2= av.length-1;iter2>=0;iter2--){ if(av[iter2].alt=='[homepage]' && av[iter2].parentNode.href && av[iter2].parentNode.href.split(/\b(yt)?[vnpfs]=/i).length){ av[iter2].parentNode.href.replace(/\b(v|yt[nfpsl])=([^&?]+)/gi,function(m,p,p1){ switch(p.toLowerCase()){ case 'v': yt.embeds[embDIV.id].playlist.push(p1); break; case 'ytn': //youtube username yt.embeds[embDIV.id].ytname=p1;break; case 'ytp': //playlist yt.embeds[embDIV.id].ytplaylist=p1; break; case 'ytf': //user favorites yt.embeds[embDIV.id].ytfave=p1; break; case 'yts': //standard feeds (top_rated,top_favorites,most_viewed,most_popular,most_recent,most_discussed, most_responded,recently_featured, watch_on_mobile) yt.embeds[embDIV.id].ytfeed=p1;break; case 'ytl': //search terms yt.embeds[embDIV.id].ytsearch=p1;break; } return m }); console2.debug('%o FEEDS:\n(youtubeUser:%o hasFavorite:%o hasPlaylist:%o hasStandardFeed:%o hasSearch:%o)',embDIV.id,yt.embeds[embDIV.id].ytname,yt.embeds[embDIV.id].ytfave,yt.embeds[embDIV.id].ytplaylist,yt.embeds[embDIV.id].ytfeed,yt.embeds[embDIV.id].ytsearch) break; } } swfobject.embedSWF((chromeless.enabled?chromeless.url:"http://www.youtube.com/v/"+id[0])+"&enablejsapi=1&playerapiid="+embDIV.id, embDIV.id, av[iter1].width, av[iter1].height, "8", //minimum flash version null, null, { allowScriptAccess: "always"}, { id: embDIV.id }, function(e){ if(e.success){ yt.embeds[e.id]['obj']=e.ref; }else document.getElementById(e.id).innerHTML+='<br>error'; } ); } break; } } } } } } } yt.notify=function(msg){ console2.assert(msg.length) var arg1=arguments[1],argdef={timeout:1500,control:AVATAR.youtube.embeds[AVATAR.youtube.activePlayer.id].control},x,y,id,progress if(arg1&&"object"==typeof arg1)for(x in arg1)argdef[x]=arg1[x]; if(!chromeless.notify.enabled && !argdef.force)return try{ if(window.removePageSpan)clearTimeout(removePageSpan); loadPageSpan(argdef.control,'',1,3); pageSpan.style.display="block"; pageSpan.innerHTML=msg; removePageSpan=setTimeout("pageSpan.style.display='none';",argdef.timeout); pageSpan.onblur=function(){hidePageSpan();} for(y=pageSpan.getElementsByTagName('*'),x=1;x<y.length;x++){ y[x].onmouseover=showPageSpan; //FIX THIS: not necessarily activePlayer if(y[x].nodeName=='SELECT' && y[x].id==AVATAR.youtube.currentDrop.id) y[x].options[AVATAR.youtube.currentDrop.index].selected=true; } if(msg.match(/((\w+?)_progressbar)/) && (id=RegExp.$2)){ var progress=document.getElementById(RegExp.$1),progressDL=document.getElementById(RegExp.$1+"1"); if(progress && progressDL){ if(arg1&&arg1.error){progressDL.style.height=progressDL.style.width=progressDL.parentNode.style.height ="auto";progressDL.innerHTML=arg1.error;return;} var ytembed = AVATAR.youtube.embeds[id]; console2.debug('Setting timer on %o',progress) setTimeout(function(){ var progressbar,progressbarDL if((progressbar=document.getElementById(id+"_progressbar")) && (progressbarDL=document.getElementById(id+"_progressbar1")) && window.pageSpan && pageSpan.offsetWidth>0){ var totalTime =ytembed.info[ytembed.playlist[ytembed.currentVideo]].duration; var currTime = document.getElementById(id).getCurrentTime(); var percentPlayed = Number(currTime/totalTime*100).toFixed(0)+"%"; var totalBytes = document.getElementById(id).getVideoBytesTotal(); var downloadedBytes = document.getElementById(id).getVideoBytesLoaded(); var startBytes = document.getElementById(id).getVideoStartBytes(); //console.log('totalTime:%o currTime:%o percentPlayed:%o totalBytes:%o downloadedBytes:%o startBytes:%o',totalTime,currTime,percentPlayed,totalBytes,downloadedBytes,startBytes) progressDL.style.marginLeft = startBytes/totalBytes*100+"%"; progressDL.style.width = Number(downloadedBytes/totalBytes*100).toFixed(0)+"%"; progress.style.width= percentPlayed;
if(!progressbarDL.parentNode.onclick){ progressbar.onmouseover = progressbarDL.onmouseover = function(){return this.style.cursor = "pointer";} progressbar.onmouseout = progressbarDL.onmouseout = function(){return this.style.cursor = "auto";} progressbarDL.parentNode.onclick = function(event){ var emb = AVATAR.youtube.embeds[progressDL.id.split('_')[0]].obj,u=emb.getDuration(),w=pageSpan.offsetLeft ,x=event.x||event.clientX, z=this.offsetParent; //console.log('w:%o x:%o u:%o',w,x,u);console.log('progressparent:%o pagespan:%o',this.offsetParent.offsetLeft,pageSpan.offsetLeft) if(!event.x){while((z=z.offsetParent) && z.id!="pagedropdown"){w+=z.offsetLeft;}x=x-w;}//else{x-=this.offsetLeft;} z = parseFloat(u*(x/this.offsetWidth)).toFixed(3); //console.log('click occurred at %o (relative:%o) of %o (%o%)\nrequesting %o of %o (factor:%o)',event.clientX,x,this.offsetWidth,x/this.offsetWidth,z,emb.getDuration(),z/emb.getDuration()) //console.log('event-x:%o mouse-x:%o totalwidth:%o totalVidTime:%o calculatedTime:%o currentVidTime:%o',event.clientX,x,this.offsetParent.offsetWidth,emb.getDuration(),z,emb.getCurrentTime()); if(z)return emb.seekTo(z,true) } } if(percentPlayed!="100%") arguments.callee.timer=setTimeout(arguments.callee,500); }else if(arguments.callee.timer)clearTimeout(arguments.callee.timer); },2000); } }else console2.error('Progressbar:'+id+"_progressbar"+' not found '); }catch(e){console2.error('pageSpan Notify: '+(e.message||e||'unknown'))} } yt.showVideoInfo=function(vID,raw,content){ if((vID=AVATAR.youtube.videos[vID])){ //ref:http://code.google.com/apis/youtube/2.0/developers_guide_jsonc.html content = content?content:chromeless.notify.content; var date={uploaded:1,updated:1} content = content.replace(/@([^@]+)@/g, function(m,p){ console.log('input:'+m); var s = p.split('.'),t=0,u,v=vID,dt=new Date(); for(;s[t],v[s[t]];t++){u=v=v[s[t]];}//console.log(s[t],u);} if(t==s.length){ if(date[s[s.length-1]] && !raw){dt.setISO8601(u); console.log('output:'+dt.toLocaleString());return dt.toLocaleString();} if(s[s.length-1]=='duration' && !raw)return (new Date(+new Date((new Date()).toLocaleDateString())+u*1000)).toTimeString().split(' ')[0].replace(/^00:/,''); if(/Count$/.test(s[s.length-1]) && !raw) return (function(n){ var o=String(n).match(/(\.\d+)/);m=parseInt(Number(n)); if(isNaN(m) || String(m).length<4)return n; m=String(m).split('').reverse().join(''); m=m.replace(/(\d{3})/g,"$1,"); console.log('output#:'+m.split('').reverse().join('').replace(/^,/,'')+(o?o[1]:'')) return m.split('').reverse().join('').replace(/^,/,'')+(o?o[1]:''); })(u) console.log('output:'+u);return u }else if(/Count$/.test(p) && !u && !raw) return '0'; else return m }); return "<img src='http://i51.tinypic.com/1z22h5j.gif' title='close popup' style='float:right;cursor:pointer' onclick='if(confirm(\"This will close the popup\\nSelect OK if you want to keep it closed\\nSelect CANCEL to close but allow future popups\")){document.cookie=\"ytanopopup=1;\"}pageSpan.style.display=\"none\";'><span style='margin:4px;'>"+content+"</span>"; }else return ''; } yt.updCtrl= function(state,ctrl){ console2.debug('Updating Control Panel with action: %o for %o',state,(ctrl&&ctrl.href?ctrl.parentNode.id:"null")) var CTRL=ctrl.parentNode.getElementsByTagName('a'),prev=0,play=1,pause=2,next=3,voldown=4,mute=5,unmute=6,volup=7; var ytEmb = AVATAR.youtube.embeds[ctrl.parentNode.id.split('_')[0]]; if(AVATAR.youtube.videos[ytEmb.playlist[ytEmb.currentVideo]] && AVATAR.youtube.videos[ytEmb.playlist[ytEmb.currentVideo]].status && AVATAR.youtube.videos[ytEmb.playlist[ytEmb.currentVideo]].status.playFail ) return window['on'+ctrl.parentNode.id.split('_')[0]+'Error'](100); switch(state){ case "mute": CTRL[mute].style.display="";CTRL[unmute].style.display="none";ytEmb.muted=false; break; case "unmute": CTRL[mute].style.display="none";CTRL[unmute].style.display="";ytEmb.muted=true; break; case "play": CTRL[play].style.display="";CTRL[pause].style.display="none"; ytEmb.playing=false;break; case "pause": CTRL[play].style.display="none";CTRL[pause].style.display="";ytEmb.playing=true; break; case "volume": CTRL[volup].title=CTRL[voldown].title = 'volume:'+AVATAR.youtube.activePlayer.getVolume()+"%"; this.notify(CTRL[volup].title,{control:ctrl}) break; case "playlist": var prevvid=ytEmb.currentVideo-1,nextvid=ytEmb.currentVideo+1 if(prevvid<0)prevvid=ytEmb.playlist.length-1; if(nextvid>=ytEmb.playlist.length)nextvid=0; CTRL[prev].title= ytEmb.info&&ytEmb.info[ytEmb.playlist[prevvid]]?ytEmb.info[ytEmb.playlist[prevvid]].title+' ('+(prevvid+1)+ ' of '+ ytEmb.playlist.length+')':'previous video: '+(prevvid+1)+ 'of '+ ytEmb.playlist.length; CTRL[next].title = ytEmb.info&&ytEmb.info[ytEmb.playlist[nextvid]]?ytEmb.info[ytEmb.playlist[nextvid]].title+' ('+(nextvid+1)+ ' of '+ ytEmb.playlist.length+')':'next video: '+(nextvid+1)+ 'of '+ ytEmb.playlist.length; break; } } yt.play = function(id,ctl){if((AVATAR.youtube.activePlayer=document.getElementById(id)))AVATAR.youtube.activePlayer.playVideo(); AVATAR.youtube.updCtrl("pause",ctl);} yt.pause = function(id,ctl){if((AVATAR.youtube.activePlayer=document.getElementById(id)))AVATAR.youtube.activePlayer.pauseVideo(); AVATAR.youtube.updCtrl("play",ctl);} yt.mute = function(id,ctl){if((AVATAR.youtube.activePlayer=document.getElementById(id)))AVATAR.youtube.activePlayer.mute(); AVATAR.youtube.updCtrl("unmute",ctl);} yt.unmute = function(id,ctl){if((AVATAR.youtube.activePlayer=document.getElementById(id)))AVATAR.youtube.activePlayer.unMute(); AVATAR.youtube.updCtrl("mute",ctl);} yt.volDown = function(id,ctl){if((AVATAR.youtube.activePlayer= document.getElementById(id))){ if(AVATAR.youtube.activePlayer.getVolume()- chromeless.volumeJump>0){AVATAR.youtube.activePlayer.setVolume( AVATAR.youtube.activePlayer.getVolume()- chromeless.volumeJump); AVATAR.youtube.updCtrl("volume",ctl);} } } yt.volUp = function(id,ctl){if((AVATAR.youtube.activePlayer= document.getElementById(id))){ if(AVATAR.youtube.activePlayer.getVolume()+ chromeless.volumeJump<=100){AVATAR.youtube.activePlayer.setVolume(AVATAR.youtube.activePlayer.getVolume()+ chromeless.volumeJump); AVATAR.youtube.updCtrl("volume",ctl);} } } yt.loadVideo = function(id){ var ytEmb=AVATAR.youtube.embeds[id]; if(!ytEmb){AVATAR.youtube.notify('Bad Player ID:'+id,{force:true});return;} if(ytEmb.playing) ytEmb.obj.loadVideoById(ytEmb.playlist[ytEmb.currentVideo],0,"default"); else{ ytEmb.obj.cueVideoById(ytEmb.playlist[ytEmb.currentVideo],0,"default"); } AVATAR.youtube.currentDrop.index=ytEmb.currentVideo; } yt.next = function(id,ctl){if((AVATAR.youtube.activePlayer=document.getElementById(id))){ if(AVATAR.youtube.embeds[id].playlist[AVATAR.youtube.embeds[id].currentVideo+1]) AVATAR.youtube.embeds[id].currentVideo++; else AVATAR.youtube.embeds[id].currentVideo=0; this.loadVideo(id) AVATAR.youtube.updCtrl("playlist",ctl); } } yt.prev = function(id,ctl){if((AVATAR.youtube.activePlayer=document.getElementById(id))){ if(AVATAR.youtube.embeds[id].currentVideo && AVATAR.youtube.embeds[id].playlist[AVATAR.youtube.embeds[id].currentVideo-1]) AVATAR.youtube.embeds[id].currentVideo--; else AVATAR.youtube.embeds[id].currentVideo= AVATAR.youtube.embeds[id].playlist.length-1; this.loadVideo(id); AVATAR.youtube.updCtrl("playlist",ctl); } } yt.goTo = function (id,ctl,index){if((AVATAR.youtube.activePlayer=document.getElementById(id))){ if(AVATAR.youtube.embeds[id] && index>=0 && index<AVATAR.youtube.embeds[id].playlist.length){ AVATAR.youtube.embeds[id].currentVideo=index; this.loadVideo(id); AVATAR.youtube.updCtrl("playlist",ctl); } } } yt.load(); })() </script> This update adds support for playing a user's favorites list or playlist as well as Youtube generated feeds such as (top_rated, top_favorites, most_viewed, most_popular, most_recent, most_discussed, most_responded, recently_featured) - to add a user's favorite list you would add
&ytn=username&ytf=1
- to add a user's playlistcompiled you would add
&ytn=username&ytp=playlistid (replace playlistid with the actual id of the playlist - e.g 7F6E927F8C9B2EB1)
- to play a standard youtube generated feed
&yts=feed_name (replace feed_name with one of the feed names listed above - e.g. top_favorites) TIP: to get a specific category of a feed (top_favorites music for example) then use top_favorites_Music
|
|