OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / docs / html / videos / index.jd
1 videos=true
2 page.title=Videos
3 @jd:body
4
5 <script src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js" type="text/javascript"></script>
6 <script src="{@docRoot}assets/jquery-history.js" type="text/javascript"></script>
7 <script type="text/javascript">
8 // for debugging in FF, so other browsers ignore the console commands.
9 var console;
10 if (!console) console = { 'log': function() {} };
11
12 /* This 'playlist' object defines the playlist IDs for each tab.
13  * Each name inside 'playlist' corresponds to class names for the tab that the playlists belong to (eg: "googleioTab" and "googleioBox" divs).
14  * Each string in 'ids' is the ID of a YouTube playlist that belongs in the corresponding tab.
15  */
16 var playlists = {
17   'googleio' : {
18     'ids': ["734A052F802C96B9"]
19   },
20   'about' : {
21     'ids': ["D7C64411AF40DEA5","611F8C5DBF49CEC6"]
22   },
23   'developertips' : {
24     'ids': ["43E15866EF0033A2"]
25   },
26   'developersandbox' : {
27     'ids': ["77426907BBAD558E"]
28   }
29 };
30
31 /* Some playlists include the title in the description meta-data, so we need to account for this when building the thumbnail lists, so we don't show the title twice
32  * This string is read via indexOf(), so multiple IDs need only be comma-separated in this string.
33  */
34 var playlistsWithTitleInDescription = "734A052F802C96B9";
35
36 /* This 'featured' object defines the Feature Videos list.
37  * Each playlist ID is paired with a custom video description.
38  */
39 var featured = {
40 // Android UI design patterns
41   'M1ZBjlCRfz0' : "The Android user experience team provides suggestions for how to make your applications more useable and engaging.",
42 // The world of ListView
43   'wDBM6wVEO70' : "ListView is a common widget that's customizable, but can be tricky to polish, so this talk shows how you can provide the best performance.",
44 // Debugging Arts of the Ninja Masters
45   'Dgnx0E7m1GQ' : "The Android SDK includes tools to debug your apps like a ninja. Enter the dojo and become a master at debugging your apps."
46 };
47
48 /* When an event on the browser history occurs (back, forward, load),
49  * load the video found in the URL hash
50  */
51 $(window).history(function(e, hash) {
52   if (location.href.indexOf("#v=") != -1) {
53     videoId = location.href.split("#v=");
54     clickVideo(videoId[1]); // click the link with a matching class
55   }
56 });
57
58 /* Load a video into the player box.
59  * @param id        The YouTube video ID
60  * @param title     The video title to display in the player box (character escaped)
61  * @param autoplay  Whether to automatically play the video
62  */
63 function loadVideo(id, title, autoplay) {
64   if($("." + id).hasClass("noplay")) {
65         console.log("noplay");
66         autoplay = false;
67         $("." + id).removeClass("noplay");
68   }
69   swfobject.embedSWF('http://www.youtube.com/v/' + id + '&rel=1&border=0&fs=1&autoplay=' +
70       (autoplay?1:0), 'player', '500', '334', '9.0.0', false, false, {allowfullscreen: 'true'});
71   $("#videoPlayerTitle").html("<h2>" + unescape(title) + "</h2>");
72
73   $.history.add('v=' + id); // add the current video to the browser history
74   document.getElementById("doc-content").scrollTop = 0; // scroll the window to the top
75 }
76
77 /* Draw all videos from a playlist into a 'videoPreviews' list
78  * @param data  The feed data returned from the youtube request
79  */
80 function renderPlaylist(data) {
81   var MAX_DESC_LENGTH = 390; // the length at which we will trim the description
82   var feed = data.feed;
83   var entries = feed.entry || [];
84   var playlistId = feed.yt$playlistId.$t;
85
86   var ul = $('<ul class="videoPreviews" />');
87
88   // Loop through each entry (each video) and add it to the 'videoPreviews' list
89   for (var i = 0; i < entries.length; i++) {
90     var entry = entries[i];
91
92     var title = entry.title.$t;
93     var id = entry.media$group.yt$videoid.$t;
94     var thumbUrl = entry.media$group.media$thumbnail[0].url;
95     var fullDescription = entry.media$group.media$description.$t;
96     var playerUrl = entry.media$group.media$content[0].url;
97
98     // Check whether this playlist includes the video title inside the description meta-data, so we can remove it
99     if (playlistsWithTitleInDescription.indexOf(playlistId) != -1) {
100       var lines = fullDescription.split("\n");
101       // If the first line includes the first 17 chars from the title, let's use the title from the description instead (because it's a more complete title)
102       // This accounts for, literally, "Google I/O 2009 -", which is (so far) the min AND max for properly identifying a title in the only playlist with titles in the description
103       if (lines[0].indexOf(title.slice(0,16)) != -1) {
104                         h3Title = "<h3>" + lines[0] + "</h3>";
105         if (lines[2].length < 30) lines = lines.slice(3);  // also, if the second line is very short (the speaker name), slice it out too
106         else lines = lines.slice(1);  // otherwise, slice after the first line
107       }
108       fullDescription = lines.join("");
109     }
110
111     var shortDescription = fullDescription.substr(0, MAX_DESC_LENGTH);
112     shortDescription += shortDescription.length == MAX_DESC_LENGTH ? "..." : ""; // add ellipsis if we've chopped the description
113
114     var img = $('<img src="' + thumbUrl + '" width="120" height="90"/>');
115     var a = $('<a class="' + id + '" href="#" onclick="loadVideo(\'' + id + '\',\'' + escape(title) + '\',true); return setSelected(this);" />');
116     var pShortDescription = $('<p class="short">' + shortDescription + '</p>');
117     var pFullDescription = $('<p class="full">' + fullDescription + '</p>');
118     var h3Title = "<h3>" + title + "</h3>";
119     var pToggle = "<p class='toggle'><a href='#' onclick='return toggleDescription(this)'><span class='more'>more</span><span class='less'>less</span></a></p>";
120     var li = $('<li/>');
121
122     li.append(a);
123     a.append(img).append(h3Title).append(pShortDescription);
124
125     // Add the full description and "more/less" toggle, if necessary
126     if (fullDescription.length > MAX_DESC_LENGTH) {
127         a.append(pFullDescription);
128         li.append(pToggle);
129     }
130
131     ul.append(li);
132   }
133
134   // Now add the 'videoPreviews' list to the page, and be sure we put it in the right tab
135   // This is the part that allows us to put multiple playlists in one tab
136   for (var x in playlists) {
137     var ids = playlists[x].ids;
138     for (var i in ids) {
139       if (ids[i] == playlistId) {
140         $("#"+x+"Box").append(ul);
141         break;
142       }
143     }
144   }
145 }
146
147 /* Draw a featured video into the existing 'videoPreviews' list
148  * @param data  The video data returned from the youtube request
149  */
150 function renderFeatured(data) {
151   var MAX_TITLE_LENGTH = 48;
152   var entry = data.entry || [];
153   var id = entry.media$group.yt$videoid.$t;
154   var description = featured[id];
155   var title = entry.title.$t;
156   var thumbUrl = entry.media$group.media$thumbnail[0].url;
157   var playerUrl = entry.media$group.media$content[0].url;
158
159   var ellipsis = title.length > MAX_TITLE_LENGTH ? "..." : "";
160
161   var h3Title = "<h3>"+ title.substr(0,MAX_TITLE_LENGTH) + ellipsis + "</h3>";
162   var img = $('<img src="' + thumbUrl + '" width="120" height="90"/>');
163   var p = $('<p>' + description + '</p>');
164   var a = $('<a class="' + id + '" href="#" onclick="loadVideo(\'' + id + '\',\'' + title + '\',true); return setSelected(this);" />');
165   var li = $("<li/>");
166
167   a.append(h3Title).append(img).append(p);
168   li.append(a);
169
170   $("#mainBodyRight .videoPreviews").append(li);
171 }
172
173 /* Request the playlist feeds from YouTube */
174 function showPlaylists() {
175   for (var x in playlists) {
176     var ids = playlists[x].ids;
177     for (var i in ids) {
178       var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/playlists/"
179                                   + ids[i] +
180                                   "?v=2&alt=json-in-script&callback=renderPlaylist'><\/script>";
181         $("body").append(script);
182     }
183   }
184 }
185
186 /* Request the featured videos from YouTube */
187 function showFeatured() {
188   for (var id in featured) {
189     var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/videos/"
190                                         + id +
191                                         "?v=2&alt=json-in-script&callback=renderFeatured'><\/script>";
192     $("body").append(script);
193   }
194 }
195
196 /* Reveal a tab (playlist) box
197  * @param name  The name of the tab
198  */
199 function showBox(name) {
200   $("#"+name+"Box").addClass("selected").siblings().removeClass("selected");
201   $("#"+name+"Tab").addClass("selected").siblings().removeClass("selected");
202   return false;
203 }
204
205 /* Highlight a video thumbnail, including all duplicates that there may be
206  * @param link  The link <a> object that was clicked
207  */
208 function setSelected(link) {
209   var videoId = $(link).attr("class");
210   if (videoId.indexOf("selected") != -1) {  // this means this video is already selected and playing, so bail out
211     return false;
212   }
213   $(".videoPreviews .selected").removeClass("selected");
214   $("a." + videoId).addClass("selected").each( function (i) {
215          if ($(this).is(":hidden")) {
216            var boxName = $(this).parent().parent().parent().attr("id").split("Box");
217            $("#"+boxName[0]+"Tab a").click();
218          }
219   });
220   return false;
221 }
222
223 /* Reveal and hide the long/short descriptions for a video in the playlist
224  * @param link  The link <a> object that was clicked
225  */
226 function toggleDescription(link) {
227         var aToggle = $(link);
228         $("span", aToggle).toggle();
229         var aDescription = $(">a", aToggle.parent().parent());
230         $("p.short", aDescription).toggle();
231         $("p.full", aDescription).toggle();
232         if ($("span.less", aToggle).is(":visible")) {
233                 aDescription.css("height", "auto");
234         } else {
235                 aDescription.css("height", "90px");
236         }
237         return false;
238 }
239
240 /* Add actions to the page onload event so that we load a video right away */
241 addLoadEvent(function () {
242   // if there's a video url in the hash, click that video
243   if (location.href.indexOf("#v=") != -1) {
244     var videoId = location.href.split("#v=");
245     clickVideo(videoId[1]);
246   } else { // otherwise, click the default video
247     clickDefaultVideo();
248   }
249 });
250
251
252 var clickVideoAttempts = 0; // Used with clickVideo()
253
254 /* Click a video in order to load it and select it
255  * @param videoId  The ID of the video to click
256  */
257 function clickVideo(videoId) {
258   if ($("." + videoId).length != 0) {  // if we find the video, click it and return
259    $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
260         $("." + videoId + ":first").click();
261          return;
262   } else { // if we don't find it, increment clickVideoAttempts
263          console.log("video NOT found: " + videoId);
264          clickVideoAttempts++;
265   }
266
267   // if we don't find it after 20 attempts (2 seconds), click the first feature video
268   if (clickVideoAttempts > 10) {
269          console.log("video never found, clicking default...");
270     clickVideoAttempts = 0;
271     clickDefaultVideo();
272   } else { // try again after 100 milliseconds
273          setTimeout('clickVideo("'+videoId+'")', 100);
274   }
275 }
276
277 /* Click the default video that should be loaded on page load (the first video in the featured list) */
278 function clickDefaultVideo() {
279         if ($("#mainBodyRight .videoPreviews a:first").length != 0) {
280         var videoId = $("#mainBodyRight .videoPreviews a:first").attr("class");
281     $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
282         $("." + videoId + ":first").click();
283         return;
284   } else { // if we don't find it, increment clickVideoAttempts
285          console.log("default video NOT found");
286          clickVideoAttempts++;
287   }
288
289   // if we don't find it after 50 attempts (5 seconds), just fail
290   if (clickVideoAttempts > 50) {
291           console.log("default video never found...");
292   } else { // try again after 100 milliseconds
293                 setTimeout('clickDefaultVideo()', 100);
294   }
295 }
296 </script>
297
298   <div id="mainBodyFixed">
299
300     <div id="mainBodyLeft" class="videoPlayer" >
301       <div id="videoPlayerBox">
302         <div id="videoBorder">
303           <div id="videoPlayerTitle"></div>
304           <div id="objectWrapper">
305             <object id="player"></object>
306           </div>
307         </div>
308       </div>
309     </div><!-- end mainBodyLeft -->
310
311     <div id="mainBodyRight" class="videoPlayer">
312       <h2>Featured Videos</h2>
313       <ul class="videoPreviews"></ul>
314     </div><!-- end mainBodyRight -->
315
316     <ul id="videoTabs">
317       <li id="aboutTab" class="selected"><a onclick="return showBox('about');" href="#">About the Platform</a></li>
318       <li id="developertipsTab"><a onclick="return showBox('developertips');" href="#">Developer Tips</a></li>
319       <li id="googleioTab"><a onclick="return showBox('googleio');" href="#">Google I/O Sessions</a></li>
320       <li id="developersandboxTab"><a onclick="return showBox('developersandbox');" href="#">Developer Sandbox</a></li>
321     </ul>
322
323     <div id="videos">
324       <div id="aboutBox" class="selected"></div>
325       <div id="developertipsBox"></div>
326       <div id="googleioBox"></div>
327       <div id="developersandboxBox"></div>
328     </div>
329
330   </div><!-- end mainBodyFixed -->
331
332 <script type="text/javascript">
333 // Initialization actions
334 showFeatured();            // load featured videos
335 showPlaylists();           // load playlists
336 </script>
337
338