Jsconf 2011-us


Published on

The making of Yahoo!'s universal JavaScript player, by Dan Beam.

Published in: Technology
1 Comment
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • ‘ Sup guise. My name is Dan, and as you can by the liberal use of purple on my slides, I work for Yahoo!, haha. I ’ ll be giving a short presentation called “ How to be a player ... on the internet - the making of Yahoo! ’ s universal JS media player. ” So, let ’ s go.
  • First of all, what is Yahoo! Media Player? By a show of hands, has anybody heard of our player (or used it)? Cool. Because this is JSConf, I added a gist of how installation of the player should go...
  • Let ’ s do a quick demo now for those unfamiliar with our product, to see what it does for you. > Click link > Scroll down to third play button> Click in-page play button for Ben E. King: Stand by me> Seek to middle> Open 17. Atlas Sound> Find on page This is cool, but what if you want more customized experience? Don ’ t think we ’ ve forgotten about...
  • Developers! Our goal is to make our player hackable and as friendly to the developer community as possible.
  • The API we expose is an abstraction and common set of functionality we find useful for you to use the player in more advanced ways. We open up control of the playlist, player controls, view settings, engine ... pretty much everything, so feel free to change it ’ s behavior as much as you want. You can also just set a global environment variable that we listen to in order to change various aspects about your player (for instance, if it should automatically start playing or not). Let ’ s show a real quick demo I made to show some custom behavior. > Click link > Explain what we ’ re about to do (search YouTube, using our player to play links in page) This is an example of loading videos from YouTube based on a search parameter (so you ’ re doing it dynamically after the page is loaded -- so you ’ re not using the default parsing mechanism built in the player by default). > Play first entry for keyboard cat (original, preferably with sound, maybe seek?) > Do one more search (spiderman?) with the playlist open to show how we ’ re populating on every search
  • We also promote skinning of our player ’ s visual appearance (and a quite a few people do). We attempt to make things easily skinnable with either the replacement of our button sprite with a custom one or the easy use of CSS to do more advanced things (the new version of the player is highly CSS-ified, using CSS gradients, RGBA and hacks, and various ways of making skins easier to change for developers and designers). We also have plans to make a theme chooser in the future, so stay tuned for this.
  • Now let ’ s talk a little bit about our goals for this player in general, and what it strives to be.
  • Firstly, we want our player to basically be the easiest way to add audio and video to your site. With only 1 script tag we handle pretty much everything for you in an unobtrusive, efficient way. We host the files for you for free on a globally distributed CDN so you can sure it ’ s be fast and reliable. Another goal of ours is to change webpages into playlists, giving your user a richer and more delighting experience (which in turn makes you more money, :D).
  • You ’ ve probably heard of the terms localization, internationalization, well we also believe in universalization -- being able to use our player on any page with browser or device using type of media or service. Whether you ’ re a web ninja or not, our player should work seamlessly for you. Any browser, includes IE6 quirksmode and mobile. We try any available browser plugin in a large fallback chain (we ’ ll soon be looking for codec support and possibly a transcoding service as well).
  • So, let ’ s talk about how we go about supporting 60 combinations of browser, OS, and document mode. About Opera - technically, we don ’ t offer *as much* browser support (by Yahoo! ’ s Graded Browser Suport guidelines). However, though we ’ re not officially mandated to support it we attempt to do our best of the goodness of our hearts. <3 Opera
  • This a rich web application with tons of logic, so we chose to use a pseudo-classical inheritance model and a clear MVC separation. A lot of this is basically engine normalization and taming crazy browser quirks to accomplish the effects we want.
  • The engines we support don ’ t work exactly the same (some of them suck). Each engine names their events differently, fire these events at different times (if at all), and have quirks that we ’ ve come to know and love (or hate). This adapter pattern allows us to abstract all nitty gritty details.
  • This pattern allows each level of inheritance to abstract the functionality that other classes will need while putting for a standard interface. For instance, each component starts by inheriting from a base engine which basically allows them to publish and subscribe to events with some slight dependency injection in the middle. Then, each media engine inherits from an abstract engine class which requires features like play, pause, stop, or seek (if it ’ s supported). As we get more and more and more specific we allow a divergence from the ultra-generic to slightly more specific (i.e. video probably needs to be showing to be useful while playing, so the video engine overrides the base engine ’ s logic just a little bit here). This pattern works awesomely to allow us to drop in engines relatively quickly as well as tame bugs at any specific level (whether it be for 1 engine or all of them).
  • So another cool aspect of our player is that we have a fallback chain of supported plugins and media players that ’ s designed to give you the best experience possible using a number of environmental clues (operating system, browser, possibly bandwidth or device in the future).
  • A good example of us taking care of the logic for you are movie trailers. If we currently have “ automatic trailer finding ” built into our player to find a trailer for a movie you ’ ve linked to in a page (for now only with Yahoo! Movie Links, but we ’ ll support additional things in the future). So, if you simply reference a Yahoo! Movie page we ’ ll find the best trailer for the movie by querying Yahoo! Movies ’ API via YQL as well as searching YouTube ’ s gdata API (and using either respective player to play your movie).
  • But enough about us, on to you! One of the things I think is really cool about our player is that we go to great lengths to not conflict with your page ’ s scripts, styles, or performance. Let me take you through a couple of examples of how we avoid making your page anything but awesomer, :).
  • So, firstly, we namespace all our CSS with a common classname prefix (currently .ymp-, will likely change in next version). This helps avoid style collision, but we don ’ t stop there - to avoid both CSS and JS collision we don ’ t use IDs (in the new player) as they ’ re always global and we don ’ t want to limit ourselves to having to create dynamic IDs on the fly. We also like to reuse as much as possible from trusted codebases like YUI (for us, the YUI Slider widget), so we grab the corresponding CSS and namespace it with ant at build time using <fitlerchains> (glorified search and replace for our needs) as well as YUI ’ s CSS prefix mechanism (very cool). We also employ a contextual CSS reset. This is similar to those resets you ’ ve seen by Eric Meyer, YUI, or HTML5 doctor but only on a small portion of the page (to not mess up your styles and ensure ours are the same cross browser). We also do more than just normalize across all browsers. For the nodes inside our player we apply styles to override the use of globals styles like using only tag selectors (i.e. blink on anchor hover!).
  • We are also a little bit paranoid about protecting your JavaScript (after all, we make a living on it, too, :P). We don ’ t want to slow down your page, so we only bring the things we need with us (we seriously have to justify every byte and are crazy about reuse). During typical usage of just 1 <script> tag in your markup, we only embed a small script that decides whether or not to load additional assets and show a minimized version of the player. Dynamically adding a <script> tag also works for those needing to get to DOMReady/load as fast as possible. If the full player is embedded, these assets are cached forever making you pay no price on any site after (even blog to blog, Yahoo! property to Yahoo! property). We don ’ t modify JavaScript natives (like Array, Object, Date, etc.) like some libraries do, we shouldn ’ t conflict with any library (that we know of, not even YUI2 or YUI3 on the same page) and we only introduce 1 global (if it ’ s not already there) - YAHOO.MediaPlayer.
  • We minimize how many HTTP connections are required to get our assets to your page. One of the many optimizations we ’ ve done is building our minified CSS into a simple string in JavaScript. When the player is evaluated it creates a stylesheet dynamically and put the minified style string into that stylesheet. We do this from an ant target using YUICompressor and a template at build time. We also use CSS sprites (everybody should know about this) extensively, generally using only 1 or 2 images for all of the UI. We ’ re investigating using data URIs (for those browsers than can handle them) to put both background images and engines inline in our script to minimize these connections even more (though we have to make sure this actually doesn ’ t hurt if some things can be parallelized).
  • We query the whole document only once for the top level containers, then make relative DOM queries after that into each subtree. We cache a reference to the internal DOM queries so that we never need to get an element more than once during initialization. Event delegation is useful for things with many or an unknown number of items that need to be handled (i.e. play buttons, playlist items). It also catches or prevents the default for events that we might not want to flow up to the document (i.e. we don ’ t want to send your reader to the top of the page with a play button with href= ” # ” )
  • Lazy kitty is lazy.
  • Like I mentioned before, we load the player asynchronously in the background after you site is done loading. This helps your page render quickly as it ’ s not waiting to parse our JavaScript. But we do more lazy stuff as well. We defer embedding / downloading video engines until you actually play a video link, as well as lazily retrieve all metadata and fallback availability until you play each item.
  • We also use an awesome technology called YQL (Yahoo! Query Language) to do some server-side processing for us and send us back exactly what we need.
  • For instance, if we want to normalize empty fields, do some aggregation or manipulation of data, and filter out unnecessary data, we do it with Rhino in a JavaScript <execute> block. This allows us to use almost any data source and transmit only the bare minimum in JSON back to the client (as well as lets us cache this for any TTL we want). Living inside a solely client-side widget doesn ’ t give you much security, so we also utilize YQL ’ s access control to be able to differentiate operations and hide sensitive information. YQL conveniently gives you execute, read, and write keys which can be passed to your calls to differentiate users and security levels.
  • So now on to our future plans.
  • As you can see from our awesome visual, the next version of our UI will be much sexier. It should be faster, safer for your page, and more modernizd (incorporating the last couple years of front-end advancements). Let ’ s see a quick mock.
  • We also have plans to add more engines, media, and device support. HTML5 <audio>/<video> is pretty clearly useful for our purposes, so we hope to be incorporating this soon (and hope the implementations solidify soon as well). This will hopefully give us engines for additional codecs that have native support for free. Another item high on our radar is mobile / tablet support (there aren ’ t too many players for iOS). We hope to support additional audio and video publishers (the landscape of this industry is quite different from when the initial version of this player came out). We are also going to add a social aspect to be connect others with media you especially liked or create relationships or relevance over the content of media you ’ re playing. And there ’ s much much more, so stay tuned.
  • Jsconf 2011-us

    1. How to be a Player (on the Internet) <ul><li>The Making of Yahoo! ’ s Universal JS Media Player </li></ul>JSConf US 2011 Dan Beam [email_address]
    2. What ’ s Y! Media Player? <ul><li>It ’ s a JS media player, so I ’ ll explain in JS: </li></ul><ul><li>(function add(one_script, your_page){ </li></ul><ul><li>(jQuery || Y.one)('body') </li></ul><ul><li>.append('<script src=&quot;' + one_script + '&quot;/>'); </li></ul><ul><li>your_page = 'AWESOME!!!'; </li></ul><ul><li>})(' http://webplayer.yahooapis.com/player.js' , 'cool'); </li></ul>
    3. Demonstration http://www.reviler.org/2011/02/14/favorite-love-songs-four-takes/
    5. API / Customization <ul><li>API </li></ul><ul><ul><li>Many public methods on YAHOO.MediaPlayer </li></ul></ul><ul><ul><li>Env vars: YMPParams = { ' autoplay ' : true}; </li></ul></ul><ul><ul><li>Allows you to create custom experiences </li></ul></ul><ul><ul><li>API demo - http://danbeam.org/ymp_api.html </li></ul></ul>
    6. API / Customization <ul><li>// populate content </li></ul><ul><li>content.innerHTML = '<span class=&quot;item&quot;>' + </li></ul><ul><li>spans.join('</span><span class=&quot;item&quot;>') + '</span>'; </li></ul><ul><li>YAHOO.MediaPlayer.addTracks(content, null, true); </li></ul><ul><li>YAHOO.MediaPlayer.play(); // play first item </li></ul><ul><li>setInterval(function(){ // start cycle </li></ul><ul><li>YAHOO.MediaPlayer.next(); </li></ul><ul><li>}, nextDelay); </li></ul>
    7. API / Customization <ul><li>Skinnable markup </li></ul><ul><ul><li>You only need to change 1 image </li></ul></ul><ul><ul><li>All the rest easily styled with CSS </li></ul></ul><ul><ul><li>More preset themes in the future </li></ul></ul>Yahoo! Search skin
    8. Our Goals
    9. Our Goals <ul><li>Easy to install </li></ul><ul><li><script src=&quot; http://webplayer.yahoo.com/player.js &quot;></script> </li></ul><ul><li>From page to playlist </li></ul><ul><ul><li>Mixing audio and video in the same page is sweet </li></ul></ul><ul><ul><li>Richer experience (adds to page, isn't annoying) </li></ul></ul>
    10. Universalization <ul><li>We want our player to work anywhere </li></ul><ul><ul><li>Any page (even your cat's blog) </li></ul></ul><ul><ul><li>Any browser/device (desktop, tablet, mobile) </li></ul></ul><ul><ul><li>Any media/service (we ’ re adding more playback mechanisms / providers) </li></ul></ul>
    11. Universalization <ul><li>How would you go about playing any media type on any platform? </li></ul>Well, kinda... Sorry, @miketaylr, :(
    12. Flexible Architecture
    13. Adapter Pattern
    14. Adapter Pattern BaseEngine VideoEngine YahooVideo YouTube QuickTime Flv Rhapsody Flash HTML <audio> HTML <video> AudioEngine
    15. Graceful Fallback <ul><li>NOTE: Nimrod is another developer on the project </li></ul><ul><li>(and he ’ s really smart) </li></ul>
    16. Graceful Fallback <ul><li>MP3 link </li></ul><ul><ul><li>Headless Flash Engine w/JS API </li></ul></ul><ul><ul><li>Windows -> WMP -> QuickTime </li></ul></ul><ul><ul><li>OS X -> QuickTime </li></ul></ul><ul><li>Yahoo! Movie link ( http://movies.yahoo.com/movie/1810099246/info ) </li></ul><ul><ul><li>Yahoo! Movies API (via YQL) </li></ul></ul><ul><ul><li>YouTube (gdata) </li></ul></ul>
    17. But enough about us - on to you! <ul><li>We co-exist with your page peacefully. ** </li></ul>** Unless your page is still on gopher
    18. <ul><li>Namespacing </li></ul><ul><ul><li>Our own class namespace (currently .ymp-) </li></ul></ul><ul><ul><li>No #IDs (always global, too risky) </li></ul></ul><ul><ul><li>Ant <filterchain> on YUI3's widget CSS at build </li></ul></ul><ul><ul><ul><li>from .yui3-slider-widget { } to .ymp-slider-widget { } </li></ul></ul></ul><ul><li>Contextual CSS reset (protect our player ’ s style) </li></ul><ul><ul><li>from html, body , div, ... to .ymp-reset div, ... </li></ul></ul><ul><ul><li>protects against a { cursor: crosshair; } </li></ul></ul>Peaceful co-existence - CSS
    19. Peaceful co-existence - JS <ul><li>Minimal included dependencies </li></ul><ul><li>Small loader with one URL that always gets the latest version for you </li></ul><ul><ul><li>Full player cached forever (including on other sites) </li></ul></ul><ul><li>We don ’ t touch natives (Array, Object) (*cough* Prototype, Mootools *cough*) </li></ul><ul><li>We don ’ t conflict with any other libraries (including YUI) </li></ul><ul><li>We only introduce 1 global - YAHOO.MediaPlayer </li></ul>
    20. Performance
    21. Less is more <ul><ul><li>CSS-in-JS (minified CSS is built into the JS) </li></ul></ul><ul><ul><ul><li>Combine/templatize at build time with Ant </li></ul></ul></ul><ul><ul><li>CSS sprites </li></ul></ul><ul><ul><li>Investigating inlining data URIs for assets </li></ul></ul>(When it comes to HTTP requests)
    22. DOM caching / delegation <ul><li>We cache DOM queries </li></ul><ul><ul><li>As smartly as possible </li></ul></ul><ul><li>Event delegation (kind of a must these days) </li></ul><ul><ul><li>Less memory spent on event handlers </li></ul></ul><ul><ul><li>Catches extraneous events (if we want to) </li></ul></ul>
    23. Async laziness (D ’ awwwwww!)
    24. Async laziness <ul><li>Non-blocking (asynchronous append onload) </li></ul><ul><li>Lazy-loaded assets and media resolution </li></ul><ul><ul><li>Media item resolution (we don't get metadata ‘ til you play something) </li></ul></ul><ul><ul><li>Yahoo! Video Player </li></ul></ul><ul><ul><li>Yahoo! Movies metadata through YQL </li></ul></ul><ul><ul><li>YouTube Player </li></ul></ul>
    25. SSJS via YQL
    26. SSJS via YQL <ul><li>YQL server-side processing with SSJS in an <execute> </li></ul><ul><ul><li>Cached with YQL ’ s caching and our own </li></ul></ul><ul><ul><li>Only transmits what we need </li></ul></ul><ul><ul><li>Adds some information hiding / security </li></ul></ul><ul><ul><ul><li>Access control per operation (r, w, x) </li></ul></ul></ul>
    27. To the Future!!!
    28. New UI <ul><li>Sexier, Faster, Modernizd </li></ul>
    29. More engines/media/devices <ul><li>HTML5 <audio>/<video> (srsly, this is a big deal) </li></ul><ul><li>Additional codecs and services </li></ul><ul><li>Mobile / Tablet </li></ul><ul><ul><li>Smaller version for all mobile devices / tablets </li></ul></ul><ul><ul><li>iPad / iPhone / iTouch support </li></ul></ul><ul><li>Support additional video and audio publishers </li></ul><ul><li>Add Social (Twitter, Facebook, IntoNow) </li></ul><ul><li>... and much much more! </li></ul>
    30. Thanks for listening <ul><li>If you have any questions or comments, let us know! </li></ul><ul><li>Dan Beam </li></ul><ul><ul><ul><li>email: dbeam@yahoo-inc.com </li></ul></ul></ul><ul><ul><ul><li>twitter: @danbeam </li></ul></ul></ul><ul><ul><ul><li>site: http://mediaplayer.yahoo.com </li></ul></ul></ul>
    31. Credits <ul><li>Images courtesy of: </li></ul><ul><ul><li>http://flickr.com/28268402@N03 </li></ul></ul><ul><ul><li>http://flickr.com/dancoulter </li></ul></ul><ul><ul><li>http://flickr.com/nimrodbar </li></ul></ul><ul><ul><li>http://flickr.com/e2 </li></ul></ul><ul><ul><li>http://flickr.com/emilymills </li></ul></ul><ul><ul><li>http://flickr.com/hoanghaithinh </li></ul></ul><ul><ul><li>http://flickr.com/rongorongo </li></ul></ul><ul><ul><li>http://flickr.com/programmerman </li></ul></ul><ul><li>(Did I mention Flickr rocks?) </li></ul>