- 7 Tem 2013
- 8,205
- 685
Today we are going to make a jQuery plugin which uses YouTube's chromeless player, and creates our own set of minimalistic controls, which allows for perfect integration with your designs. The supported controls include a Play/Pause/Replay button, and a clickable progress bar.
The plugin is going to use YouTube's gdata api to determine whether embedding has been allowed for the video, and fetch extensive information about it, such as title, description, tags, screenshots & more, which you can use to improve the plugin.
Using the plugin to embed videos is extremely easy:
You can also specify a width for the embedded video (the height will be calculated automatically depending on the aspect ratio), and choose to disable the progress bar:
You can grab the plugin from the download button above, and start with the first step.
Step 1 - XHTML
Our plugin depends on jQuery SWFObject to embed the SWF files in the page. Below you can see the combined markup that is generated by both of the plugins.
youtube-player.html
The .flashContainerDiv is dynamically created by the plugin for each video on the page. It is populated with the embed code generated by SWFObject, the .controlDiv (which acts as a play/pause button) and the progress bar.
As mentioned above, the insertion of the player itself is handled by the SWFObject plugin. Depending on the browser, it can output either an object element, or a non-standard embed element for IE. This lifts the burden from us and allows us to concentrate on tasks such as querying YouTube's APIs and building the player controls.
Step 2 - jQuery
The plugin's code is located in the youTubeEmbed-jquery-1.0.js file. However, before being able to use it, you need to include the latest version of the jQuery library in the page, along with the jQuery SWFObject plugin and lastly script.js, which inserts two videos in the demonstration page and handles the submissions of the preview form.
Before we start digging into the player plugin's code, lets take a look at a sample response from YouTube's gdata api. It can give you a lot of useful information about a video, including duration, access control (both of which used by the plugin) and all sorts of additional data such as title, description, tags, screenshots and more.
Sample JSON response
All the fields of this response objects are available as properties in the data variable (data.fieldname). You could potentially modify the plugin to show the title with a link to the video page on youtube, or show the rating of the video.
Now lets dive directly into the script's source code.
youTubeEmbed-jquery-1.0.js - Part 1
settings.height = Math.round(settings.width*settings.ratio);
We start by defining our script as a jQuery plugin by adding it as a function to the $.fn object. To make the code easier to follow and read, I put all the elements of the page, such as the control and the progressBar divs in a structure called elements.
After extracting the id of the video (a unique 11 character sequence after the ?v= parameter), we send a JSONP request to youtube's gdata API. Depending on whether such a video exists, and on whether embedding is allowed on it, we proceed with calculating the aspect ratio. The height of the video is calculated by using this ratio and multiplying it to the width.
youTubeEmbed-jquery-1.0.js - Part 2
The plugin is going to use YouTube's gdata api to determine whether embedding has been allowed for the video, and fetch extensive information about it, such as title, description, tags, screenshots & more, which you can use to improve the plugin.
Using the plugin to embed videos is extremely easy:
Kod:
// Embed a video into the #player div:
$('#player').youTubeEmbed('http://www.youtube.com/watch?v=u1zgFlCw8Aw');
// Chaining is also supported:
$('#player').youTubeEmbed('http://www.youtube.com/watch?v=u1zgFlCw8Aw');
.youTubeEmbed('http://www.youtube.com/watch?v=AsdfFdwlzdAw');
You can also specify a width for the embedded video (the height will be calculated automatically depending on the aspect ratio), and choose to disable the progress bar:
Kod:
$('#player').youTubeEmbed({
video : 'http://www.youtube.com/watch?v=u1zgFlCw8Aw',
width : 600, // Height is calculated automatically
progressBar : false // Hide the progress bar
});
Step 1 - XHTML
Our plugin depends on jQuery SWFObject to embed the SWF files in the page. Below you can see the combined markup that is generated by both of the plugins.
youtube-player.html
Kod:
<div class="flashContainer" style="width: 640px; height: 360px;">
<object height="360" width="640" id="video_26ELpS3Wc4Q" type="application/x-shockwave-flash"
data="http://www.youtube.com/apiplayer?enablejsapi=1&version=3">
<param value="always" name="allowScriptAccess">
<param value="transparent" name="wmode">
<param value="video_id=26ELpS3Wc4Q&playerapiid=26ELpS3Wc4Q"
name="flashvars">
<param value="http://www.youtube.com/apiplayer?enablejsapi=1&version=3"
name="movie">
</object>
<div class="controlDiv play"></div>
<div class="progressBar">
<div class="elapsed"></div>
</div>
</div>
As mentioned above, the insertion of the player itself is handled by the SWFObject plugin. Depending on the browser, it can output either an object element, or a non-standard embed element for IE. This lifts the burden from us and allows us to concentrate on tasks such as querying YouTube's APIs and building the player controls.
Step 2 - jQuery
The plugin's code is located in the youTubeEmbed-jquery-1.0.js file. However, before being able to use it, you need to include the latest version of the jQuery library in the page, along with the jQuery SWFObject plugin and lastly script.js, which inserts two videos in the demonstration page and handles the submissions of the preview form.
Kod:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="jquery.swfobject.1-1-1.min.js"></script>
<script src="youTubeEmbed/youTubeEmbed-jquery-1.0.js"></script>
<script src="script.js"></script>
Before we start digging into the player plugin's code, lets take a look at a sample response from YouTube's gdata api. It can give you a lot of useful information about a video, including duration, access control (both of which used by the plugin) and all sorts of additional data such as title, description, tags, screenshots and more.
Sample JSON response
Kod:
{
"id": "u1zgFlCw8Aw",
"uploaded": "2008-03-05T01:22:17.000Z",
"updated": "2010-07-23T01:02:42.000Z",
"uploader": "GoogleDevelopers",
"category": "People",
"title": "The YouTube API: Upload, Player APIs and more!",
"description": "Listen to the YouTube APIs and Tools team talk about...",
"tags": ["youtube", "launch", "api", "engineering"],
"thumbnail": {
"sqDefault": "http://i.ytimg.com/vi/u1zgFlCw8Aw/default.jpg",
"hqDefault": "http://i.ytimg.com/vi/u1zgFlCw8Aw/hqdefault.jpg"
},
"player": {
"default": "http://www.youtube.com/watch?v=u1zgFlCw8Aw",
"mobile": "http://m.youtube.com/details?v=u1zgFlCw8Aw"
},
"content": {
"1": "rtsp://v4.cache5.c.youtube.com/CiILE..",
"5": "http://www.youtube.com/v/u1zgFlCw8Aw?f..",
"6": "rtsp://v3.cache4.c.youtube.com/CiILENy73.."
},
"duration": 259,
"********": "san bruno, ca",
"rating": 4.3,
"likeCount": "119",
"ratingCount": 144,
"viewCount": 251024,
"favoriteCount": 164,
"commentCount": 118,
"accessControl": {
"syndicate": "allowed",
"commentVote": "allowed",
"rate": "allowed",
"list": "allowed",
"comment": "allowed",
"embed": "allowed",
"videoRespond": "allowed"
}
}
Now lets dive directly into the script's source code.
youTubeEmbed-jquery-1.0.js - Part 1
Kod:
(function($){
$.fn.youTubeEmbed = function(settings){
// Settings can be either a URL string,
// or an object
if(typeof settings == 'string'){
settings = {'video' : settings}
}
// Default values
var def = {
width : 640,
progressBar : true
};
settings = $.extend(def,settings);
var elements = {
originalDIV : this, // The "this" of the plugin
container : null, // A container div, inserted by the plugin
control : null, // The control play/pause button
player : null, // The flash player
progress : null, // Progress bar
elapsed : null // The light blue elapsed bar
};
try{
settings.videoID = settings.video.match(/v=(\w+)/)[1];
// safeID is a stripped version of videoID,
// ready for use as a JavaScript function name
settings.safeID = settings.videoID.replace(/[^a-z0-9]/ig,'');
} catch (e){
// If the url was invalid, just return the "this"
return elements.originalDIV;
}
// Fetch data about the video from YouTube's API
var youtubeAPI = 'http://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc';
$.get(youtubeAPI,{'q':settings.videoID},function(response){
var data = response.data;
if(!data.totalItems || data.items[0].accessControl.embed!="allowed"){
// If the video was not found, or embedding is not allowed;
return elements.originalDIV;
}
// data holds API info about the video:
data = data.items[0];
settings.ratio = 3/4;
if(data.aspectRatio == "widescreen"){
settings.ratio = 9/16;
}
settings.height = Math.round(settings.width*settings.ratio);
We start by defining our script as a jQuery plugin by adding it as a function to the $.fn object. To make the code easier to follow and read, I put all the elements of the page, such as the control and the progressBar divs in a structure called elements.
After extracting the id of the video (a unique 11 character sequence after the ?v= parameter), we send a JSONP request to youtube's gdata API. Depending on whether such a video exists, and on whether embedding is allowed on it, we proceed with calculating the aspect ratio. The height of the video is calculated by using this ratio and multiplying it to the width.
youTubeEmbed-jquery-1.0.js - Part 2
Kod:
// Creating a container inside the original div, which will
// hold the object/embed code of the video
elements.container = $('<div>',{className:'flashContainer',css:{
width : settings.width,
height : settings.height
}}).appendTo(elements.originalDIV);
// Embedding the YouTube chromeless player
// and loading the video inside it:
elements.container.flash({
swf : 'http://www.youtube.com/apiplayer?enablejsapi=1&version=3',
id : 'video_'+settings.safeID,
height : settings.height,
width : settings.width,
allowScriptAccess:'always',
wmode : 'transparent',
flashvars : {
"video_id" : settings.videoID,
"playerapiid" : settings.safeID
}
});
// We use get, because we need the DOM element
// itself, and not a jquery object:
elements.player = elements.container.flash().get(0);
// Creating the control Div. It will act as a ply/pause button
elements.control = $('<div>',{className:'controlDiv play'})
.appendTo(elements.container);
// If the user wants to show the progress bar:
if(settings.progressBar){
elements.progress = $('<div>',{className:'progressBar'})
.appendTo(elements.container);
elements.elapsed = $('<div>',{className:'elapsed'})
.appendTo(elements.progress);
elements.progress.click(function(e){
// When a click occurs on the progress bar, seek to the
// appropriate moment of the video.
var ratio = (e.pageX-elements.progress.offset().left)/elements.progress.outerWidth();
elements.elapsed.width(ratio*100+'%');
elements.player.seekTo(Math.round(data.duration*ratio), true);
return false;
});
}