Internet & Web • iOS, OS X • 42:36
With HTML5, embedding audio or video in a web page can be as simple as adding a single line of code. Go beyond the basics and learn the best practices for implementing custom media controls that match the look and feel of your website. Discover how to use JavaScript to add custom play and pause buttons, volume controls, a timeline, a fullscreen button, and see how to display custom controls when video plays fullscreen. Find out tips for optimizing the look and feel of custom media controls for Safari on the desktop, and for the touch-enabled, zoomable interface of Safari on iPhone, iPad, and iPod touch.
Speakers: Eric Carlson, Jer Noble
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Well, hello, and welcome to Advanced HTML5 Media Controllers for Safari on iOS and Mac OS X. My name is Jer Noble. I am a Safari and WebKit engineer. And today, we're going to talk about how to make awesome, accessible controls for your HTML5 media content. Eric Carlson, Jer Noble But first, last year at WWDC, there were a couple sessions which covered the basics of JavaScript controls for HTML5 video and audio.
The video for these sessions is available on Apple's Developer site. So if you go to developer.apple.com/videos, clicking on the link to WWDC 2010 session videos will get you this page. And the ones you're interested in are Delivering Audio and Video with Web Standards Parts 1 and 2. These are great presentations, if I say so myself. I highly recommend checking them out.
So last year at WWDC was all about baby steps. Everything was very new and very exciting and just a little bit blurry. And a lot of things have changed in the last year. We've added a bunch of new capabilities to Safari, and a lot of things have changed in the HTML5 standard. And we're going to tell you all about them today.
But since last year, we've seen a lot of sites adopting HTML5 for delivering video content to their users, which is fantastic. But we've also seen a lot of those same sites only delivering HTML5 video to browsers reporting that they are iPads and iPhones. So this has led people to go to extreme measures to convince websites to deliver HTML5 video to them.
In fact, so far as to say that there's one popular technology blogger who posted a multi-page recipe about how to do this, how to convince websites that you're browsing from an iPad when you're on Safari on the desktop. Needless to say, we don't think user agent sniffing is the best of ideas.
It's fragile. Whenever there's a new device, you have to change all of your scripts to parse user agent strings. And it doesn't really detect capabilities. It only detects devices. So we're going to show you a better way to do this. But why is this happening? Well, page authors want controls that match the look and feel of the rest of their website.
They want controls to work on all browsers and across all platforms. They want controls to do things that the default controls can't because otherwise, You know, why bother? And somewhere along the way, a lot of authors got the idea that this is just something you can't do with HTML. But today, we're going to show you how all of this and more is possible with HTML5 and standard web technologies.
So, what did you learn today? We're first going to cover how to create simple custom controls with JavaScript and CSS and HTML5. How to make sure those controls work for everyone, no matter what device they're using or what assistive technologies they're using to view your site. And finally, we're going to cover a little special effects you can add to your video elements and your controls.
But first, getting started, if you'd seen last year's sessions, and you will recognize these when you go back and watch the video later, this is the basic set of API you'll need to implement a play, pause button, and timeline slider for HTML video. So getting started, every media element has a play and a pause event, somewhat self-explanatory. You can also query for a media element's current time, ask for its duration.
Ask for its duration. And then while the media is changing time, it will emit events occasionally, such as play when the user plays your video, pause when they pause. And as the movie is playing or as the user is scrubbing, it'll emit these time update events. So how might you use this to make, say, a general play/pause button? If you have a button and has a click handler, all you need to do is check to see if the movie is paused or if it's ended, and if so, play it. If not, pause it. That's it. Just, what is that? Five lines of code, including braces.
And in addition, if you want to react to the fact that the movie is now playing instead of paused, Three event listeners for the play, pause, and ended events is all you'll need to update your button to say something different when the user plays the movie, or when the movie gets to the end of its timeline and stops playing on its own.
Okay, the next thing you might want to add is a timeline scrubber. This is like a slider element that you can drag back and forth to allow quick, rapid access to any point in the video. And last year, this was kind of like a hard problem to solve. You had to implement your own slider to make it work on all browsers. However, HTML5 and now Safari on iOS have this input type of range, which will be represented as a slider.
It's also fully stylable in CSS, both the thumb and the track. So anything you could do before with your own custom slider, you should also be able to do with this one. It has the added benefit of handling touch events where you might have to write custom code to do that if you were implementing your own timeline slider. And it emits just one event that you'll need to worry about, the onChange event. And when the timeline slider changes, because the user's dragging it around, set the video's current time.
And then you can add the slider to the start time plus-- wait, what did I say? Yes. The value of the slider times the duration. Anyway, this is actually kind of unnecessary. Set the max value to the duration and set the min value to the start time, and all you have to do is pass that value across to the current time. Easy as that.
And same thing, as the movie's playing, you're going to want to react to the time changing and update your slider, and listen for the time update event, and change the value of the slider to match. And again, if you set the min and the max to the duration and the start time, it's as easy as just passing the movie's current time into the value of the slider. And that's it. You have a timeline slider that works to change the value of the time in your movie. Easy peasy.
And like I said earlier, this range element is now supported on mobile Safari on iOS. OK. Now you've got a play button. You have a timeline slider. The next thing you might want to control is volume. You have an input range element, which would easily work for a volume slider as well.
There is a caveat, however. On iOS, there is only one volume setting, and that's the system volume setting. And the system volume can't be changed from JavaScript. You probably don't want it to be changed from JavaScript to have some website change your volume to min or max, and you miss phone calls, or you're waking up in the middle of the night. Either way, bad idea.
So, after I just told you that user agent sniffing isn't something we endorse, now we're back to looking at user agent strings to not change the volume for iOS. I have a better idea. So here's your input range element, just like the last example. It has a min and a max, and as you scrub it, it calls set volume. But in this case, we're going to set the style by default to display none.
And we set up our functions for changing the volume. We add our event listeners. And after we're done, we're going to change the video's volume to 0.5. On iOS, nothing will happen. On the desktop, This will actually result in a volume changed event, which at that point will remove that display none property. The volume slider shows up.
Bob's your uncle. You have a slider that does not appear on iOS where it won't work and appears on desktops where it will. No need for user agent sniffing. So volume slider, timeline slider, play button. You have the basics of a set of JavaScript video controls. But the next thing you might want is to go into full screen. You have some great content.
You'd love to display it on the entire screen at once. We covered this a little bit last year. There are two functions you should know about for the HTML media element, WebKit enter full screen and WebKit exit full screen. We'll take the video into and out of full screen. And when these functions are called, they'll emit WebKit begin full screen and WebKit end. So you can react to changes in the full screen state.
This works on Safari on iOS, Safari on the Mac, Safari on Windows. And on all these platforms, we provide great default. Connections. You can use the default controls appropriate to the platform. On iOS, they're touch sensitive. On the desktop, they're just gorgeous. And videos on the iPhone will always play in this full screen mode. So, so far.
It's a great ability to take your video into fullscreen and show off your content on these great monitors we have. However, we got a lot of feedback after last year's session. People kept wanting to know, how do I get these custom controls you're talking about into fullscreen? And we would say, sorry, we only take the video into fullscreen. We don't take anything else. But I'm pleased to announce that in Safari Online, you can now take any element into fullscreen, which will bring that element and all of its children, all of their style, all of their display, into fullscreen mode.
And when you're in fullscreen mode, you have complete DOM access just like you did in the in-page mode. So you can add children, move children, change styles, react to events. Users can click buttons, slide things. All of these controls that you will have built to make your video have a great experience will also be present in fullscreen mode.
Now, the basis of this support in Safari is a proposed specification from Mozilla. So if you want to read more about this fullscreen mode and the development of it, check out Mozilla's wiki, the URL here. Okay, so every element has a method called WebKitRequestFullscreen, which tells the document, hey, I want this element to go into fullscreen mode. This element, all of its children, all that stuff.
And the document has a host of new APIs as well. You can check to see what the current fullscreen element is. You can ask whether or not the document is in fullscreen mode. And when you're in fullscreen mode, you can ask to see whether or not keyboard input is allowed. And as the web page transitions into and out of fullscreen state, it'll emit this fullscreen change event, which you can listen to to update your controls.
And at any point, you can request the document cancel out of fullscreen. On user press, end of a movie, whatever. There are also a couple of CSS pseudo-classes you'll need to know about. The first one applies to the element that is currently fullscreen. So you could style it completely differently when it's in fullscreen mode versus not. This next pseudo class applies to the document which contains the fullscreen element. And between these two things, you should be able to apply a completely separate set of style rules for your page when in fullscreen mode.
There are, however, a couple of requirements to using this API. The first and biggest is that going into fullscreen must begin with a user action, either a mouse press or a key click, or key click or mouse press. The other requirement is that an iframe, if it has content that it wants to take into fullscreen mode, must have a WebKitAllowFullscreen attribute set.
But between those two things, those are the requirements for taking something into fullscreen mode. So how might this work? Well, you have a button. It has an event handler. First thing you'll do is check to see if the current fullscreen element is the element you want to take fullscreen. In that case, cancel out.
Otherwise, request that element goes in. And that's it. That's a fullscreen button in one snippet. And additionally, if you want to react to the fact that the user has gone into and out of fullscreen mode, just listen for the WebKit fullscreen change event and check to see what happened and react accordingly.
However, this is available right now only on Safari Online. So you'll want to fall back to a different fullscreen mode, perhaps, on platforms that don't support this new API. So to do so is as easy as checking to see if your element has a WebKit fullscreen method. And if so, use the new API. If not, fall back to a different browser-specific fullscreen mode, or perhaps an in-window, full-window mode. There are some caveats, however, like there always are.
This spec is an act of development. It is just a proposal, and though we've implemented it here in Safari, it's likely to change in the future. So you should keep this in mind. Also, when entering into fullscreen mode, we disable most keyboard input. For security reasons, we don't allow the users to press alphanumeric keys when they're in fullscreen.
You still have command keys, arrow keys, spacebar, other things you might need to implement some kind of run-and-shoot video game in fullscreen mode. but alphanumeric keys are disallowed. And also, if for some reason your fullscreen request is rejected, there is no error or event that is thrown in response. But with the information we've given you here today, you should be able to accurately know when your fullscreen request will be acted on or denied.
So, to demo this and everything we've talked about so far, I'd like to invite Eric up to show you how this works in practice. So, what we have here is a basic video player using exactly the code that Jer just walked you through. You press the play button, it begins to play.
We don't have any volume, but I guess we don't need it right now. You can drag the slider. Again, this is an input type of range, as you can probably see, because we didn't change the style very much. There's a simple button to mute and unmute. You can see the volume change events are being fired there. So here we have a basic-- well, actually not a basic controller, a full-featured controller using just a little bit of code that Jer showed you. OK. The next thing you'll want to worry about after you've made your own custom controls is accessibility.
So why? First things first, you'll want to maximize your audience. And this is something that actually I heard during a Google I/O presentation, that the number of internet users in the United States using an assistive browsing device when browsing the web is a larger number, larger in population, than the entire online population of Canada.
So the number of people out there who need to be able to have an accessible experience with browsing your site is huge. So it's something to keep in mind. Also, you may be under some kind of legal requirement to have your site be accessible for a variety of reasons. But finally, it's just the right thing to do. Denying a large group of people access to your site, you want to let as many people in as possible.
So, first thing to consider, we're going to briefly cover this, touch events. There's a lot of people here with iPads and iPhones, and none of those iPads and iPhones has a mouse. So, anytime you're developing a custom JavaScript controller, you need to worry about touch events. So, generally mapping, touch start, mouse down, touch end, mouse up. Touch move, mouse move, and there's really no corollary to touch cancel, but if something interrupts your user in the middle of a gesture, you want to handle that one as well.
And if you're doing super advanced things with gestures in your video player, you might want to use gesture start, change, and end, which are fired when the user uses more than one finger in a gesture. So, if you want to have a volume knob that the user actually rotates, this is what you're looking for. Okay, put that out of the way. There's another thing you'll want to know about, and that's VoiceOver. Now, VoiceOver is a screen reader that's built into both iOS and Mac OS X.
And support for VoiceOver is also built into Safari. And this support is based on the Accessible Rich Internet Applications, or ARIA, specification. So what does this look like? Well, first, here's a non-accessible set of controls. You have a div here that when the user clicks on it, plays and pauses the movie. Maybe it even changes state and says pause when it's playing and playing when it's paused.
You also have a div which represents the progress through the video as a width. So, so far, great, except when VoiceOver sees this content, it has no way to know that this is a play and pause button. It has no way to know that this is a progress meter underneath it.
So how do we let assistive devices like VoiceOver know more about our controls? Turns out it's really easy. For the button, you would add something called a role attribute and set the attribute to button. And after that, as the screen reader is browsing through your DOM, it sees that. Notice it's the button.
And now it can allow the user to navigate through your controls, interact with them without using a mouse. Again, with the progress meter, set the role to progress bar, and it knows that is a progress bar and can relay that information back to the user through voiceover. More roles are available, such as application and slider. And for all of these roles and the values that are attached to them, please take a look at the ARIA specification found at the W3C's website.
So, to demonstrate the accessibility features of Safari and how you would build it into your custom controller, I'm going to ask Eric to come up and give you a short demo. What we have here is your same basic controller. We can see we can start it. We can stop it. We can scrub. But let's see what a user of VoiceOver experiences when they interact with the same page. VoiceOver on Safari, custom controller. So we'll turn on VoiceOver. Let me turn it down a little bit.
And we'll navigate down into the page. And VoiceOver sees that we have an element here. It knows it's called play. You are currently on a text element inside of HTML content. But it sees it as a text element. So it knows that it's an element. It knows it has -- well, it says that it's a play element. But when we try to interact with it with the VoiceOver keyboard gesture -- Slider, Fs. It doesn't know anything about it. We'll go back to it.
So a user who's using VoiceOver doesn't have any way to interact with it. Here it sees that we have a slider, and we can interact with it. But again, VoiceOver doesn't know how it's being used. So while the user can interact with it, if they can't see the screen, they aren't actually able to do anything with it. So let's go in here.
And fix this up. As Jer said, telling VoiceOver that these things are buttons is as easy as adding role equals button to the div. So let's save it. We'll go back. Reload our page. Turn VoiceOver back on. VoiceOver on Safari. Interact with HTML content. Interact with button. Now, it sees that it's a button. Press button. And, in fact, from the keyboard, I can turn it on and off.
Press button. But you can see that while we're changing the title, when VoiceOver pushes the button, VoiceOver isn't announcing it, because now it's a button. And so it's not reading the... "It's not reading the content, but luckily that's also easy to fix. We'll just give it a title." So we can say title equals play. Let's give all our elements titles. Timeline. All right, so let's turn on voiceover and see if it actually works. VoiceOver on Safari, Custom Controller, and Play button. Okay, let's interact with the page.
[Transcript missing]
We changed that state by, in the JavaScript, when we get a playing event, we change the class name, which makes CSS change its title. So we'll do the same thing here. When we get the play and pause, load it again.
Turn on voiceover. Voice over on. Interact with HTML. So now. Interact with press play button. So when we go off it. timeline slide pause button now it sees it's a play button it sees it's play button press pause button so that works well press play button timeline slide interact with slider we while we can we can control it again voiceover doesn't know stop pause press pause button play button voiceover off so there's one more thing that we should do and we will add an aria attribute to the Slider.
Whenever the time changes, set the ARIA value as text to the current time as a string, which, again, lets ARIA know more information about that slider. Reload our page. VoiceOver Back On. VoiceOver On Safari, play button. Press play button. And now. 0.6 seconds, timeline slider. Interact with slider. 4.6 seconds. So now. 6.0 seconds, pause button. Press pause button. So with just a little bit of extra markup, we've -- You are currently on the button inside of HTML content. VoiceOver Off. Thank you, VoiceOver.
So, you know, I mean, It's sort of a laugh for us because we can see it, but somebody that is trying to interact with your media content, they can get a lot out of it. By implementing a custom controller, you lose all of the accessibility that's built into the default controls, which are fully accessible.
Eric Carlson, Jer Noble And so you can see that just by adding a little bit of extra markup and a little bit of extra logic to your JavaScript, you're able to restore the full functionality of your media controller. Eric Carlson, Jer Noble There are similar ARIA attributes that you can and should add to the rest of your page to make the other custom UI and markup accessible. Eric Carlson, Jer Noble Thank you. Eric Carlson, Jer Noble Okay, back to slides. Okay, so now you have a fully accessible custom set of controls for your HTML5 media content. But there's something else you can add, and that's subtitles.
So this is an area of active work within the World Wide Web Consortium. And on this front today, we have good news. And that news is what working group has decided on a file format. There you go. Okay. The file format they are proposing is called WebVTT. It's based on the SRT file format, and for detailed instructions about the format they've chosen, check out the What Working Groups website at whatwg.org.
Concurrently, the W3C has been working on the rendering of text tracks into your video content. And one works really well with the other. You have WebVTT to load subtitles into your video element. Here's the catch. No browser yet supports WebVTT in specific and time text in general. There's a lot of work in WebKit to enable this, but no shipping browser supports it.
[Transcript missing]
You add some track elements. In this case, we're going to add two track elements, an English and a Spanish subtitle track. They have a kind, a source, just like a source on a video element, a source language, and a user visible label. And that's it. That's what you need to get your subtitles overlaid on your video.
So what does the API look like, though, if you're doing this from code? Well, a given text track will have a kind. And that kind can be, according to the spec, subtitles, captions, descriptions for descriptive audio, chapters for chapter-based navigation, and a generic one called metadata, which is not meant to be displayed, but is very useful if you're writing your own custom scripts.
There's a user-visible label for things like chapter one, the language of the track, perhaps the kind, in this case, director's commentary. There's a language string, which is some ISO code that can be anywhere from an EN to the type of German spoken Austria to the type of Spanish spoken in Latin America. The track will have a ready state, which lets you know whether or not the resources backing that track have been completely loaded yet.
and a mode so you can switch these tracks on and off at will from JavaScript. Additionally, they have two sets of arrays, one set of cues that is all the cues that are in the track, and a second array of those cues which are currently active, meaning their start times and end times enclose the current time of the movie. And when this list of active cues changes, the track element will emit a cue change event you can listen to for doing your own custom scripting.
Okay, like I said, there are a couple of arrays of queues, and those queues have an API of their very own. First, they all have a back pointer to the track which owns them. They have a unique ID that lets you target each queue individually, if you so desire. It has a start time, like I said, and an end time, which defines those areas, which those areas of the timeline in which that track will be active.
There's also a property called pauseOnExit. So if a queue has pauseOnExit set to true, and the movie, while it's playing back, hits the end time of that track, the movie will pause. And the reason for this is so you can do accurate, very accurate pausing at certain times of your movie.
So if you need, for some reason, the movie to stop at a very specific time, this is what you'd use it for. As they become active and inactive, they will emit a enter and exit event. And you can always ask a queue for its raw source with get queue as source, or you can get a document fragment back of parsed HTML from get queue as HTML.
Finally, if you want to implement your own parser, if you don't like the web VTT format, you have a lot of things that are in time text, you can make these tracks up from scratch with a mutable text track by adding cues in one at a time that you've made from parsing out a file of your very own. Okay, but we talked a lot about captions. This is the header of my first slide. But this isn't all about captions, of course. It's about time text in general.
And in specific, it's about any text that has to occur at a specific time. Also, video is not easily searchable. When Google spiders your website, it's not going to look through and do a speech-to-text transform on all the tracks in your movie to get backlinks and allow people who are searching for a specific phrase to go be directed to your website. However, they will spider your text tracks.
And so if you want to pull people into your website, this is a great way to do it. Add subtitles to all of your videos. Also, translating your videos in different languages is pretty hard. You have to find a voice actor, and we know how hard it is to work with those guys.
I have some voice actor friends. They'll get the joke when they listen to this later. Anyway. But text tracks are inherently machine translatable. You can just drop one into Google, and it'll spit one out in whatever language you ask for. And so you can broaden your audience to speakers of many, many other languages just by adding a few text tracks to your video, and then translating them with Google or any other translation tool into a plethora of languages. And finally, text tracks are all about timing. If you want an event to happen at a specific time in a movie, text tracks are what you'll need.
And to demo the use of text tracks and subtitles with this polyfill library, Eric's going to give you a short demo. What we have here is an extremely boring demo. It's a video element. Actually, let's look at the source first. "Let's make this bigger so people can see it." So we've got a very plain page.
We've got a video element. Just like in the slide, a pair of source elements pointing to two alternate video encodings and a single track element. Again, we have captions in this, so we have kind equals, "Kind equals captions. We point to the VTT file. It's in English, so we label it as English. And then we also include, because this version of Safari doesn't support the track element natively, we include a reference to the Captionator, JavaScript Library.
And then when the body loads, we... "And what we end up with is captions. And suddenly we have all of the benefits that Jer was just talking about. Something that he didn't talk about and that we're not going to do here because it would be a bit to set up is we could also mark up this page so that VoiceOver automatically reads out the captions.
Now, it obviously wouldn't make sense for a page playing in English with English captions Captions to be read out, but if they were in a different language or if they were a different type of text track, we could easily hook it up so that VoiceOver would read those out.
And we didn't have to do anything. We're using HTML5 standard markup. It's not supported in this version of Safari. In fact, it's not supported in any shipping browser, but you can begin to use it now. And this JavaScript library is written in such a way that when this same page gets loaded in a browser that does have native support, it will just back out of the way and let the native support take over. So you can start to use this really exciting, I think, new HTML5 feature in currently shipping browsers.
-Jer, I have a couple of demos to show you myself. So I promised you a couple of flashy things, and so we're going to make some of these demos you'd seen previously a little bit more flashy. First of all, So these controls are very similar to the controls in the first demo. But one thing we've done was replaced all the buttons with SVG.
And so as we zoom in, the element looks just as good at this zoom level as it does in the original one. And so using SVG for things like icons is a great way to make sure that your controls look great on every platform and whatever zoom level your user is currently using. So that's one thing.
I just wanted to demonstrate that the sliders are incredibly easily stylable in CSS. So we've replaced the circular thumb with a square one that changes colors as you drag it. One more thing you can add to spice up your video controls. So here's your mute button and your volume slider, and when I reload the page,
[Transcript missing]
And finally, that's what it should look like. So here we have, in fullscreen mode, we have our own custom controls along the bottom.
That we can bring into fullscreen mode with us. OK, so that's the fancy controls demo. But we said a lot of things about text tracks. And one of the key features of text tracks is chapter support. So if we have a video here and you want to easily navigate between chapters, it's as easy as adding a select element with a bunch of options in it. You pull from the chapter file.
To let your users easily navigate around your video. And the best part is, does this machine have a simulator? Yes, it does. So if your user is using a-- oop-- spinning beach ball of death, then-- Let's change this to an iPad, and we'll rotate it so we get more screen real estate. Drop this guy on it.
And when you use this tool to do chapter navigation, you get platform-specific interface to pick and choose chapters without you having to do any extra work. OK. So that's that demo. What more can we add? Well, we have chapters. Let's add some subtitles and show you how to switch between them. So here's that same demo, except now we also are able to switch between different subtitle formats.
Because it's just normal HTML content, we're able to completely style differently the representation of those subtitles. In this case, we gave it a bit of a drop shadow and a background color that didn't take up the whole width of the screen. It's hard to see how something so simple, so thin, so fly-- And we can switch between them on the fly. And because it's just HTML content, it supports all the UTF character sets that normal HTML content would. --we learned so much from it and developed so many amazing technologies and all the applications-- Go back.
So finally, this is the real flashy demo. We talked about how you can choose between subtitles and chapters and captions and audio descriptions and something called metadata. So metadata is anything that isn't covered by those top ones and anything you'd want to use in your script. So what we did is we took a file and filled it with Base64-encoded keyframes from this movie. And now that we have that file, just in the same way that subtitles will pop up and disappear as you navigate through the movie, we can implement a timeline slider that shows you where in the movie you will be as you scrub around.
And so if you have a really long movie, one that probably takes a long time to load, This is a great way to indicate to your users where they'll be when they let go. So without having to load the movie in the foreground, you can let them scrub to a specific time they want and not spend a bunch of time trying to load that piece of the media in.
And the best part is, of course, just like all the rest of this stuff, it just works in fullscreen mode like anything else. And with just a couple simple lines of CSS, we can completely restyle the way our controls work and even maybe add a couple extra more features in here.
Well, I'm sorry. Add a couple more graphical features in here. So, like, maybe a cool-looking gradient on the controls and perhaps, like, some shadows on things. Whatever you can do in CSS, you can do in page, you can do in fullscreen mode as well. So, for more information about all the things we talked about today, please talk to Vicki Murley.
She's our Safari Technologies Evangelist. And also, there's a whole lot of information up on the Safari Dev Center on the developer page at apple.com. And the Apple Developer Forums, which I'm sure you guys already know about, are a great resource for figuring out how things work as well.
There's going to be a session on HTTP live streaming. If you're interested in doing that with your video coming up, let's see, what, at 4:30 today. There's going to be another session on understanding and optimizing web graphics on Wednesday. And finally, all the things you found out about accessibility, you can get more in-depth information for accessibility and automation on iOS on Friday. There's a lab directly after the session downstairs on HTML5 audio and video. There's going to be a live streaming lab on Wednesday, and Wednesday is also full of open labs for Safari. So come on by and ask any questions you didn't get answered today.
But in summary, I hope that this allows you guys to come up with some really fantastic looking controls for all of your content. And I also hope that the fullscreen feature is really exciting, as exciting to you as it is to me. And the subtitles and text tracks, I really hope you start adopting those right now. It's possible with these JavaScript polyfill libraries, and it will only get better in the future as browsers take over more of the work from the JavaScript. And finally, making your video accessible to everybody. I hope that we've shown you how and shown you how important it is.