Streaming is available in most browsers,
and in the Developer app.
-
Discover rolling clips with ReplayKit
Never again miss anyone's great moment in your game or app. Learn about ReplayKit's latest update — clips screen recording — which provides your app with a rolling buffer of past video and audio samples. When memorable moments happen, discover how you can record and save it for people, and find out how you can surface those clips when they're most relevant. Lastly, we'll take you through integrating ReplayKit into your iOS and macOS apps.
Resources
Related Videos
WWDC21
WWDC20
-
Download
Hello, and welcome to "Discover rolling clips with ReplayKit." My name is Ernest, and I'm a software engineer on the ReplayKit team. Today, I'm really excited to show you a new way to capture your application highlights. Let me start by giving you an overview of ReplayKit.
ReplayKit is a framework that enables you to record your application's screen and audio. When people want to make an instructional video, or simply just wanna show off their gameplay, in-app screen recording creates a video that they can save and share with their friends. And what if you wanted more control over the video content people create? You may want to add additional filters, or overlays. You can do this with in-app screen capture. In-app screen capture will give the audio and video samples directly to your application process, so you'll have complete control over the content that is being created. And we all know the next best thing to playing a game is watching gameplay live. In-app broadcast makes it easy for people to stream your application to third-party broadcast services, to be viewed all around the world. While our current recording features cover a wide variety of use cases, there is one that we currently don't. So, imagine your players just fought all the enemies and unlocked the key to a level in your game, and now they wanna share that moment with their friends. But because it's their first time playing this level, they didn't know something exciting was gonna happen, and they weren't able to capture that moment. Currently, players will need to record their entire gameplay in order to save all their memorable highlights. This results in a large recording that will not only take up a lot of space, but will require time to trim into shorter clips. Wouldn't it be awesome if you could record all the highlights right when they happen? Or even better, what if ReplayKit does this for you, and gives you the video clip of each moment? This year, I'm excited to show you a new feature we've been working on, clips recording. Clips recording will keep a rolling buffer of audio and video samples. When clip export is called, the samples up to 15 seconds prior can be exported into a short video clip. So now, instead of needing to know when to Start Recording, you just need to know when you want to export.
There are several ways to export a video clip. You can add UI buttons or a game controller support to your application, so people can have manual control on when to capture clips. With the tap of a button, they can get the clip exactly when they want it. You can also add triggers in your application that will automatically capture clips. With this, you will always capture those exciting moments when they get a perfect combo, defeat the final boss, or beat their best speed run. And with all of these clips, you can create personalized user experiences. You could add a custom overlay that opens to a collection of recordings, or you could present a highlight reel with all the clips captured at the end of a level for your players to see and share.
Clips recording will be available for iOS and macOS, and is a powerful feature that will sit alongside our existing recording, capture, and broadcast APIs. Similar to our other features, clips recording will provide the same HD quality, low-performance impact, and built-in privacy safeguards. How does clips recording work under the hood? Let's take a look. Clips recording includes three APIs: start, stop, and export. To start clip buffering, your application should call into RPScreenRecorder to get the sharedRecorder singleton instance. With the shared instance, you can call the startClipBuffering API. At which point, ReplayKit will store screen and audio samples from your application in a rolling buffer. Every time ReplayKit receives new samples, any samples older than 15 seconds will be discarded. After the rolling buffer starts, ReplayKit waits for your application to tell it to export. When the application calls the export clip API, ReplayKit takes care of the rest and returns you the video clip of that moment. When you no longer need the rolling buffer, or when you want to use another ReplayKit feature, such as in-app broadcast, you can call the stop API, and ReplayKit will tear down the session.
With this information in mind, let me show you a sample project that implements the new clips APIs.
You may already be familiar with this sample project from our session last year. The updated sample project now includes code for clips. Let's take a look at this code. Just like the other recording sessions, here's the IBAction associated with the "start clips" button in the main storyboard. This button is used to start clip buffering if you aren't already active, and stop clip buffering if you are active. Now, let's go ahead and take a look at what happens when you start clip buffering. Here is the code to start clip buffering. You're going to get the shared recorder instance from RPScreenRecorder and call startClipBuffering with your completion handler. Here, within the completion handler, you will need to handle any error that occurred while attempting to start, including updating the UI. If there's no error, then you should also update the UI to show that the recording is currently active.
Similar to start, there's a stop clip buffering method in the sample project. This is where you're going to get the shared instance, but this time, you'll call the stopClipBuffering API. In the completion handler, you will need to handle any error that occurred while attempting to stop, and should update the UI to show that you're no longer recording.
Now that I went through the code for start and stop clip buffering, let's look at the code needed to export a clip. This is the code for the IBAction associated with the "export clip" button. The action is triggered when a person decides they want to generate a clip. Just a reminder that you're not limited by this approach and may export clips automatically based on your own application triggers. Here, if you're actively recording and the button is enabled from the previous startClipBuffering method, the exportClip function will be called. To call the exportClip API, you will need to specify a URL and a clip duration.
Similar to the start and stop APIs, you will then handle any errors in the completionHandler. If there's no error, then you should have the clip at the specified URL. With access to the clips, you can then build and organize your own user experiences. In my sample code here, the clip is simply saved to Photos.
And that's it! With these three APIs, you can now add clips recording in your application. You will have direct access to the clips in the specified URL, so you can build your own in-app experiences. As previously mentioned, another way to get clips is by adding game controller support. The game controller framework will now have built-in clips recording. Keep in mind, clips exported from the game controller will save directly to Photos or the Desktop. So, to make your own in-app experiences with the generated clips, you will need to implement the ReplayKit clips API. When integrating both ReplayKit and the game controller framework, it is good idea to make sure you're using key value observing for both available and recording properties on RPScreenRecorder. Also be sure to follow the protocol RPScreenRecorderDelegate so that you can update your application's state as needed. And it's that simple to integrate clips recording in your applications. With clips recording, your application will be ready to capture all of the exciting moments when they happen. I look forward to seeing all of the clips and the new user experiences you will create. Thank you so much for watching our session. I hope you have a wonderful WWDC. [percussive music]
-
-
5:19 - Start clip buffering
// Start clip buffering API call func startClipBuffering() { RPScreenRecorder.shared().startClipBuffering { error in if error != nil { print("Error attempting to start Clip Buffering") // Update the app recording state and UI. self.setClipState(active: false) } else { // No error encountered attempting to start a clip session. // Update the app recording state and UI. self.setClipState(active: true) // Set up camera View. self.setupCameraView() } } }
-
5:46 - Stop clip buffering
// Stop clip buffering func stopClipBuffering() { RPScreenRecorder.shared().stopClipBuffering { error in if error != nil { print("Error attempting to stop clip buffering") } // Update the app recording state and UI. self.setClipState(active: false) // Tear down camera view. self.tearDownCameraView() } }
-
6:13 - Export clip button
// Export clip button @IBAction func exportClipButtonTapped(_ sender: Any) { // If clip buffering is active, export clip if self.isActive && self.getClipButton.isEnabled { exportClip() } }
-
6:41 - Export clip
// Export clip func exportClip() { let clipURL = getAppTempDirectory() let interval = TimeInterval(5) print("Generating clip at URL: \(clipURL)") RPScreenRecorder.shared().exportClip(to: clipURL, duration: interval) { error in if error != nil { print("Error attempting to export clip") } else { // No error, so save clip at URL to photos self.saveToPhotos(tempURL: clipURL) } } }
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.