Delivering Audio and Video Using Web Standards, Part 1

Session 501 WWDC 2010

HTML5 is the best way to deliver audio and video in web pages in Safari. Discover basic techniques for delivering media with HTML5 and master the JavaScript APIs necessary to design and implement your own custom media controls to match the look and feel of your website. Learn platform-specific details and best practices for delivering a seamless media experience in Safari on iPhone OS, Mac OS X, and Windows.

Vicki Murley: Hi everyone I'm Vicki Murley the Safari Technologies Evangelist at Apple is this is Session 501: Delivering Audio and Video using Web Standards Part 1.

So how many of you out in the audience are using a plug-in to display audio or video?

If you could just show of hands please.

Ok great and how many of you are using HTML5 on iPad but a plug-in everywhere else?

How many people are in that boat?

Ok a couple.

And how many of you are using HTML5 everywhere you possibly can, in every browser, on every platform that supports it?

Can I get a show of hands?

Ok small group that last one.

Ok well whichever group you happen to be in I can guarantee you're going to learn something in this session today that you can go back and implement immediately once you leave this session or leave the conference.

So you've probably been hearing a lot about HTML5 these days, in fact you have been hearing a lot about it and there's one thing that kind of caused people to sit up and take notice with regard to HTML5 and that's iPad.

So iPad is technically a mobile device but like iPhone OS like iPhone it does not support plug-ins, however it has this very large screen, so users browsing the web on iPad are really expecting a desktop caliber, full fledged browsing experience.

If you have audio or video on your website, they want to see it on iPad.

So since there are no plug-ins on iPad this really - this is a device that caused a lot of website developers to sit up and take notice and take a good hard look at web standards for the first time.

So you've probably seen this site before.

apple.com/ipad/ready-for-ipad and if you've ever surfed the web you've probably seen at least one of the sites that are listed here.

So there's quite a few: CNN, Vinio, NPR, People.com, Life, America's Finest News Source, theonion.com.

These are all websites that are moving to HTML5 to deliver a great experience on iPad and in particular HTML5 audio and video elements to deliver a great experience.

So I actually worked with quite a few of these developers to get them started with HTML5 audio and video and that's what I'm going to do with you today, help you do the same thing.

So in this session I'm going to cover 3 main areas: the first is pretty simple, just adding media to your web pages with HTML5.

After that I'm going to talk about how to optimize that experience with standard web technologies and finally I'm going to discuss how you can use built-in functions to control your media.

As I mentioned I work with developers a lot so along the way as we're going through those 3 main topics, I'm going to address some of the most common questions that I've heard from developers just like you.

So let's get started talking about adding media to web pages with HTML5.

So in this section I'm going to tell you how you can specify fall back content, how you can write cross browser compatible code and I'm also going to talk to you about some platform specific considerations if you're deploying media with HTML5 on iPad or iPhone versus the desktop.

So let's get started with the basics.

So this is just one line of code and with this boom you're done, you have video in your webpage.

It's pretty great.

I want to just take one moment to point out that everything I'm going to talk about today is true for both the video tag and the audio tag so there's really only 5 attributes that are different, that are unique to the video tag, poster image, height and width and video height and video width, those last two are the native height and width of the video.

Everything else is the same for the two elements but most of my examples and code snippets et cetera are going to focus on the video tag.

So let's get back to our basic tag again.

If we want to display some fall back content in web browsers that don't support the HTML5 video tag, we simply nest that content in between the opening and closing tags so here we're falling back to a plug-in to display our movie.

Here we're just showing a static image and here we're showing some text.

You can really put anything you like in between these opening and closing elements.

Also on our simple example here we have a source attribute and you can really throw a lot at this source attribute and it just works.

So for example, in Safari on the desktop the video and audio elements will play any linear codec supported by QuickTime and this includes user installed codecs.

In Safari on iOS you can play H.264 video with a baseline profile, uncompressed WAV and AIF audio, and MP3 AAC-LC and HE-AAC audio.

It's also worth noting there are a couple of other types of media that you can provide to that source attribute that just work.

Those are QuickTime reference movies and also HTTP Streams.

So you can point that source attribute at your streaming media, at that URL and it will just work in Safari.

Ok back to our simple example one more time.

So we have this opening video tag, closing video tag and our fallback content in between which just is a line of text.

So it's worth noting and it trips people up a little bit sometimes that this text is only displayed if the browser does not implement, does not support the HTML5 video tag at all so in cases where you point to a media resource that can't be played, or something like that because it's in a codec that the browser doesn't understand, that fallback text won't be shown.

It's only shown if the browser doesn't implement the video tag.

So how can we deal with that?

Well one answer is to use the source tag and you can put source tags in between your opening and closing video elements, video tags and what happens is the browser sees these and they iterate through this list of source tags and they play the first encoding that they can play.

A couple of tips when you're using the source tag is number 1, to specify a type attribute.

So if you don't specify a type attribute, the browser actually has to download a piece of the video to see if it can play it before it can move onto the next one so you can avoid unnecessary network requests and optimize performance a little bit if you always specify a type.

You should also include in that type attribute you can include a string of codecs so basically with this source tag you're asking the browser a question: Can you play this video?

The more information you give the browser, the better answer it can provide.

So if you provide additional information here like codec information, the better answer you will get.

So here we have 2 different codecs, they're both H.264 video but one is a baseline profile and the other is a high profile.

Another tip for using the source tag - it's really great for just multiple media resources in general so just like you might use a CSS media query to serve different CSS files to different devices iPhone, or iPad, or the desktop you can use those same queries here in the media attribute on a source tag.

So in this first example here I'm serving this smaller file, maybe it's a smaller dimensions to a device that is probably an iPhone and in the second source tag here I have a different file, it's larger dimensions, I want to serve that to anything bigger than an iPhone.

Ok so we've talked about using the source tag to go through different encodings to see whether or not the browser can play that given encoding but what if you just want to have one encoding and you want to see if the browser can play that encoding and supports the HTML5 video tag?

Well here's what you do.

The first step is to detect whether or not the current browser supports the HTML5 video element so you can just check HTMLVideoElement in window here.

The next step is to detect whether or not the browser can play your media using the canplay type function so here we've checked to see if the browser supports HTML5 video.

Now we've created a video element and on that video element we're calling canplay type and just like you saw the type attribute earlier on the source tag we're going to specify the same type of string here, a mime type and a string of codecs.

So this string that you're passing to canPlayType it has a lot of information in it but it doesn't have all the information that the browser needs to in order to determine whether or not it can play the video.

For example, we can't know the bit rate, so canPlayType can't conclusively tell you whether or not it can play the video but it can get pretty close, it provides one of three answers: probably, maybe, and no are the three return values from canPlayType.

Codecs they're crazy.

So if it's maybe or probably you're in pretty good shape so I'm going to set some extra attributes on my video tag or video element that I created earlier and then I'm going to append that element to the body.

Ok so now we're moving onto some platform-specific differences between Safari on the desktop and Safari on iPad and iPhone.

So here's my basic video tag once again with just a little bit of text for fall back content and if I loaded that file in Safari on the desktop, Safari on iPad, and Safari on iPhone here's what I would see.

So the first thing that you're going to notice is that on the far right you're going to see that controls are displayed.

So iPhone always displays controls.

The video is played in full screen mode all the time and we always show our own controls over the video, so controls are always shown on iPhone.

The second thing you're going to notice is that these videos are different sizes so I haven't specified a height and width on my video tag and so on iPad and iPhone we get a default height and width of 150x300 pixels and this is per the HTML5 spec. What's happening here behind the scenes is the default behavior on the desktop is to auto buffer download and auto buffer the video.

So even though we haven't specified a height and width, the browser knows the height and width of the video, just like when you specify a image in a webpage and you don't specify a height and width.

The browser can infer that information from the media, in that case the image.

So on iPad and iPhone there's no automatic buffering.

We don't want our users to be on a cellular network and incur involuntary data charges so we don't auto buffer this media on iPad and iPhone so in that case we can't infer the dimensions and we have to give a default dimension.

So luckily it's very easy to make one simple change to this video tag to make all of these look the same.

I'm just going to specify a height of 240, a width of 320 and I'm also going to add the controls attribute which is a boolean attribute so even the existence of it turns it on so I could even have controls equals false here but it would still be there, it's boolean attribute so the controls would still be on in that case.

Here I've just set it with no value whatsoever and doing that will cause my video to look like this on all platforms.

All the same size that we would expect it to be and controls that match the platform, so some controls on the desktop and then same controls on iPad and iPhone.

Ok so that's one sort of platform-specific detail.

Let me tell you about a few more.

Safari on Mac OS X in windows is optimized for concurrent playback of multiple media resources so you can play two videos at once, an audio and a video file at once, two audio files at once, more than two, whatever you want to do, you can play multiple files at the same time on the desktop.

You also have programmatic volume control on the desktop so you would set change the volume via the volume and muted properties on the video or audio element and that is available on the desktop.

And as I mentioned before automatic buffering is enabled by default so things like autoplay, the autoplay attribute on an audio or video tag which will start your video automatically, or calling the play function from an on-load handler or something like that, something where the user has not explicitly triggered playback, both of those things will work on the desktop.

On iOS, iOS is optimized for playback from a single media resource, so only one media resource at a time.

Volume is under user control.

You notice that in this screen shot I don't have the little volume control that I had on my previous screen shot, these are my own controls that I drew myself and on iOS I removed them because the volume cannot be changed programmatically.

This is true for native iOS applications as well.

You don't want one of the apps that you installed or a script from a webpage muting your volume and missing a phone call so volume is under user control on iOS and finally, as I mentioned earlier, there's no automatic buffering on iOS and this means that things like autoplay do not work.

Again we don't want our users to incur data charges involuntarily and if you call play from your on-load handler not a result of a explicit user action to click a play button, that will not work on iOS.

Ok so that covers the first section: Adding Media to Your Web Pages with HTML5, now let's move onto Optimizing the Media Experience with Standard Web Technologies.

Ok so I mentioned a couple of times that autoplay or calling the play function in line is only supported on the desktop and I want to give you a real world example of how that affects the different events that are emitted by the HTML5 audio and video tags so I'm going to switch to the demo machine.

Ok can barely see you guys now but oh well.

So I'm going to load this simple file and this is basically a simple video tag, I have the controls attribute set and then I have a bunch of event listeners added that log a message to the page whenever an event is emitted.

So here you can see load start and duration change have fired, I'm going to show some notes here and explain a couple of the non-obvious ones.

Load in metadata is very important.

At this point you know the height and width of the video.

Loaded data tells us that the browser can render the media data at the current playback position.

In this case its zero time.

Progress tells us it's fetching the media, this is a pretty small file, it's only 42 seconds so we only have one progress event here.

Canplay tells us we can play the media but we might have to buffer to play it all the way to the end and canplaythrough tells us we can play it all the way through and won't have to buffer anymore.

So I'm just going to start playing this media and you can see a couple of things have happened we got this play event which tells us we just returned from the play function, playing tells us playback has started and we received several time update events here as well.

So time update is emitted anywhere from 3-5 times per second here.

So I'm just going to collapse those and then I'm going to load the same file on iOS on iPhone.

So you can see right away that the first frame of this video is black and also we get two events here: We get a load start event and a suspend event so the load start tells us that media has started downloading and the suspend event tells us that loading has stopped but not all of the media has downloaded.

So now I'm going to play this video, its Johnny talking about iPad and now full screen mode which is the default on iPhone.

So I'm just going to click done and the interesting thing that you should note here is that JavaScript is still running even when my video is playing in full screen mode so I'm still getting all of the events that you would expect to get, even when you know the video is taking over the whole screen.

So here we had our load start and suspend, we click the Play button here, we were waiting a little bit for some of the media, we got a duration change event, a lot of these are the same as the desktop, loaded metadata and loaded data, canplay so at this point we immediately start playing the media because we clicked the Play button way back here.

We get a progress event telling us that the media is being fetched, canplay through, load and then pause and of course all of these time update events as well.

So that's it in a nutshell how events work with the video tag in Safari on the desktop and on iOS.

So this is actually really important because understanding when these events are emitted are really critical if you want to kind of enhance the user experience, create your own controls, add a progress indicator, anything like that you need to have a good understanding of when these events are firing.

So the sample that I just showed should be associated with this session as sample code and I would really encourage you to experiment with that file, try out different devices, different media sources, try a streaming source, try a very large resource.

Here we just got one progress event but if you had a very large resource you would get many and also software versions.

The HTML5 spec for video is changing a little bit.

One concrete example is that the load event has been removed so that is something that may change in the future in Safari so try different software versions as well.

Ok so we saw just now the default behavior on both platforms.

Auto buffered on the desktop, not auto buffered on iOS but what if I wanted to disable automatic buffering on the desktop, so maybe I have a video blog and I have like 10 videos on the front page and I don't want them all to start downloading at once because that would use up a lot of bandwidth and it wouldn't be great performance so I want to just disable automatic buffering.

Well there is a new attribute that is available in Safari 5 and it's this pre-load attribute and you can just set it to none and auto buffering is disabled, which is great.

So that's new in Safari 5 but what about users who may still have Safari 4?

You might want to disable auto buffering for those users as well.

Well thanks to the power of JavaScript that's easy to do as well so here we have our video element and you'll notice that the source attribute is blank, it's just an empty string so basically when the browser encounters a video tag it'll look at that source attribute and if there's anything there it's going to try to start pulling that media immediately.

If there's nothing there it has nothing to pull so we also set a little event handler here for a click and when we click on this video element we call this set source function.

We get our video element and we just set the source attribute to the URL of our media, in this case iPad.m4v.

Then we programmatically play and everything is great, no automatic buffering in older versions of Safari.

A couple of other, I want to point out a couple of other useful things about events, basically when you should do what as far as events go.

So loaded metadata is a really important one so here we are setting height and width on the fly.

Earlier in this discussion I mentioned how you'll get a default height and width if you don't specify one.

Sometimes it's not always possible to hard code that height and width into your video tag.

You might be serving the video on the fly and not know the height and width.

So you can set these attributes on the fly and resize your video pretty easily so here we're listening for a loaded metadata event and when we get it we're going to set height and width, very straight forward, we're just getting our video element and we're looking at the native video height and video width and we're setting the height and width attributes accordingly.

So this will resize your height and width on the fly.

Loaded metadata is also really important if you want to trigger full screen mode.

So this is now supported in Safari 5, its new.

Saw it at the State of the Union yesterday, it was mentioned.

This is really cool so we have again our simple video tag listening for loaded metadata event in this case we're calling a function called checkFullscreenSupport.

We also have a button on this page, this button is actually what's triggering full screen mode and it's doing that by getting our video element and calling webkitEnterFullscreen.

So this is our button that's triggering full screen mode in our user controls.

So back to our check full screen support function here which is called once the metadata is loaded, at this point you need to check and see if the video element, or it could even be an audio element, if that supports full screen mode so if it doesn't support full screen mode I'm going to want to hide that button that triggers it.

So if you're drawing your own custom controls this is a really great technique you you know don't want to present controls to the users that don't work so always check to see if full screen mode is supported for those types of controls.

Ok other useful events that are emitted by HTML5 media elements are canplay, canplaythrough and waiting.

These are great opportunities to show a progress indicator to let your user know that something's happening but they just have to wait a little bit.

We're not going to show any code snippets for this one because Beth Dakin is going to walk us through the code step by step and show us exactly how to listen for these events and optimize the user experience so Beth.

[ applause ]

Beth Dakin: Thanks Vicki.

So I put together a little webpage today that just shows a video, I'd like to share it with you and it's really pretty straight forward.

So let's just dive straight into the code.

So here's my HTML file I just have 14 lines of HTML, very simple stuff, this should look pretty familiar at this point.

Here's my video element I just have an ID on it, a width and a height.

I specify the controls attribute so that I get the default controls on each platform.

I have the source pointing to my media resource which is a beautiful short film called Dartmoore by James Watson - highly recommend it - and finally I've specified the poster attribute to have pointing to a ping that I have that I want to display as a poster image and I have a little bit of fall back content too and then I just have a link down here to James Watson's webpage.

I just have a tiny bit of CSS, which isn't especially relevant to this so we won't really focus on it so let's take a look at what this looks like in iPad.

[ pause in speaking ]

So here you go I have my poster image displayed here, I get the default controls and I can [ music ]

Let's take a look at this in Safari 5.

So you may have noticed a little something different here.

We're no longer showing a poster image so let me explain what's going on there a little bit, the HTML5 specification defines a poster image as something that shows when no data is available, so as Vicki explained earlier the default behavior on Safari on the desktop is to auto buffer the video.

So once enough of the video has auto buffered the poster image won't display anymore and so what we're seeing instead is the first frame of the video which happens to be black so now I can play my video [ music ]

There you go.

So with just a few lines of HTML I've got a really good out of the box experience here for the HTML5 video element but the fact that this is so good out of the box is really only half of what's awesome about HTML5 video element.

Really the other half is that it's totally customizable, it's within your power and control as a designer to make this look however you want so there are a few things that I want to change here.

First of all I don't think I want a poster image, what I really want is an image overlay that's going to display over the video until the user starts playing it and instead of just disappearing and going to the first frame of the video like a poster image, I want it to fade out nicely which is an effect we can easily achieve with CSS and I also want a custom play button that will be the same on all platforms so that's kind of a lot so let me show you what I want to achieve and then I'll show you the code to do it.

Ok so this is what I want here we are on Safari 5.

We still have that image because it's not a poster image, it's instead an image overlay and it's still there and I have my custom button.

So let's take a look at the code.

[ pause in speaking ]

Ok here's my HTML it has not changed much, it's only a few lines longer.

We have 20 lines of HTML now instead of 14.

My video element should look pretty much the same.

I've removed the poster image attribute.

Here I've added a DIV element that I'm calling my status DIV this is going to be that click to play button.

I also have an image element, this is the image overlay, it's pointing to the same ping resource that I was formally using as a poster image but now it's my image overlay and I've also added to my body tag here I've added an on load handler I'll call a function init and I've also added a little job script file so let's take a look at that init function.

Here it is in my JavaScript file.

Basically the point of this function is to just add a few event listeners for various events that I want to handle when that click to play button is clicked so I have a little bit of local variable stuff here at the top, just to take care of most down, most up, touch start, touch end etc, cover all my bases with desktop and iOS and then the first one here when I get any of those up events I want to call load video so that's a function I've defined right here.

Let's take a look at that.

Load video will just get that video, add an event listener to the video itself so that if we get the canplay event then we'll call another function play video.

We also load the video here and here we're setting the controls attribute on the fly instead of doing it in the HTML and this is just so our click to play button is clickable, we don't want the default controls handling those clicks so we're just going to set this when the video is loading.

So the play video function is the one we'll call when we get that canplay event and here what we're doing is just changing class names for the image overlay and the click to play button, the status DIV and then I'm telling the video to play programmatically but this is a really common technique that any of you familiar with web development, which is probably a lot of you, are probably familiar with but basically we're just switching out class names here, what we really want to achieve in this function is just changing around some CSS and rather than writing out a bunch of lines of JavaScript to individually manipulate the CSS attributes on each of these elements, I'm just changing class names so changing these [inaudible] class names hidden which I have defined in my style sheet will just cause their opacity to be 0, their Z index -1, they'll be out of the way and basically all the rest of the JavaScript in this function, excuse me this file is just devoted to toggling the appearance of that click to play button so that it disappears appropriately and one other thing I want to point out here is I've also defined some transitions in my CSS just here so that my image overlay and my click to play button at status DIV will fade out nicely with the transition.

It's really this simple, if you don't know about transitions, or you want to know more there are two sessions later today: CSS Effects Part 1 and Part 2 that I strongly encourage you to attend to learn more about that.

So let's take a look at this in action [ Background music ]

So there we go I have a poster image and it faded out nicely [inaudible].

And we have the same experience on iPad [ music ]

So we have a pretty fast network right now and so this video is loading pretty quickly but you can imagine that if we were on some kind of cellular network, or having some kind of network problems, this might take awhile to load and it might be a little bit confusing to users who just clicked that button and see nothing happening yet cause the video is not ready to play.

So I think I want to enhance this some more by adding some progress indication.

Also if the resource wasn't available it seems like my user would get a pretty bad experience too.

So if I just change the source attribute on my video to something that doesn't exist and then I reload this page and try to play it, nothing's happening here.

So this is not a great experience so I think we should add some error handling as well.

[ pause in speaking ]

So let's take a look at that.

So I'm going to add some progress indication and error handling so I don't' need to change my HTML to do that.

Over here in the JavaScript I don't need to change either of these functions up here in it, our toggle button appearance so I've just collapsed them.

Here I'm taking I'm doing some more of that class name manipulation I mentioned earlier and I'm going to change the class name of that status DIV which was our click to play button to progress.

So if we look over at our CSS file to see what progress is that's going to change the content of that progress DIV to an animated gif so if we look at my resources that's just this simple animated gif with a few frames that I have of like a spinning progress indicator back here in the script.

I also wanted to add error handling so I'm adding another event listener here for the error event and if we get that event then we will call our new report error function which also just does class name manipulation on that status DIV and we'll change the class name to error where instead of that animated gif we'll have some text.

So let's take a look at this.

[Background music] So there we have the nice progress indication; we got to see the video is loading, it took awhile, but it would make a lot more sense to our users.

And finally if the resource is actually not available then we also get some nice indication to that and again this all works the same on an iPad.

[music] So that's all for now I think I'll hand it back to Vicki thanks everybody.

[ applause ]

Vicki: Al right thanks Beth.

That was pretty cool.

So there are a lot of pretty cool things about that demo.

I just wanted to point a couple of them out.

First, we basically we're noticing that HTML5 video is just like any other web page element.

You can layer it with other elements; here we have that button overlaying an image which was overlaid over the video.

You can style it with CSS, not sure if you noticed but there was a little box shadow around the video, that was just CSS applied directly to the video element and also it can be manipulated with JavaScript.

Now the power of JavaScript in the DOM here allowed us to add a lot of enhancements to that basic video tag pretty quickly so that was pretty cool thank you Beth.

Ok so that covers Part 2 Optimizing Your Media Experience with Standard Web Technologies and now we're going to move onto the final section here: Using Built in Functions to Control Media.

So a lot of websites out there are doing a really great job just using basic, the built in standard controls so here's America's finest news source, The Onion displaying video with just the controls attribute, no custom controls at all.

But it's actually pretty simple to add your own custom controls and we're going to look at a very common control here, a play/pause button.

So it's pretty simple to do.

We basically have our video tag at the bottom, is that built in?

Yes it is.

So we have our video tag at the bottom.

We have a button here which says play/pause on it and when it's clicked we're going to call this play/pause function here and this is basically getting our video and checking to see if it's paused via the pause property.

If it is paused, we're going to play it and otherwise we're going to programmatically pause it.

So pretty straight forward, not very many lines of code and to show us exactly how that works I want to bring Beth back to the stage to add a Play/Pause button [ applause ]

Beth: Thanks Vicki.

Let's see ok so we're going to add a play/pause button to this.

So here's my HTML again and it hasn't changed much, I've added one more element here, another DIV and this one has the ID play/pause button.

If we look in our script file here I've rewritten this init function a little bit because now I have a lot of buttons so I've added this for loop so that all of my buttons do these first two things, which is to toggle the button appearance so that I don't have to rewrite adding those event listeners for every single button manually and then for the special buttons that need some extra event listeners I've added this switch statement.

So this status case is an event listener that we added before, we don't need to talk about that but what's new is here we've also added a case for the play/pause button so we'll add an additional event listener for that button that whenever we get the up event we'll call toggle, play, pause and so that I've defined down here.

I'm not going to get into this too much because it's basically identical to what Vicki showed you on her slide, it's pretty straight forward here we're just programmatically calling play or pause as appropriate and I'm also switching out some class names again to get the appearance that I want further in the play case or the pause case and the only other thing I want to point out here is that I have also gotten rid of my line of code that used to set that controls attribute programmatically, because now we're drawing custom controls so we don't want default controls.

So I'm just commenting out that line of code.

Oh and then the other thing is that I'm just telling the play/pause button here to show because initially it's not showing until we start playing the video so I want to tell it to show here and it will fade in nicely because I've added a transition to my CSS file for that.

So let's take a look at this.

[ pause in speaking ]

[background music] So there you go you can see my custom pause button in the corner there, no default controls.

I can click Pause and it toggles appropriately.

[background music] I can click Play again and you'll see it has it's semi-opaque so it has this nice effect, you can see the video playing behind it, it's just another element layered on top of the video and we can see the same thing whoops in iPad.

[ pause in speaking ]

[background music] There we go [ applause and music ]

Thanks. Back to you Vicki.

Vicki: Beth oh you know what though like it would have been really cool if you had added like a full screen button too since that's new in Safari 5, like that Play/Pause button was pretty cool but it would have been really cool if you added a full screen button too.

Beth: Actually Vicki I do have a version of the demo with a full screen button.

Why don't I show everybody?

[ pause in speaking ]

Ok so to add a full screen button again we just need to add a few more lines.

Here in my HTML I've added another DIV, this one has the ID full screen button.

If we looked over in the JavaScript here we add another special case for our full screen button, a special case event listener.

When we get that up event on the full screen button we will enter full screen but you may recall you may have noticed in my HTML the default the initial behavior of that DIV that's the full screen button is to be hidden so what we really want to control here is when we show that full screen button and we want to make sure we only show it when we have full screen capabilities.

So we add the event listener here cause we want the capability to always be there but we're only going to show it down here in our play video function so you may recall that play video is only called when we get the canplay event so by the time we get the canplay event we will know if we have full screen video capabilities so if we have it then we will show the button.

So let's take a look at that.

[background music] Click to play, I get my custom controls.

I have my new full screen button in the corner.

I can press it, we go full screen, then I can collapse by clicking this button or pressing escape and that's it, full screen button.

[ applause ]

Vicki: Thanks Beth that was pretty cool.

You know that was pretty cool how it like scaled in and everything but this video it's kind of big it would have been cool if our video was a little smaller so that people could really see the scaling effect.

I mean no offense; it would have been cool if we had something like that.

Beth: I do actually.

I can show everybody.

How about I do that?

[background music] So here's a version of my movie that's kind of small but I can click it and go full screen.

Why don't we watch that slow motion?

There you can really see how nice that transition is and that's just out of the box experience there.

You can see it's scaling up slowly, you can also see the background fading out, it's pretty sweet.

[ applause ]

Ok I think I'll go back to your slides now if that's ok.

Vicki: All right sounds good.

All right thanks Beth.

So pretty quickly added our own custom play/pause button that matched the look and feel of our video, pretty cool.

So just to recap what I've gone over today: First I talked about adding media to your web pages with HTML5; really simple to just add one line of code and simple fallback as well.

After that we talked about optimizing the media delivery experience with standard web technologies, just using CSS, JavaScript the DOM to make your media look great and finally we just really quickly cause it was really simple went over how to use built-in functions to create custom media controls, in this case we just did a simple play/pause button.

So just a couple of thoughts to take with you today when you leave this room: I want you to remember that it's really easy to add media to your web pages with HTML5.

Lots of websites are just doing it with one line of code, using the default controls, super easy.

You can make it as basic or as sophisticated as you like.

You saw when Beth was you know building up our demo code that she started with just one video tag and then added to it as she went and made it pretty sophisticated, pretty quickly and finally if you're a web programmer you're already an expert at using HTML5 audio and video, it's just another web page element that you can style with CSS, manipulate with JavaScript and get started with something pretty cool.

So for more information if you have any questions you can contact me, the Safari Technologies Evangelist at Vicki@apple.com.

There's some great documentation on the Safari Dev center which his at developer.apple.com/safari.

Specifically, I would want to point out the Safari HTML5 Audio and Video Guide.

It's a great document that tells you everything you're going to need to know about HTML5 media in Safari on all platforms.

The HTML5 Spec is always a great resource to see what the latest and greatest is around HTML5 and finally, announced yesterday we have Apple Developer Forums for web developers just join the Safari Developer Program and access is totally free which is pretty cool.

There are a lot of great sessions coming up this week related to HTML5 media and web technologies in general.

A couple of specific ones that I wanted to point out to you: In this room following this session we have Delivering Audio and Video Using Web Standards Part 2.

We also have - I think its right after that one, Advances in HTTP Streaming, so if you want to set up streaming media, don't miss that session.

This afternoon also in this room we have CSS Effects Part 1 and 2.

These sessions are amazing.

You don't want to miss them.

They're going to show you how to add some really cool CSS effects to your web pages, which also could apply to video and finally on Wednesday there's another great session on adding touch and gesture detection to your web pages on iPhone OS.

So here we just had a really simple example where we used touch down, I'm sorry, touch start and touch end instead of mouse down and mouse up to just get really direct manipulation of those buttons in our example.

This session is going to go way beyond that to tell you everything that you need to know and implement some pretty cool stuff around down touch events.

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US