2024 Graphics & GamesAudio & Video
WWDC24 · 11 min · Graphics & Games / Audio & Video
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.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 5 snippets
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() 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) 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)
}
} 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) 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.
} Resources
Related sessions
-
15 min -
37 min -
14 min -
29 min -
34 min