Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2000-303
$eventId
ID of event: wwdc2000
$eventContentId
ID of session without event part: 303
$eventShortId
Shortened ID of event: wwdc00
$year
Year of session: 2000
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC00 • Session 303

QuickTime: Streaming on the Web

Digital Media • 1:00:10

QuickTime is the fastest growing and most powerful streaming technology. Learn to take advantage of new QuickTime Internet services and how your product can better integrate online content to bring these benefits to your partners and customers.

Speakers: Anne Jones, Kevin Marks

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Please welcome Kevin Calhoun. Oh, that's me, the QuickTime Streaming Engineering team, in person. Actually, several members of the QuickTime Streaming Engineering team will be here today to talk about, well, QuickTime streams on the web. This is not news to you. If you've been at sessions during the show, it seems to us anyway on the QuickTime team, as if almost every demo at the show includes a QuickTime movie, many of them streaming. This is wonderful for us to see because, after all, the tagline for WWDC 2000 is, "QuickTime is ploppable." If you missed the previous session, what that means is that QuickTime movies can show up everywhere.

QuickTime is, in fact, everywhere. In fact, QuickTime media, media that QuickTime can play, is everywhere on the Internet. Yes, QuickTime streams via streaming protocols, but QuickTime can also play files that are transferred via conventional file transfer protocols. And QuickTime can also handle connectivity, the network, media that's connected to other media via URL links.

We're going to talk in this session... about how you can take advantage of these QuickTime services in your applications. On the reception side, on the reception of media coming from the Internet, we'll talk about opening and playback of media in your applications. Now many of you already own or develop applications that can play QuickTime media.

Can I have a show of hands here? Who here knows all about opening a movie, instantiating a movie controller, closing the movie file, setting the movie controller action filter, Nobody? Anyone here do this in your app already? Excellent. I'll give the rest of you a link for where you can go to get information about how to open and play back QuickTime media in its most basic form.

But even those of you who do, if you haven't touched that part of your application for several years, we have some recommendations for how you can optimize your user's experience of QuickTime media, of QuickTime network media in your apps. That's the chief part, the chief topic of the first part of our talk today. Then we're going to talk about some things you should be aware of if your application actually edits media.

There are some surprising things that are showing up now in QuickTime movies. If you wrote your app three or four years ago even, and you're editing QuickTime media, you should be aware of some things that show up in streaming movies and how to deal with them. We'll also talk about how your application can mediate the linking of one piece of media to another. Thank you.

But we're saving the best for last today. For the first time publicly, we're talking about our QuickTime streaming broadcast APIs. Not just the reception side, but how your application can be the source of streaming media on the web as well. That's coming up here today in this session. You're in the right place.

Some of you are applauding and some of you are just saying, "Finally." Okay, I told you for those of you who are not yet playing QuickTime media in your application, I'd like to ask you why. Now that you know at this show all the things that QuickTime can do, not only play stream media but also interactive media as well.

In fact, you can embed a calculator in your application just by using these APIs as we saw at the previous session. Go to the URL www.apple.com/quicktime, click on the Developer tab, and that will take you right to the right page within Apple's Developer site for you to get documentation, headers, sample code for how to get started with playing QuickTime media in your application.

Also, you probably want to participate in the QuickTime mailing lists. There's a QuickTime API mailing list that you can sign up for. There's a QuickTime talk mailing list. There's a VR mailing list. Go to list.apple.com, search for QuickTime, find the mailing lists that are interesting to you, and you'll begin participating in the discussion with members of the QuickTime team and other developers who are using QuickTime in amazing ways.

Okay, so let's now talk about the topic of receiving media on the web via QuickTime. QuickTime supports two flavors of such reception. And there's a tradeoff, of course, as you know on the Internet, between getting the media as good as it can be and getting it as fast as we can get it.

The tradeoff is, in fact, between integrity and expediency. You either want it real good or you want it right now. QuickTime allows you to make the choice of how a content developer wants to deploy media on the web. And your application can handle the media regardless of the choice that the content developer makes.

If you want the best content possible, for example, the movie trailers that are up on QuickTime's movie trailer site, FastStart is the mechanism that QuickTime offers. We use standard file transfer protocols, HTTP and FTP, and QuickTime can play the media that's being transferred by these transfer protocols before it's all there. That's why we call it FastStart. As soon as there's enough media to play, we'll start playing it.

And you get the best quality because those file transfer protocols guarantee the fidelity of the media transfer. However, for many applications, the choice of real-time streaming is more appropriate. In other words, for a live broadcast, for example, you don't want to wait for a file transfer. You want the broadcast to keep up with what's happening live.

Well, a real-time protocol is appropriate for this choice, and QuickTime now does that also. That's the form of timely data transfer. We support RTSP and RTP. All of the transfer protocols that we support in QuickTime are, in fact, IETF standards, and they work with servers of many different varieties.

Okay, when will network media come into play? Are you safe from things like network latency? Well, if your application opens QuickTime media, even if you haven't touched that portion of your application since 1992, it already does play network media. Even if all you use is the QuickTime API call "new movie from file," you should be aware that local files can contain references to external media, and your application might require, when it calls "new movie from file," the user to wait for a network transaction to occur.

We'll talk about how you can make that experience better in just a minute. If your application is a little bit broader in its approach to opening QuickTime media, you might be calling "new movie from data ref," which would allow your application to be able to access the data from the data source.

You might be calling "new movie from data ref" to your application to open QuickTime movies via URL, such as HTTP or FTP or RTSP, or any other form of reference of media that QuickTime supports. Even forms of reference that QuickTime itself doesn't support, but which have been added by third-party developers as extensions to QuickTime. We'll talk about how you can add support for "new movie from data ref" to your app so you can open movies directly via URLs.

You should be aware that when you do this, network transactions will be more efficient than ever before. For example, for FastStart, a very typical transaction for an HTTP URL might be a request from the server, a GET for some media, and then the transfer begins. This transfer could take an awfully long period of time, and we have requested specifically that the QuickTime sessions be across the street from the main hall, so that we'll have a slower network over here so I can show this to you in just a moment.

The series of transactions that occurs for a streaming movie are somewhat different. If you send an RTSP URL to a streaming server, there's a transaction that occurs first that first returns to you a session description for the stream that will then ensue, and then a network session will be established that allows the media to be transferred. So the transactions are a little bit more complex. Again, there might be some delay in this occurring.

One other wrinkle that you should be aware of when you're playing network media is that QuickTime may intervene. If the user's connection settings in the QuickTime control panel are set not to allow multiple simultaneous streams, then QuickTime will devote all the available bandwidth between the machine and the network to the particular stream that has the user's current focus, usually the last one that the user opened or the one that the user last clicked. I'll demonstrate that as well. That's all just to tell you that there may be new wrinkles in your user's experience of your apps because of network media. Okay, let's see some of this in action over here on demo one.

What I decided to do was to prove to you that even your legacy applications could play network media. So I went and I dug through my office, which those of you who know my office realize is no simple feat, and I came up with some old QuickTime CDs.

I found QuickTime 3, I found QuickTime 2, I found QuickTime 1.5 and I decided if I went back any further than that I was inviting some danger. So off of QuickTime 1.5 CD-ROM from 1992 I pulled off MoviePlayer 1.1 and I'll show you MoviePlayer 1.1 D1 is actually the version string that we shipped with QuickTime 1.5.

You'll have to ask third party developers who may be present in the audience why that was the version number for that version of QuickTime. What I want to do is to open some local files with MoviePlayer 1.1 that reference network media. So I happen to have some here. This particular movie is a movie that's coming off an HTTP server, which I happen to have running right next to me here.

And I'll drop this file, which is fairly-- that's not the right one. Here it is. Here's the file that has the reference to the HTTP URL on the server. You can see that this particular movie is only 22,000 bytes. If I drop this on MoviePlayer 1.1, you'll see that even MoviePlayer 1.1 is capable of playing network media. What you see happening there at the bottom of the screen is an indication of the state of the download. 5, 6, how many?

[Transcript missing]

You can do it without laughing at Dan, that's funny.

Okay, so what you saw happening at the bottom of the screen was an indication of not necessarily the progress of the file transfer, but of course in QuickTime what matters more is how much of this movie can we actually play right now. So let me just drop that on again. Watch the bottom of the screen and watch the progress of the download occur. By time, not by file size. That indicates how much of the movie is currently playable, the first minute, the first two minutes, what have you.

MoviePlayer 1.1 from 1992, which predates QuickTime's ability to stream, can also play streamed media. I have that same movie compressed for streaming. Let me drop that onto MoviePlayer 1.1. And here I'll click the play button and you'll see the typical experience of a streaming movie. The transaction occurs between the client and the server. And then once the movie becomes available to play, it plays.

Let me show you that again. In this particular case, we're not waiting for a file transfer to occur. We're waiting for the transaction between client and server to occur. It goes through multiple stages. And you'll see status messages in the movie controller to indicate each of the stages. Negotiating, buffering, here they come again.

If I should change the time within this movie, then of course I have to negotiate with the server to play later on in the stream. You've got bugs. You've got bugs. You've got bugs. Oh, that's too bad. That was a good one, too. I play that myself so that no one else has the privilege of embarrassing me.

Okay, so now you've seen the typical experience of playing streaming media using standard QuickTime stuff. If you use the standard QuickTime controller, that's the experience the user can have in your application as well. Let me show you an application that allows me to play QuickTime media in line.

Outlook Express allows me to send a QuickTime movie file from my mail server to somebody else, and when that other person receives the mail file, the movie will play in line. So I sent myself a streaming movie, and I can play it here in Outlook Express. Which allows me to play streaming movies right there in the mail doc.

So even without you being aware of it, if we go back to slides, your users may be playing network media in your applications. Now there may be some problems that can arise, if we can get back to slides, With that experience, because as we all know, the Web has some interesting characteristics. Foremost among these is it can be slow, especially if the packets have to cross the street.

Secondly, media that you play on the Internet may be dynamic. You may not know everything about the media when you first open it that there is to know. For example, in the case of streaming movies, when we are having that early transaction between the client and server, the client may not know at what size the movie wants to play or even the duration of the media.

Those things might only become known subsequently. Well, how do you deal with that? We'll get to that in a moment. Also, media on the Internet is interesting, like other things on the Internet, because it can be interactive. It can link from one piece of media to another. You might want to mediate that linking in your application. We'll talk about that.

Okay, let's drill down on some of these things. The net can be slow, of course, because there may be limitations in bandwidth between the client and the network. If I'm on a very slow modem, for example. But other problems may occur at other points on the network. There might be a router between the client and the server which is congested and can't keep up with all of the packets that have to be routed through it.

There can be a delay there. Finally, as we saw demonstrated so dramatically with denial of service attacks recently, servers can be overloaded and for that reason they can be slow. The point is, quite beyond any one person or any one organization's control, there can be delay, for one reason or another, in a network transaction.

Movies can also be dynamic. I mentioned earlier that dimensions of a movie might not be known, so they might have to change from an unknown to a known state after a movie has been opened, or they might change from one known to another known state, just because the movie wants to play at a different size. Duration of a movie can change, again because you might not know it and then later it might become known, but also because it might change from one known state to another.

For example, a stream might be set up as a live broadcast and at some point, towards the end of an event, the server might tell you what the rest of the duration is, because it's set to close down after five minutes. How can you become aware of such a thing hours after you open the movie? Also, movies can stop.

You might set them to play, or your user might set them to play, but they might be authored to pause for one reason or another, or bandwidth restrictions might come into play and QuickTime itself might intervene and stop a movie in order to devote bandwidth to something else.

Finally, movies can be interactive. They might be smart movies, such as QuickTime VR movies that allow you to navigate them left and right, up and down, because of direct user manipulation. Or they might have state. A lot of Flash movies, for example, are authored in such a way that when the user clicks a particular button in the movie, a set of options then become available. There might be different pieces of content, a tab, for example, with different pieces of content, or perhaps it might transition to a different segment of the Flash movie that presents something different. These states are navigable by the user.

The movies might also have links to external media. These links might be automatic. A movie might play and automatically send a link to a web page or another piece of media. Or they can be links that require user intervention, something that you click on and then the link becomes available. Let me show you some examples of dynamism on the QuickTime TV that we have right now. So on demo one, I'm going to open up the QuickTime player and show you some new channels in our QuickTime TV channel drawer.

The inventor of which I can't mention. I don't happen to have an example of this just now because I remembered I left it in the office. But you can play a movie that automatically tells the client to go to a web page or goes to a different piece of content. This can also occur. How can your application know when this occurs? How can you mediate? Those are things we'll talk about now as we get into some API details. Back to slides.

You can handle all of these things gracefully. Slowness, we'll call it asynchrony, just between you and me. We can handle media that's dynamic, media that's interactive. First thing that we recommend is that you go ahead and support URLs in your application. Those of you who already call new movie from file in order to open local movie files can easily add new movie from data ref in order to support the opening of movies via URL. I have a code snippet to show you in a moment.

You should be aware, as we just mentioned, that this can take a while, and we recommend that if you do this, you provide an affordance in your UI for recent URLs so the user can have a history of where he or she has recently visited available in your app.

How do you do it? How do you open URLs in your app? If I know I want to go to http://qtvote.net/movie, can I just type that into your app and go there directly without opening a file? Yes, I can. Here's how you do it. You can do it in your application. The key API call, new movie from data ref.

A data reference is just a record, just a structure in QuickTime that tells us what kind of reference it is and then also the data for the reference itself. In this case, a URL reference has a type URL data handler subtype, and the data in that data reference is just a handle full of characters terminated by a null. So you can do this in your application just by allocating such a handle. Putting the characters of the URL in, make sure it's zero terminated, and call new movie from data ref. And you instantly have a feature exactly the same as open URL in QuickTime player.

Of course, you might also want to do this programmatically based on other things that are occurring in your app. If you have a multimedia app, you can easily add this, not as a user feature, but as something you want to make available under the covers. For example, an authoring app like Live Stage.

When you are opening a movie for playback, our strongest recommendation is use the movie controller. APIs exist in QuickTime so that you can control playback without the use of a movie controller. However, you lose many things when this happens. The movie controller is our mechanism, QuickTime's mechanism, to inform you of changes that occur in the media as it plays. The movie controller is also our mechanism for handling things like asynchrony, for handling things like interactivity.

If you don't instantiate the movie controller and attach it to the movie, it's much more difficult for us to present these features. In fact, the only reason that MoviePlayer 1.1 from 1992 knows how to play fast start media and streaming media is because it uses the movie controller. And by instantiating a movie controller, it gets the latest and greatest features. It gets the latest and greatest version of the movie controller, the one that we shipped with QuickTime 4.1.2. So therefore, that's how it knows how to do all that cool stuff.

You should be aware that the user interface of the Movie Controller is optional. The experience that I showed you in MoviePlayer 1.1 with the standard Movie Controller is something that you can override. In one of the demos yesterday of the MovieShaker application, they had completely overridden the standard look of the QuickTime Movie Controller. In fact, QuickTime itself does this with the QuickTime Player. You can do the same.

Programatically, once you've instantiated a Movie Controller, how do you start the movie? If you don't want the user to do it, you want to do it yourself. Send the Movie Controller the action via MCDoAction, the API call, MCActionPreRollAndPlay. That will take care of, from now and forever, network media, local media, all the different wrinkles.

All right. How do you detect edits? How do you know that the duration of a movie has changed? Once you've instantiated MovieController, you need to install a MovieController action filter. That's a callback routine that you write in your application, and you let us know what it is, by means of an API call. That allows us to call you to tell you everything interesting that's going on in that movie.

For example, to find out if the duration of a movie has changed, look for the action, MCAction Movie Edited. That's how we tell you. That's how the QuickTime player, for example, knows that a stream has a fixed duration, as opposed to an indefinite duration. If it doesn't receive an MCAction Movie Edited action through its MovieController action filter, it assumes the stream is a live broadcast.

How do you know that media wants to resize itself? Well, first of all, we're very nice to you in that we don't insist that you support media that's dynamic in this way. If you're not prepared in your application to handle movies that resize, then we won't try to resize them.

But if you are prepared, then what you can do once you've opened a movie is to set the movie play hint "Allow dynamic resize" as you see up on the slide, and that will tell QuickTime that you're prepared to handle dynamic resizing. How do you know when the movie wants to resize itself? Again, your movie controller action filter will tell you. Look for "MC Action Controller Size Changed." You can get the size that the movie wants to be now and resize your window, if that's what's appropriate, or layout your page, if that's what's appropriate.

Okay, actually I'm going to skip this demo and come back to it in a moment because I have some other API calls I want to go through first. This MovieControllerActionFilter, this has a lot of intelligence associated with it. That's what you're sitting there saying right now. Yes it does. In fact, all of the things that we do in our own user interface, you can override.

You can get the streaming status messages. When is the movie buffering? When are we negotiating with the server? We'll tell you in that MovieControllerActionFilter, look for this particular action, show status string. And in the QtStatusStringRecord, you'll get a string along with some flags to tell you what kind of string it is that you can display.

Okay, what about interactivity? Movies want to link from one place to another. I want to know when this is happening. Or I have a special way to resolve URLs. Or I've built media that's specifically for my application and I want to mediate all of the URL linking that occurs within my application. How do you do that? Again, in your MovieControllerActionFilter, there's a particular action to watch for: MCActionLinkToURL.

When you see that, we will give you the string which represents the URL that the media is trying to link to. And you can do whatever you want with that URL. If you wish, you can handle the link yourself and open the media directly in your application. If you do that, just set the return value of your function to true and QuickTime will not perform its default handling. We'll assume that it's not. But you've done it.

You can change the URL that the media is trying to link to. You can resolve it. You can do character substitution, what have you. Put the URL back into the parameters that you get. Set handled equal to false. And QuickTime then will perform its standard handling but with the URL that you gave us.

Okay, if you are going to do this overriding of URLs, you should be aware that some interesting things may pop up in these URLs. You might not get them just naked URLs, HTTP or RTSP and so forth. We also encode other information into these strings as well. For example, if media has been authored to link to a movie within the QuickTime player, just as in an HTML webpage, there will be target information associated with that URL that you are going to want to have to know where the link should be represented, where it should be carried out. In QuickTime, we give you this information in the same string as the URL. The format is, as you see here, the URL is bracketed with angle brackets. A T will represent the URL.

A V will represent the URL. A V will represent that the target information follows. Then within another set of angle brackets, we will give you the target information. The target can be the name of a frame, just as in HTML, which QuickTime player, by the way, interprets as the name of a window.

It can be some special string values such as myself, which means replace me, the movie that wants to link, with whatever this link points to. It can be web browser, which QuickTime interprets to mean show the link in a webpage. Or it can be QuickTime player. Now, these might not be the only weird things that show up in these URL strings. In fact, they're not. Right now, what we're recommending is, if you see anything you don't recognize, then don't try to handle it yourself. Just pass it through to QuickTime, and QuickTime will deal with it.

In the future, we're going to be talking about a more robust mechanism that's more generalized for URL linking, but for now, this will get you started with mediation of QuickTime URLs. You can see more of the kinds of interactivity that QuickTime movies can play. If you missed the previous session, you missed some great demos of this. But also tomorrow morning right here at 9:00, more interactivity will be presented. And as you witness that, remember that you can mediate all this in your application.

Okay, so we dealt with several of the characteristics of the Web. Here I'm standing on stage dealing with three prime characteristics of the Web before you're here today, feeling really important. Dealt with interactivity, dealt with dynamism. The only thing left that we have to deal with is slowness. So what we've decided to do with QuickTime 4.1.2 is to distribute a T3 with every version that you download.

And that's it, so we can skip the rest of these slides. But in fact, it turns out that there are export restrictions on T3s, and so we can't make them available to everyone here in the room. Therefore, some of you might still be suffering through slow connections for one reason or another.

Therefore, we're recommending that those of you who open and play QuickTime media in your apps be prepared to deal with slowness by allowing QuickTime to handle network transfers asynchronously. Now, asynchrony is not new to QuickTime, of course. We've been dealing with it in web browsers since the very first release of the QuickTime plugin.

And of course, we're dealing with asynchrony with QuickTime streaming. But for the first time publicly, we're talking about how you--well, the first time publicly in Northern California, anyway--we're going to tell you how you can add this to your own applications and not force the user to wait for a slow connection.

Now what you should be aware is once you give permission to QuickTime to do things asynchronously, movies that you open might not be in a state that you expect. They might not immediately be playable. They might not immediately be savable because you've told QuickTime, "Do this asynchronously. Let it happen when it happens." You as the application take on the responsibility for inquiring what state a movie is in before you perform an operation with it.

OK. How do you do it? When you call new movie from file, or new movie from data ref, set in the flags field, the flags parameter of those calls, new movie async OK. That's your permission for QuickTime to do things asynchronously. Then, a movie will be returned to you that may not be playable, may not be saveable.

It's up to you to call get movie load state to find out what state it's currently in, to find out what you can do with it. And then if an error should occur, you can find out what that is by calling get movie status. Was there a problem with a network transaction? Do I, am I missing a codec for this particular piece of media? Call get movie status to find that stuff out.

Okay, you can combine the flag newmovieasyncOK with other flags that you may already be using when calling newmoviefromfile or newmoviefromdataref. It just ores right in there and we're happy with all that. The flag's field is what, thirty-two bits? Are we running low? No? Okay, we have a few more. Stay tuned next year, come back.

GetMovieLoadState that tells you what state the movie is in currently currently returns the following values. There may be an error. That would be a negative value. You can then call GetMovieStatus to find out what's wrong. We might tell you that the movie is currently loading, in which case wait a little while longer before calling GetMovieLoadState again. We could tell you the movie is playable, which means you can immediately start to play it.

However, that can occur before the entire movie has loaded. You saw earlier that QuickTime handles fast start media by allowing playback before the entire transfer is complete. So a movie can be playable, you should note, before the loading is done. When everything is loaded, getMovieLoadState will return load state complete.

At that point, it's safe, for example, to save the movie to a local file if your application enables that. So here you can see that you can compare these return values arithmetically. The more advanced load states are arithmetically greater than the less advanced ones. It's pretty smart how we managed to figure out how to do that all by ourselves in Cupertino.

OK, if you get an error when you are loading media for one reason or another, you can find out exactly what went wrong by a getMovieStatus. That will return you a component result that, uh, will give you an indication of the error that occurred. What I want to do actually is go back to demo one. There's a fast guy back there. All I have to do is walk over here. Watch this. I walk over here, he goes, "No, I won't do that to you.

Sorry." What I have here is a URL in my scrapbook, which I will now copy. And I have a very smart application, which is actually quite small. This little application, which actually has a lot of stuff linked into it that I can't talk about, so I won't show you how big it really is, could be much smaller.

All it knows how to do are the basic things for opening QuickTime media. Open movie from DataRef. I'm sorry, new movie from DataRef. New movie controller. Set a movie controller action filter. Close the movie file. Let it play. That's all this thing knows how to do, but it also allows QuickTime to do things asynchronously.

It has an open URL menu item that allows me to paste in a URL. This is a particularly large movie that might take a while to transfer, although it's actually right next to me here, the server is. What you'll see this application do is while the movie's load state is prior to playability, what it will do is display a loading message. So here you see that it's currently loading, and as soon as the movie becomes playable, then it actually displays the movie in a window.

Let's see. Oh, I haven't got the URL for the even slower movie out on the Akamai network that I can show you. That would allow you to see that loading thing a little bit longer. Your application can choose what to do while the movie is loading. The whole point is, while it's loading, I have control over the menus. Boy, that was quick, huh? I've already returned control to the user. I'm not waiting for a new movie from DataRef to return. I'm actually checking the state of the movie independently.

[Transcript missing]

Now, we're going to move over to a second topic for this particular session. That covers my part of the session. What we're going to talk about now is some features that you should be aware of of the streaming APIs. If we can go back to slides.

We're going to talk, Anne Jones is going to come out here and talk to you about some things you should be aware of when you open movies that are streaming, they can have surprising things inside them that you may or may not be aware of. So she'll tell you all about those details now.

I'm going to talk about some of the things that you can do when you use the streaming APIs. Now, why would you want to use the streaming APIs? If you use just the plain movie APIs, you can get pretty good streaming playback experience. But if you want more information about what's being streamed or more control over what's being streamed, then you should use some of the streaming APIs. And also, as you'll see later, if you want to do a broadcast application, you'll have to use the streaming APIs.

With streaming, two new track types were introduced: hint tracks and streaming tracks. Hint tracks are found in movies that are put on servers, and the streaming servers looks at the information inside these hint tracks and forms RTP packets out of them. The really cool thing about using these hint tracks is that it makes the streaming servers media agnostic and codec agnostic.

So, for instance, later this year when we introduce MPEG streaming, we'll have to, of course, rev the client to handle streaming of MPEG reception and also rev the hinting components so that we can hint MPEG movies. But these movies can be placed after they're hinted on the streaming servers that are out there today, and the servers can just stream them without knowing anything about MPEG movies. If you have an authoring app and you want to add hinting to your app, it's done through the basic QuickTime export components. Something to remember is that if you have a movie with a hint track and it gets edited, then the movie needs to be re-hinted.

The other kind of track are streaming tracks, and these are found on movies that are on the users' machines. And API-wise, there's a lot more that you can do with these. The streaming track usually contains a very small sample. The amount of data is like a RTSP URL or SDP data. And when these movies are first opened, so they only have this URL, and they don't know anything about the media that's going to be streamed.

As the stream track contacts the server, it gets more information from the server and it starts knowing more information about the things to be streamed, such as the number of streams, the media type of the things that are being streamed, the dimensions, the duration of the thing being streamed, etc.

Something else to remember about movies with stream tracks is that they really should be pre-pre-rolled. And pre-pre-roll is sort of like an async version of pre-roll. And if you use the movie controller, pre-roll and play, you'll get that automatically. But anyway, during pre-pre-roll, that's when the streaming track contacts the server, gets all the information, buffers up some data, gets ready to play.

And if you don't pre-pre-roll these movies, then your playback at the beginning will be pretty bad and you'll lose lots of data at the beginning. Okay, if you want to use the streaming APIs, include QTSMovie.h and QuickTimeStreaming.h. You'll mostly make the calls QTS Media Get Info to get information about the presentation as a whole or QTS Media Get In the Stream Info to get information about a particular stream.

If you have a movie, to find out if you have a stream track in it, call getMovieIntoTrackType with kqts-streamMediaType. Once you have the stream track, you can get the stream media handler from it. Once you have the stream media handler, there's all sorts of information you can get about what's being streamed. In this example, we're getting the average running data rate and the average loss percentage of the thing that's being streamed. And you do this by calling QTSMediaGetInfo with particular selectors. Okay, another thing you can find out is how many streams are coming from the server.

Once you have the number of streams, you can find out information about each particular stream. In this example, we're getting the media type of a particular stream and also the sample description. There's lots of other information that I'm not showing here that you could actually get, such as the frame rate, the dimensions, volume.

OK, if you're going to use the streaming APIs, there's some errors that you should be aware of. QtS unknown value error means that the thing that you're querying doesn't know the answer yet, but it might later. So for instance, the streampack has just contacted the server, and some information has come across, and it knows that there are three streams, but it doesn't know the media type of these streams yet.

So if you ask for the media type of a particular stream, you'll get back this error. Later on, if you ask for the media type and it's gotten that information, then it will return the actual media type and return no error. QTS bad selector error, on the other hand, means that the thing that you're querying will never know the answer, and so you shouldn't try again. And an example is if you make volume info calls on a video stream.

Okay, if you want more control over what you're streaming, then you'll need to use the QTS presentation calls. A QTS presentation is a set of streams with one timeline. So you can think of it as the set of streams that one stream media handler would control. And in fact, the stream media handler is implemented using the QTS presentation APIs. And these APIs are the same ones that you can find in QuickTimeStreaming.h and the same ones that you can use in your apps.

If you have a Stream Media Handler, you can get the presentation from the Media Handler by calling QTS Media Get Info with the appropriate selector. Once you have the presentation, there's all sorts of things you can do with it. An example here is if you're streaming a movie and it's got two audio tracks, you can change the volume of the audio tracks independently by calling QTSPresSetVolumes on each audio track.

And this is something that you can't do using the movie APIs alone. So this is just a very brief introduction of things you can do using the streaming APIs on playback. And if you're more interested, look in the file QuickTimeStreaming.h. and Kevin Marks will tell you more about the broadcast specific portions of the streaming APIs.

Hi, the Streaming Broadcast APIs is not something we've covered before. I'm going to discuss them briefly here and show some demonstrations of things you can do with them. If you want to get access to these, I'll tell you at the end how you can be seeded with these as we develop them.

So the way QuickTime streaming is organized internally is that transmitting is parallel to receiving in API terms. Both of them are QTS presentations, as Anne just discussed. There are different components that are used inside the broadcast side. There are sources that provide sample data. Packetizers then break that up for the net, and it's then sent out over various different network configurations. Anne just mentioned QuickTime presentations. Again, see QuickTimeStreaming.h here for how to manipulate these.

Here's a simple diagram of how this works. You've got your application at the top which talks to the presentation. Within the presentation there are various streams which may be video, audio, text or whatever. And within each stream there are a series of different components that are handling the different parts of this.

The sources providing media data in the usual QuickTime format. The packetizer takes that media data, finds out from the stream what size it wants the packets to be and so on. And breaks it up into that and hands it on to the network component that sends it out.

To create a transmission, we have a description stored in a QuickTime Atom container that describes the number of streams, network connectivity, which sources and which packetizers to use. You can construct these yourself, or you will be able to once we tell you how to do that, but importers can also make them from other formats such as SDP files. And the way that you would start a transmission is you call new presentation from data and pass in one of these atom containers. And you set the flag to say it's in send mode.

As Kevin said earlier, you need to be aware that a lot of this networking stuff requires asynchrony, that you will try something out and things won't be constructed straight away. You need to define a QTS notification proc, which you set up in the presentation, and the presentation will then call you back with status information when something changes.

It handles the asynchronous actions, it also gives you error messages and some kind of knowledge when things change. This is true on both the send and receive sides. On the receive side, you get notifications to say when a stream has arrived and so on. If you want a fine-grained knowledge of what's going on inside, you can set this up on the receive side and listen to it.

On the broadcast side, the component chain is built when you pre-roll or preview the presentation. So you call QTS pre-roll or QTS preview. However, it won't be completely constructed and set up straight away because network negotiations may need to happen. So you'll need to idle the presentation a bit first and wait for acts coming back from the different parts to say that you're okay to start broadcasting. So we'll do a demonstration starting a broadcast. Kevin's going to come out and help me with this.

[Transcript missing]

So if I start the application up, I'm going to open an STP file, which is the IETF standard file for describing RTP streaming media. Open that up. It's for my camera. I can point this at you and see what we can see. Over here, Kevin's going to open up a copy of the same STP file on his machine. And you can see that it's buffering up here.

It's probably not well lit enough. I'll turn it around and point it at him for a bit. So you can see I'm getting a slow frame rate preview over here on the broadcast machine. On the client machine you're seeing QuickTime streaming. You'll notice that there's a delay. I'll move the camera away and back.

[Transcript missing]

Does it blow up? I could do it down here. If I do it on this side, you get the usual feedback thing. If I do it over there, I'll zoom this thing. You get a longer feedback loop. It doesn't work. Was he wearing a vibe? It's on the table back here. Okay, back to slides, please.

I mentioned the sources earlier. Sources are where the media data comes from that's sent in the broadcast. And in that case, we were using a sequence grabber sourcer. But it doesn't have to come from that. The media can come from anywhere. And if you're familiar with QuickTime, you'll know about sample descriptions that describe how media data is compressed. And you also need to provide a timestamp.

Writing your own source is a powerful way of extending this. Broadcasting, streaming isn't just for video and audio. You can imagine using it to send experimental results or stock prices or whatever you feel like. There are built-in sources into QuickTime, including the Sequence Grabber Sourcer, which is the one that I've just demonstrated there, but you can add your own.

So what the sources provide to QuickTime is a data record. And you can see there's a whole series of fields here. The key ones are the time value and sample description. You can get the time value back from a QuickTime time base. And you provide the sample description to describe your media and send the data through. And you notice you have to provide a release proc, which is called when the next stage in the chain is finished with the data. And then it wants it to be disposed. And there's also duration and flags. Duration is only really relevant for audio data.

For video data, for example, you don't necessarily know when the next frame is coming, so the client will just display the frame when it comes through. But the time values need to be matching, or your sync will go. And, second demonstration, I'm going to show you a custom sourcer.

Okay, so what I have here is a sourcer component which I can reinstall here. And then I can use the same application as I had before. This time, instead of opening the SDP file, I'm opening an Atom container file that contains that container describing the streams that I'm going to use and says to use my custom sourcer rather than relying on the default of using the sequence grabber sourcer which you get with the SDP file.

So here what I've got is a sourcer that opens a movie file and I can step through the frames in the file and try and catch up with myself. If we open this on the client, over here you'll see that, again, it buffers, it gets a larger size, and it's displaying the slides. And I can, you notice again that I've changed it here and it'll change over there three seconds later.

Um, there's something, it's not attached. So in this example, I've taken the slides from the presentation and exported them as picked files and made the picked files into a movie. So what I'm sending over the wire is picked data, which actually is fairly well compressed for this kind of information.

[Transcript missing]

I could, we could just send out this audio and the slides and that would give a fairly good example of what's going on until we hit the demo. I don't think I can give this presentation with three second lag, so I'll go back to the ordinary slides to do the rest of it.

So the next stage in the chain that I spoke about earlier, packetizers and reassemblers. We already published the APIs for these and explained how to build them because they're also used for stored content. When you hint a movie, the packetizer breaks it up into packets and when you play a movie back, the reassembler puts them back together again.

[Transcript missing]

In terms of transporting your media over the Internet, there are three main ways of doing this with QuickTime streaming, which are multicast, unicast, and reflected unicast. Multicast is Basically, we make the job of making multiple copies the problem of the network itself, of the routers. So the transmitter sends out the data into the network and the routers replicate it and send it on to the clients who are listening.

This is great for us because we're not doing the work the network is. It's also great for you because there's only one copy of the data on the network. Or rather, there's only one copy of the data on each particular leg of the network. The router won't forward it through if there isn't anyone listening at that point.

The drawback of this is that multicasts don't go everywhere. They have a limited range and not all routers will pass them. So if you were doing a broadcast within an organization, if we were broadcasting something within Apple, for example, we could do a multicast. It would go around the campus and pass through the routers and everyone would be able to see it.

But it wouldn't load our network because there'd only, in effect, be one copy of the data moving around over each branch. But if we wanted to do it out to the whole world, we'd have to persuade every ISP between us and them to enable multicast on the routers. And that hasn't happened yet, though. People are working on it.

The second way that you can do it is to do a unicast, which is more like a... The QuickTime is a conventional internet connection where you send out packets with a label on, with someone's IP address, they pass through the internet and get routed over to the client. This works fine, but the drawback is that there's only one address on the packet, so they only go to one person. There are more complicated things you can do to get around that.

The way that we do this is to have a separate machine that does that. So we have a transmitter machine that's creating the broadcast and sending out the packets. And that goes to what's called a reflector. Now the QuickTime streaming server contains a reflector. And if you want to hear more about that, stay for the session after this one.

So what happens there is that the transmitter captures the data, sends the packets to the streaming server. As each packet comes into the streaming server, it makes a copy and sends one out to each client that's listening over the Internet. The advantage of this is that they can go anywhere across the Internet.

The drawback is that there are N copies of each packet on the network. And so the server has to work fairly hard to do this, and the amount of bandwidth you use is directly proportional to the number of clients you've got. This adds complexity and rather than trying to do all this on one machine, we've separated this. There's a transmitter and a separate reflector in the streaming server to do this.

And there are more complicated topologies of this that you can do. You can send, you can unicast all the way across to a remote streaming server and then turn that back into a multicast for that area and so on. So you can route these things different ways. So if you want to be seeded with this and be able to use these APIs, the person to contact is Jeff Lowe, the QuickTime technology manager, and his email address is up there.

You may know also that there is an existing tool for broadcasting to the Sorenson Broadcaster, and there's a Birds of a Feather meeting tomorrow night in J2 for people who are interested in the Sorenson Broadcaster. And there's also a second Birds of a Feather session discussing the details of VDIGs, which if you worked with the QuickTime Capture staff, that's also happening tomorrow night. So, okay, so that's it. Thank you.