Streaming is available in most browsers,
and in the Developer app.
-
Capture HDR content with ScreenCaptureKit
Learn how to capture high dynamic colors using ScreenCaptureKit, and explore new features like HDR support, microphone capture, and straight-to-file recording.
Chapters
- 0:00 - Introduction and ScreenCaptureKit recap
- 1:20 - Capture HDR content
- 7:14 - Add microphone output
- 8:41 - Record to file
Resources
Related Videos
WWDC24
WWDC23
WWDC22
-
DownloadArray
-
-
5:22 - Capture HDR
// Get content that is currently available for capture. let availableContent = try await SCShareableContent.current // Create instance of SCContentFilter to record entire display. guard let display = availableContent.displays.first else { return } let filter = SCContentFilter(display: display, excludingWindows: []) // Create a configuration using preset for HDR stream canonical display. let config = SCStreamConfiguration(preset: .captureHDRStreamCanonicalDisplay) // Create a stream with the filter and stream configuration. let stream = SCStream(filter: filter, configuration: config, delegate: self) // Add a stream output to capture screen content. try stream.addStreamOutput(self, type: .screen, sampleHandlerQueue: nil) // Start the capture session. try await stream.startCapture()
-
6:40 - Use a local display preset to capture HDR
// Create an SCStreamConfiguration with preset for HDR. let config = SCStreamConfiguration(preset: .captureHDRScreenshotLocalDisplay) // Call the screenshot API to get CMSampleBuffer representation let screenshotBuffer = try await SCScreenshotManager.captureSampleBuffer(contentFilter: filter, configuration:config) // Call the screenshot API to get CGImage representation. let screenshotImage = try await SCScreenshotManager.captureImage(contentFilter: filter, configuration:config)
-
8:05 - Capture samples of microphone audio
// Create instance of SCStreamConfiguration. let config = SCStreamConfiguration() // Enable microphone capture and set id of microphone to capture. config.captureMicrophone = true config.microphoneCaptureDeviceID = AVCaptureDevice.default(for: .audio)?.uniqueID // Create an SCStream instance. let stream = SCStream(filter: filter, configuration: config, delegate: self) // Add stream outputs for capturing screen and microphone. try stream.addStreamOutput(self, type: .screen, sampleHandlerQueue: nil) try stream.addStreamOutput(self, type: .microphone, sampleHandlerQueue: nil) // Start the capture session try await stream.startCapture() // Implement SCStreamOutput function to receive samples. func stream(_ stream: SCStream, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, of type: SCStreamOutputType) { switch type { case .screen: handleLatestScreenSample(sampleBuffer) case .audio: handleLatestAudioSample(sampleBuffer) case .microphone: handleLatestMicrophoneSample(sampleBuffer) } }
-
9:38 - Record to file
// Create a recording output configuration. let recordingConfiguration = SCRecordingOutputConfiguration() // Configure the outputURL (optionally set file type and video codec). recordingConfiguration.outputURL = url recordingConfiguration.outputFileType = .mov recordingConfiguration.videoCodecType = .hevc // Create the recording output with the configuration. let recordingOutput = SCRecordingOutput(configuration: recordingConfiguration, delegate: self) // Add an SCRecordingOutput to the stream. try stream.addRecordingOutput(recordingOutput) // Start capturing (which will also start recording). try await stream.startCapture() // Stop recording. try await stream.stopCapture() //OR // Stop recording, but keep stream running. try stream.removeRecordingOutput(recordingOutput)
-
10:27 - Respond to delegate events
func recordingOutputDidStartRecording(_ recordingOutput: SCRecordingOutput) { // Recording started asynchronously after addRecordOutput. } func recordingOutput(_ recordingOutput: SCRecordingOutput, didFailWithError error: Error) { // Recording failed with error. } func recordingOutputDidFinishRecording(_ recordingOutput: SCRecordingOutput) { // Recording finished after calling either removeRecordOutput or stopCapture. }
-
-
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.