Networking and Server • 43:49
This session presents an overview of the latest version of QuickTime Streaming Server and Darwin Streaming Server. Topics include new server functionality, new APIs, and techniques for developing products and content around the streaming server.
Speakers: Chris LeCroy, John Anderson, Mythili Devineni
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
So let's talk about streaming servers. So Apple, we've got QuickTime Streaming Server. We also have Darwin Streaming Server. And basically what that is, is the open source version of the QuickTime Streaming Server. So I want to keep that in mind as another entry point for development throughout this session. So let's talk about what we're going to talk about today. So I'm going to briefly go over some of the new features in QTSS 4. And then after that, we're going to have some engineers come up and provide some more detailed technical information.
A couple of the things you're going to learn about are more about our server module API. The server's got a really powerful API for building modules. It's very object-oriented, and we've made some enhancements to it in form. I'll have an engineer come up and talk about that a little bit.
We also have something we call the admin protocol in the server, and that's a mechanism for remotely administering and monitoring and controlling the server. We'll have a little talk about that and show how you can build some tools around that protocol. Let's talk about what's new in QTSS 4.
Here's a short list. The list is actually a lot longer, but I want to focus on some of the high-level things here. We've done some enhancements for development. As I said, we've improved the module API a little bit. We've provided some more developer documentation. And we've made some enhancements to our skip protection algorithms and the result of that is some of the InstantON demos that you saw earlier in the conference. And with every release we try to improve the performance. We've done that.
We have completely designed the web admin. We've added some support for automated relays, which allows you... Relays are a mechanism for sending streams from server to server as opposed to from server to client. And we've added native MPEG-3 streaming. And last but certainly not least, QuickTime Streaming Server 4 has full support for MPEG-4 content.
So, this is a big deal. What this means is that the QuickTime Streaming Server will work with any ISO-compliant MPEG-4 content, and it'll stream it to any compliant player. It doesn't have to be the QuickTime player. It can be any MPEG-4 player. So this is actually a really big deal. We really think that MPEG-4 is going to become the de facto standard for streaming.
So let's drill down a little bit. Module APIs. So if you are familiar with the module APIs at all, prior to QuickTime Streaming Server 4, you were able to, modules were able to access some of the objects in the server. So let me explain what I mean by objects. The API is really object-oriented.
So all of the API calls take objects as parameters to them, and objects are basically the mechanism that's used for the server to communicate with modules. Modules and servers pass objects back and forth to each other. With QuickTime Streaming Server 3 and prior, the only objects that modules could get to were objects that the server had created and they were owned by the server. With QuickTime Streaming Server 4... We've now made it possible for modules to create their own objects, and that provides a bunch of power to modules that you didn't have before, and you're going to learn more about that later in the session.
Documentation-wise, we have now documented our reliable RTP protocol, or skip protection as you guys know it. And what that means is that if you want to write a server or a client that take advantage of script protection and advantage of instant on and things like that, we've documented that protocol, so you can do that now.
In addition to that, we have documented our mechanism for tunneling RTSP over HTTP. And the reason we do that is it's our way of getting through firewalls that don't support RTSP and RTP. So that's documented. Again, if you want to write a server or a client that take advantage of that protocol, documentation is all there.
And the last thing we need, new documentation that we have is for caching streaming proxies. So if you're writing a proxy appliance, for example, or streaming appliance, what we've done is we've provided, we've done some extensions to RTP and RTSP that allow caching streaming proxies to get pristine copies of the stream and some other features. We've documented how that works now.
Performance improvements. So every time we release a new version of QuickTime Streaming Server, we lock a guy in a room and we tell him to make it go faster. And we did it again. We're now up to 4,000 concurrent streams on a single server. Those are low bitrate streams.
But in addition to that, we've now doubled the number of high bitrate movies that we can stream from a single server. By high bitrate, I'm talking about one megabit movies, big movies, movies that can play full screen that look just as good as TV. We've doubled that number.
And for those of you who have ever been through the process of hinting a movie, you're probably familiar with the little checkbox that says optimize for streaming or optimize for server. We did a lot of work in the server, in QuickTime Streaming Server 4, and made a bunch of changes to the parsing code.
And we basically made it so that you don't need to optimize anymore. The downside, the reason we used to need optimizing was that it created movies that allowed the server to scale much higher so we could serve more movies if they were optimized. The downside was that they doubled the size of your movie. So, as of QuickTime Streaming Server 4, you no longer need to optimize.
Here's a graphical view of what we've done with performance. With the first version of the streaming server, we were able to do a thousand concurrent streams off of a single machine. At that time, we thought that was actually pretty good. In each release, we've increased the performance. You can see now QuickTime Streaming 4 has quadrupled our original capacity in the server. Hopefully, the graph will continue going up as we release more versions of the server.
So another feature is the redesigned admin app. So if you're familiar with QuickTime Streaming Server 3, we announced a web-based administration application. Basically, it lets you administer the server from a web browser locally or remotely. And that was great, but we made it even better. We completely revamped it. It's got a brand new look.
It's much cleaner, much easier to navigate. We've added a setup assistant, and you can probably figure out what that does. Basically, it walks you through a couple of questions, you answer them, and then within minutes you've got the server up and running and ready to serve content. And we've added UI for something that was actually pretty complex to do in the past, which is set up relays. So we've got UI and monitoring for that.
One of the features we added in QuickTime Streaming Server 3 was the ability to do server-side playlists. What that allows you to do is things like internet radio stations by serving a server-side playlist of content. We've completely revamped the UI for that in the administration app. I'm going to show you a little bit of what we've done.
I'm going to launch the admin and log in to the server. So this is all secured. We support SSL. If you don't remember your name and password, we can't help you there, though. So, here's the new look. It's much cleaner. Here's the main page. Shows just some general status on the server. You can see some general settings that you can set. You can monitor which users are connected.
I've got a lot of users connected and they all seem to like the very popular sample 100k bit movie. And let me show you how easy it is to work with playlists now. I'm going to set up an MP3 playlist. I'm basically going to set up an internet radio station. I'm going to show you how easy this is. I'm going to call it Chris Radio.
And I'm going to give it a mount point. The mount point is basically the path portion of the URL that users are going to use when they listen to this from their MP3 player. Pick a genre, which will show up in the MP3 player. It's a radio station, so I want to randomly play music, but I want to be able to control the randomness of certain songs, and that's what weighted randomness is. It allows me to add weights to songs so that certain songs play more often than other songs.
And I want to make sure that the song doesn't repeat itself until five other songs have been played. So that's basically setting things up. Now I want to go through and just pick the items that I want to have in my radio station. So these are files that are actually stored on the disk on the server. Basically, I just select them and drag them over.
And here you can see the weighting, so I can say that I don't really like compression to play too often, so I'll reduce that. You'll notice I've got a station ID MP3 here, so this is, you know, Chris Radio, welcome to Chris Radio, station ID. I want that to play more often, so I'll increase the weight on that. And I'll save those changes. And I will tell this playlist to start playing and I basically have an internet radio station. I'm done. It's very simple.
Speaking of MP3, let me tell you more about what we've done. We have native MP3 streaming. What I mean by that is we are Icecast/Shoutcast compatible. The server can rebroadcast an incoming stream of MP3s. We can generate a stream of MP3s off of the server. Because we're compatible, we can also inject into networks or other servers that are using these standard protocols.
As you've seen, it's really easy to set up an internet radio station. I think it's certainly the easiest server-side solution that I've seen. This server scales really well, so this is really the thing you're going to want to use if you want to send streams out to massive numbers of people. Of course, because we're using standard protocols, it works with any MP3 player that supports standard HTTP streaming, Windows Media Player, or real-time streaming.
We've provided mechanisms for doing insertion of ads or station IDs. You saw an automatic way of doing it. We actually have ways where you can dynamically do that in real-time if you like as well. You can do real-time playlist manipulation. If I wanted to remove songs or add songs while the playlist was playing, no problem.
You don't have to stop the radio station and bring it back up. That would be a pretty poor experience. You can broadcast locally from your machine. You can treat your machine as an all-in-one unit that does all of the streaming to the clients, or you can have the server send off to another server and relay things that way.
[Transcript missing]
So next, I'm going to have John Anderson come up, and he's going to talk to you a little bit about the admin protocol and show you how to write tools using this protocol. John? Hello, everybody. I'm John Anderson. I'm here from QuickTime Streaming Server Engineering to talk to you today about the admin protocol.
And the reason you'd want to use the admin protocol is if you want to make another application which communicates with QuickTime Streaming Server. And you can do this in real time and get real-time data out of the server and real-time preferences out of the server from another application, even running on another machine. And it's really easy to do.
[Transcript missing]
With that in mind, I'm going to show you a quick demo, and this will give you an idea of how easy it is to access information inside QuickTime Server. I have a URL bookmarked, and you can see this is basically going to connect to a copy of QuickTime Server and get a specific path. I'm logging in with the same password as Chris used. And here we go.
We have -- Here we have some information from the server. So you can see some information about what the default DNS name is. You can see some information about what the current bandwidth is, what the average bandwidth is. So there's lots of information that you can get at via the admin protocol that's all updated live. And all of this is just like accessing pages, say, on an Apache web server. Very, very simple.
Can I go back to slides, please? Actually, never mind. I have another application, actually, that I'm going to show you. The reason for it is that, you know, just bringing up a web page, that's kind of boring. It doesn't really show what you can do with the admin protocol.
So I have this application, the QTSS Inspector. And this is a Cocoa application, which gets all of the preferences from the server. So when I log in here, I'm seeing the same information I saw on that web page, but it's parsing it and putting it into a nice outline view so that you can see it. Now, you notice here that you see some folders.
Not only does this mimic an Apache web server from the standpoint that you have a bunch of paths, but you also have subpaths. So it's just like having subfolders on a web server. For example, here we have a QTSS Server Client Connections subfolder. And inside that, we have subfolders for each connection to the server. So you can see information about every client that's connected to the server through the admin protocol. So, yeah, now I'd like to go back to slides.
Please. So this inspector is based on the NSOutlineView class in Cocoa. So if anybody's familiar with Cocoa, they probably already know this. And the data source for that outline view gets its data just by performing HTTP requests. And it uses the password that I entered when I first started the application as authentication for that. So again, it's just like getting pages out of a web server. Very simple thing to do.
The format of the URLs is basically, you can see the sample URL at the bottom. The port that you access through is typically 554. That's the default port for streaming. If you have port 80 turned on in your web administration UI, then you can connect through port 80 as well. So you wouldn't even have to type the port in in that case.
All of the URL paths begin with /modules/admin. The reason for that is that that's the way that QuickTime Streaming Server can tell the difference between a URL that's meant for the admin protocol versus a URL that's meant for an MP3 stream or a video stream or something like that.
You notice you can also use wildcards to get multiple values or sets. This is similar to when you can go to a directory in Apache and have it automatically create an index page for you. If you use an asterisk at the end of your URL in QuickTime Streaming Server, it will give you a listing of all of the preferences in that folder.
So the sample URL you can see here is modules, admin, server, and then an asterisk. Pretty much everything, even though all URLs have to start with modules, admin, pretty much all of the preferences and data that you're going to need are actually inside a subfolder of that called server. So as you can see, it's just a standard URL path that you get, and you get your results back. So again, I have another demo for you.
Now, Chris showed you in the web UI, you can see a list of the connected users. And again, that's, you know, this is a demo. This is supposed to be exciting. So I've built a connected, a connection monitor, which is another Cocoa application. And when I log in here, I can I can see a graph of all the bandwidth that's coming through the server.
And you can see at the top of the window, it lists whatever the current bandwidth coming through the server is at the moment and what the maximum bandwidth is set to in your preferences. So it's gathering the information from the preferences to find out what your bandwidth cap is, and then it's gathering live information from the server via the admin protocol to find out what the current bandwidth coming through the server is at any moment. So that's it for the demo. If you can switch back.
So again, this fetches the current bandwidth every half second and then uses a subclass of NSView to display a historical chart. So this application is composed of three main components. The first one being that NSView, which constructs a bar graph from a given array of history. And then it includes an NSTimer, which fires every half second and then consequently tells the NSView to redraw itself. And lastly, there's a custom object that I created, which was an admin protocol access object. And this custom object that this application uses basically performs the HTTP request and parses it into something that Cocoa can understand.
So the URLs that it's getting in order to populate its data, the top one is the URL for the current bandwidth cap. And again, you can see that it starts with slash module slash admin slash server. And in this case, since it's a preference, it's actually in a subfolder of that called QTSS server preferences.
And so you can see, kind of get a general feel for what kinds of URLs and what kinds of information that you can get from the server. And then, of course, we have two different URLs for the RTSP bandwidth and the MP3 bandwidth. And then we total those two together to find out what the total bandwidth is going through that server.
So to give you an idea of some of the Cocoa calls that I'm giving here, I basically just tell my admin protocol access object to get a value using HTTP. And it returns, this object basically parses the result and returns it in an array. And we take the first item of that array, since we're only getting one item of information, we take the first item of that array and set the string value for the field at the top of the window using that information.
We, of course, have similar code here to get the other two values from the server, to total them together, and to tell the NSView to redraw itself. So that's it for me, and I guess on to Mythili, and she's going to talk to you about writing QuickTime Streaming Server modules.
Hi, everyone. Now I'm going to give you a brief introduction to QTSS modules. In this overview, I shall explain a little bit about some of the key concepts that are involved in writing QTSS modules. I shall also show some sample module code that illustrates some of these concepts and end with a demo of a sample module.
But before going talking about writing modules, why would anyone want to write QTSS modules? The streaming server does a lot of different things. It serves QuickTime movies, it streams MP3s, it even relays streams, it also reflects live broadcasts, and a bunch of other things. Now, all these features are not implemented in the core server, but really in all the modules. Each module implements one or more features.
So if you want a feature that's not already in the server, then writing a module is the only way to go. There are two ways to write a module. One, you can compile in the module with the server, and that's called a static module. But you could also write the module such that it's dynamically linked in at runtime and not compiled in, in which case it's called a dynamic module. It's very similar to a plug-in.
In this case, if you write your module as a dynamic module, then you do not have to publish your source code or give back your source code to Apple, even though the core server itself is open source and is under the Apple public source license. This means that you can sell your dynamic module and still protect your intellectual property, which I'm sure is very important to all of you. Also, you could package your module along with QTSS and sell this version of the enhanced streaming server. Now, moving on to writing QTSS. DSS modules.
One of the main concepts in writing a QTSS module is a QTSS role. As I said earlier, the server is not doing the work, but the modules are the ones that are really doing all the work of implementing the features. This means that the server calls all these modules at different points in time. These different points in time or states are called QTSS roles in our server. So the server provides a well-defined state each time it calls a module in a particular role.
And it exchanges information with the module by passing in one or more QTSS objects. I should explain a little more about QTSS objects later. But the server doesn't know what modules need to be called in any particular role. So when it first starts up, it asks all the modules what roles they handle. So this process is called registering for a role in QTSS.
Some of the roles that are available in the server are the RTSP filter role, the route role, the RTSP route role, the client session closing role, and so on. There are many more roles, and you can implement your features in sometimes more than one role. There's no hard and fast rule that you need to use a particular role to implement a particular feature.
For example, if you wanted to implement load balancing in your server, then your module could, in the RTSP filter role, stop the request processing and send back an RTSP redirect to another server. This is how typically load balancing works, right? You have a server that's at the gate, and it's redirecting requests to other servers. So basically, based on some rules that you have, you can redirect. But you can collect statistical information. You can collect data from the other servers and load balance accordingly and send back an RTSP redirect in the RTSP filter role.
Also, the server only has one content directory. But there might be times when you want to have multiple content directories, so you're hosting your content on more than one directory in the server. For this, you could write a module that listens in the RTSP route role that redirects or rewrites the content directory for each RTSP request that comes in, again, based on certain rules.
and the server also does some logging. The server keeps a lot of information for each client that connects to it. And this information is kept inside a QTSS object called the QTSS client session object. So when the client comes in and disconnects, the server calls all the modules in the client session closing role and passes in the client session object, which means that your module, if it wants to log some advanced attributes off the client, client session, then you could do so by registering for the client session closing role, grab those attributes of the client session object, and record them in whatever form you may want. Maybe you don't want to really record it to file, but you want to send it off somewhere to a remote server. You can do all sorts of things with that, and it's pretty simple.
Now, I've been talking about QTSS objects. What are QTSS objects? I'm not sure how many of you are familiar with writing object-oriented programming or object-oriented programming languages, but if you are, then you're all familiar with the concept of an object. And really, a QTSS object is very similar to a regular object in an object-oriented programming language, which means that it has a set of attributes, which are called members in object-oriented programming, and it has a set of methods that you can operate on that particular object. So the concept is very similar. There's a QTSS object that has a set of attributes, and there are a set of API calls that you can operate on those QTSS objects. And it is a method.
It's a way to exchange information between the server and the modules. So the modules, the server passes in these objects in different QTSS roles, as I already mentioned. So the modules can get any sort of information, get and set attributes in these objects. The server pre-defines some of the objects. One of the objects is a QTSS server object, which is basically the overall server object that stores the attributes, such as the statistics, as in the number of current connections, the current bandwidth, and so on.
And all these attributes get dynamically updated during the life of the server. The server also creates an RTSP request object when an RTSP request first comes in. Correspondingly, it creates a client session object for an RTP session that's associated with a client when you're accessing the RTP packets app.
So these are some of the pre-defined or built-in objects of the server. And prior to QTSS, in QTSS 4, the only objects available to the modules are all defined by the server. Modules could not define their own QTSS objects. But in QTSS 4, modules can now create their own QTSS objects.
Now, why create QTSS objects? You could have always stored your data in internal data structures inside your module, and that's what all modules did prior to QTSS 4. But now, you have the advantage of storing your data in QTSS objects. By doing this, your data becomes part of the server, and all the other modules in the server have access to these attributes.
This becomes really important when we learn more about it as we move on. So, by creating a QTSS object for your module, it has become a stock QTSS object, which means that you can use a really powerful yet simple QTSS API on your object and do a variety of things. One of the other big advantages is accessibility through the admin protocol.
John has already talked to you about how powerful the admin protocol is, and it's as simple as doing it. It's as simple as doing HTTP requests. By creating QTSS objects, your data is browsable and accessible through the admin protocol. That means you can set and get attributes through the admin protocol without writing your own new protocol.
For example, we ourselves use these objects in our modules at vWritten. And Chris talked about the automatic relay feature. So in the relay module is the module that implements the relaying of streams. And every time you set up a relay in the web admin, the relay module is actually creating a relay object, a QTSS relay object, really, and it populates with all the attributes that are necessary for that relay. So once you configure it, you have this object ready, and you can monitor it through the web admin by getting these attributes, and that's what's happening.
So if you go to the web admin and try to look up the relay status, how many bits the relay is sending out, how many are coming in and how many are going out, what is really happening is that the admin is fetching the relay object attributes to the admin protocol and getting it. So if you want to learn more about how to create these objects, then the relay module is the place to go and look for it. Thank you.
Let me explain a little more how this works. So prior to QTSS 4, the modules kept their data internally. So you see the yellow blobs of data? Those are internal data structures. And as you can see, they're not accessible to any of the other modules. They're not viewable. So you don't have the advantage of the API calls, nor of the admin protocol. But now in QTSS 4, a module can create its own QTSS objects.
That means your module objects have actually become part of the server. And you can see that by virtue of being in a server, they have complete access to the API calls. And any module can get access to your data by using just the API calls. It's not something that's hidden.
As you can see, because the module objects are part of the server, the admin protocol also has access to it via the admin module. And so you don't have to write your own. Prior to... I'm going to go back a little.
[Transcript missing]
With the module objects, you can see that the admin protocol knows about your module objects, so your job is way simpler. And you can take full advantage of the tools and technologies that the streaming server provides.
Now, you know, now you want to create these QTSS objects, but how do you do it? As I said earlier, the concept of objects is very similar to objects in object-oriented programming. So just as you would first define a class when you want to create objects, you would do the same. You would create a new object type in QTSS. And so you would define this new object type using the createObjectType call.
And in object-oriented programming, once you define a class, you need to instantiate an object of that class to do anything. So this means it's the same analogy here, because you instantiate an object of the newly defined type of yours. And you do so by using the create object value call. This is just a brief, it gives you a brief idea of what the API calls are, but there's a lot more. And the API documentation clearly explains how all these calls work.
And there's a sample module that you can look at if you want to learn more about it. And once you create these QTSS objects, as I said earlier, you can use any QTSS API call on your object, just like you would use for the regular built-in predefined objects.
To illustrate some of these concepts further, I wrote a sample module that uses some of these API calls. I wanted to serve content from users' home directories. Some of you are probably familiar with when you go to a web server and you use a request such as tilde joe slash index.html, the server is actually getting Joe's home directory or Joe's web server directory.
I wanted the same feature for the streaming server, where I wanted to have a tilde joe in my RTSP URL and my module. I can serve content from Joe's home directory instead of having to put all the user's content into one big movies directory so that the users have their own access. It's a very common use, and everybody wants to have that. So I decided to write a module that can do it.
So when a request comes in with tilde joe slash bday.move, the bday.move is actually going to be coming from Joe's home directory. And since I need to rewrite the content directory to point to Joe's home directory, the role that I need to register for is the RTSP route role. The RTSP route role is basically routing the request to another directory.
And the attributes that I'm interested in are the RTSP request file path and the RTSP request router. The request file path, because as you can see, the file path has tilde joe slash bday.move, and I need to strip out the tilde joe because the server doesn't know what tilde joe is.
And the request router will be initially pointing to the movies directory, so I need to change that to Joe's home directory. And these two attributes are going to be coming from the bday.move directory. And these two attributes belong to the RTSP request object, and the RTSP request object gets passed in by the server in the QTSS RTSP route role.
As I mentioned earlier, the server doesn't know what modules can handle what roles. So you need to register for the role when the server calls you in the register role. And you can do so by telling the server that you want to be called for the route role, as I'm doing here, and some other roles that you might need.
There's only one entry point function into the module, so the server always calls the module in the same function for every role. So it's a very common way of writing dynamic modules or plug-ins, and we call it dispatch functions. And as you can see, I am just redirecting. When I get called in the RTSP route role, my module is calling my own internal function that's actually doing the work.
Now the work here is to look for a tilde in the first part of the path, and if I find the tilde, then rewrite the requestRooter attribute of the request object to point to the user's home directory. As you can see, the actual API calls are not here, but this is the code that's going to do it. The rewriteRooter is rewriting the requestRooter attribute to Joe's home directory in this case. So, let me show you how it works.
So let me go to my home directory. Here the user is WWDC. And I have one movie in my movies directory. and Enya1.mov. So I'm going to try and go to my player and connect to the movie in my home directory. Oh, there it is. So it's tilde www.dc/nu1.move.
Let's see what happens. 404 not found. So the server doesn't understand what a tilde is, and so it's throwing out and saying, I don't know what it is. It's not here. It's not available. I've written a dynamic module, and this dynamic module can be dropped into the modules folder.
There it is in the modules folder. And I need to restart the server so that the server can load up the dynamic module or the plugin. There you go. I restarted the server. I'm going to try and connect it again, now with my module installed. So hopefully, I've written the module correctly and there are not too many bugs. It'll work. Let's see. There you go.
So you can see how easy it is to write really powerful modules with not so much code, really. So, and this concludes my demo. Chris? Okay, so you've seen some of the new features in QuickTime Streaming Server 4. The team's already hard on work on the next release, so you'll be seeing a bunch of new features some John showed you how to work with the admin protocol.
Hopefully you can see the power of the admin protocol. The tools he wrote were simple to write. He wrote them just as demos and it didn't take him a whole lot of time to do it. You guys could write even more powerful tools than that to do monitoring.
and Mike Leigh, and Mike Leigh showed you that it actually really is easy to write modules for the server. You need to understand the APIs, but you can do some pretty powerful things with just a few lines of code. I encourage all of you to try to take a look at some of the documentation for these things.
So let's talk about what is left for the rest of the week related to streaming. So not much left because it's Thursday, but if you want to learn more about MPEG-4 and QuickTime, there's a session on Friday at 3.30 in room A2. And I believe some of our MPEG-4 engineers will be there, so that should be a pretty good session. And then on Friday at 10.30 a.m., there's a feedback forum for QuickTime, and that's the place to give any kind of feedback you'd like for anything QuickTime. QuickTime Streaming Server, QuickTime Client, QuickTime APIs, anything like that. It's usually a pretty interesting feedback session.
So if you're a developer and you need to work with Apple, Jeff Lowe is your man. He's the QuickTime technology manager in the evangelism group at Apple. So he handles developer things for all things QuickTime, and his email address is there, jefflowe at apple.com. and Jeff is here in the room, so maybe if you want to talk to him now, he's... after the session, he's sitting right over there.
In terms of where you can get more information on some of the things you heard about today, so as I mentioned, the streaming server is open source, so if you want to just take a look at the source code or actually become one of our developers, go to Apple's open source website and you'll see links there for the Darwin Streaming Server. And we encourage you to help us out. We love help.
If you want to learn more about QuickTime developer topics, the developer.apple.com slash QuickTime site has everything about QuickTime in terms of APIs, the QuickTime Streaming Server APIs, and anything QuickTime, basically. And then another good place for contacting or for kind of getting information are some of our mailing lists. So the streaming server group has two mailing lists.
We've got a developer's mailing list. That's for people like you, people who are actually working on the server, trying to get information on the server, trying to write modules, working on the open source, working with the admin protocol. And we've got a user's list, which is more for people who are deploying the server and trying to get it up and running or wondering how they can do certain things.
Both of these lists are fairly low traffic. I shouldn't say traffic. There's a low amount of noise. It's actually, they're pretty high quality lists. And so I'd encourage you to go ahead and subscribe to those lists. And the other thing about those lists is that the engineers are really active on that list.
That's the way that you talk directly to a QuickTime Streaming Server engineer is to get up on that list and ask. In addition, there's a mailing list for kind of general QuickTime discussion. It's typically kind of a technical nature. A lot of content developers are on that list, and that list is the QuickTime Talk mailing list. And to get on any of these mailing lists, just go to the list.apple.com website, and you can subscribe on that web page there.
In terms of technical documentation, I mentioned that you can get the streaming server API documentation off of the developer website. In addition to that, if you download or check out the source code, there's a documentation directory in the source code. What that has is kind of unofficial documentation. These are things that are more like developer notes and how to build, some discussion of some of the internal workings of the server and things like that. I encourage you to take a look at that directory.
A great place to learn about modules is also in the source code. As Mythili mentioned, almost every feature, actually every feature in the server is implemented as a module. We also include some sample modules. These are great places to look through code and learn because the sample modules are intended to teach you how to write modules. They're not quite as daunting as something like our live reflection module, which is huge and pretty complicated. These are all well documented and well commented.