Recorded video looks blurry, color-washed, low bitrate, compressed using ScreenCaptureKit

Hello everyone, I am trying to implement ScreenCaptureKit into my project, I am using MacOs 26 for the target version and followed this official project from apple regarding the screencapture kit. https://developer.apple.com/documentation/ScreenCaptureKit/capturing-screen-content-in-macos

I used the official exact code and implemented in my app, but the results are not good. The video look blurry, unclear, lost colors and its like 720p honestly. The 1st video frame t is result when I integrate it in my app.

After that, I used another app ( which was built in electron, they were using screencapturekit as well ) and there results were a lot better. The 2nd video frame is when I recorded using their application. It appears as close to as system display

I tried multiple things, but no impressive results. For my purpose, I want to the final recorded video to be as good as the display quality of the system. I also applied .hdr local display and coronolicial, but no help with that as well. Changed codecs to .mov, .hevc, but still no help

Why is not the recoded video as high quality as the display

Do you have any code that you can post? What are the differences between your code and the sample?

import Foundation
import ScreenCaptureKit
import AVFoundation
import UniformTypeIdentifiers
import OSLog

@MainActor
class ScreenRecorder: NSObject, ObservableObject, SCContentSharingPickerObserver, SCRecordingOutputDelegate {
    
    private let logger = Logger()
    
    // MARK: - State Properties
    @Published var isRunning = false
    @Published var isRecordingStream = false
    @Published var isAudioCaptureEnabled = true
    @Published var isMicCaptureEnabled = false
    
    // The object that manages the SCStream.
    private let captureEngine = CaptureEngine()
    private var recordingOutput: SCRecordingOutput?
    
    // The user's content selection from the picker.
    private var contentFilter: SCContentFilter?
    
    // MARK: - Capture Control
    
    /// Starts the screen capture session.
    func start() async {
        guard !isRunning else { return }
        
        // Ensure we have a content filter from the picker before starting.
        guard let filter = self.contentFilter else {
            logger.error("No content selected. Present the picker to the user first.")
            return
        }
        
        do {
            // Initialize the recording output to save the stream to a file.
            try initRecordingOutput()
            guard let recordingOutput = self.recordingOutput else {
                logger.error("Failed to start: SCRecordingOutput is not initialized.")
                return
            }
            
            let config = streamConfiguration
            
            // Update the running state.
            isRunning = true
            
            // Start the stream and await new frames.
            for try await _ in captureEngine.startCapture(configuration: config, filter: filter, recordingOutput: recordingOutput) {
                // This loop runs for each new frame. You can process frames here if needed.
            }
            
        } catch {
            logger.error("Failed to start capture: \(error.localizedDescription)")
            isRunning = false
        }
    }
    
    /// Stops the screen capture session.
    func stop() async {
        guard isRunning else { return }
        await captureEngine.stopCapture()
        try? stopRecordingOutput()
        isRunning = false
    }
    
    // MARK: - Content Sharing Picker
    
    /// Presents the system's content sharing picker to the user.
    func presentPicker() {
        SCContentSharingPicker.shared.add(self)
        if let stream = captureEngine.stream {
            SCContentSharingPicker.shared.present(for: stream)
        } else {
            SCContentSharingPicker.shared.present()
        }
    }
    
    /// A system callback for when the user selects content in the picker.
    nonisolated func contentSharingPicker(_ picker: SCContentSharingPicker, didUpdateWith filter: SCContentFilter, for stream: SCStream?) {
        Task { @MainActor in
            // Save the selected filter. The `start()` method will use this.
            self.contentFilter = filter
            
            // If the stream is already running, update it with the new selection.
            if self.isRunning {
                await self.captureEngine.update(configuration: self.streamConfiguration, filter: filter)
            }
        }
        logger.info("Picker updated with filter: \(filter)")
    }
    
    nonisolated func contentSharingPicker(_ picker: SCContentSharingPicker, didCancelFor stream: SCStream?) {
        logger.info("Picker canceled.")
    }
    
    // MARK: - Recording Output Setup
    
    /// Initializes the `SCRecordingOutput` to configure where the video is saved.
    private func initRecordingOutput() throws {
        // Save someonewhere
        
        // Configure the recording output.
        let recordingConfig = SCRecordingOutputConfiguration()
        recordingConfig.outputURL = outputURL
        recordingConfig.outputFileType = .mp4
        recordingConfig.videoCodecType = .hevc // H.265 for better compression.
        
        let output = SCRecordingOutput(configuration: recordingConfig, delegate: self)
        self.recordingOutput = output
        logger.log("Recording output initialized at: \(outputURL.path)")
    }
    
    /// Starts the recording output process.
    private func startRecordingOutput() async throws {
        guard let recordingOutput = self.recordingOutput else { throw SCScreenRecordingError.setupFailed }
        // The recording output is added to the stream when `startCapture` is called.
        // You can manually call the delegate method for logging or state updates.
        recordingOutputDidStartRecording(recordingOutput)
    }
    
    /// Stops the recording output and finalizes the video file.
    private func stopRecordingOutput() throws {
        if let recordingOutput = self.recordingOutput {
            logger.log("Stopping recording output.")
            try? captureEngine.stopRecordingOutputForStream(recordingOutput)
            recordingOutputDidFinishRecording(recordingOutput)
        }
        self.recordingOutput = nil
    }
    
    // MARK: - Stream Configuration
    
    /// Creates the stream configuration based on the current state.
    private var streamConfiguration: SCStreamConfiguration {
        let streamConfig = SCStreamConfiguration()
        
        // Configure audio capture.
        streamConfig.capturesAudio = isAudioCaptureEnabled
        streamConfig.captureMicrophone = isMicCaptureEnabled
        
        // Set a standard frame rate (e.g., 60 fps).
        streamConfig.minimumFrameInterval = CMTime(value: 1, timescale: 60)
        
        // Use a pixel format and color space compatible with most displays.
        streamConfig.pixelFormat = kCVPixelFormatType_32BGRA
        streamConfig.colorSpaceName = CGColorSpace.sRGB
        
        // Set queue depth for smoother capture at the cost of memory.
        streamConfig.queueDepth = 8
        
        return streamConfig
    }
    
    // MARK: - SCRecordingOutputDelegate
    
    nonisolated func recordingOutputDidStartRecording(_ recordingOutput: SCRecordingOutput) {
        logger.log("Recording started.")
    }
    
    nonisolated func recordingOutputDidFinishRecording(_ recordingOutput: SCRecordingOutput) {
        logger.log("Recording finished.")
    }
}

class CaptureEngine {
    var stream: SCStream?
    
    func startCapture(configuration: SCStreamConfiguration, filter: SCContentFilter, recordingOutput: SCRecordingOutput) -> AsyncThrowingStream<Void, Error> {
        // 1. Create SCStream with the configuration and filter.
        // 2. Add the recordingOutput to the stream.
        // 3. Start the stream.
    }
    
    func stopCapture() async {
       
    }
    
    func stopRecordingOutputForStream(_ output: SCRecordingOutput) throws {
        
    }
}
Recorded video looks blurry, color-washed, low bitrate, compressed using ScreenCaptureKit
 
 
Q