스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
ScreenCaptureKit 소개
macOS 화면 공유 응용 프로그램, 화상 회의 앱, 게임 스트리밍 서비스 등에서 ScreenCaptureKit을 통해 고성능 화면 캡처를 제공하는 방법을 알아보세요. 이 API의 구성 요소를 알아보고, 스트림을 구성하여 화면상의 비디오 및 오디오 콘텐츠를 캡처하는 방법을 배우며 여러분의 기존 앱에 이를 통합하기 위한 팁을 공유합니다.
리소스
관련 비디오
WWDC23
WWDC22
-
다운로드
안녕하세요 환영합니다 제 이름은 Ernest고 ScreenCaptureKit 팀의 소프트웨어 엔지니어입니다 지난 몇 년 사이 우리 모두는 원격 협업에 더욱 의존하게 되었습니다 화면 공유를 자주 쓰죠
또한 OBS Studio 같은 녹화 애플리케이션을 사용한 게임 플레이 스트리밍과 콘텐츠 제작은 교육 및 엔터테인먼트 분야에서 지속 성장하고 있는 분야입니다
이를 염두에 두고 개발자의 요구에 맞춰 강력한 고성능 화면 캡처를 제공하는 프레임워크를 만들었습니다 ScreenCaptureKit을 만나보세요!
ScreenCaptureKit은 macOS의 새로운 프레임워크입니다 애플리케이션의 화면 공유 경험을 만드는 데 도움이 되도록 설계되었습니다 ScreenCaptureKit은 캡처하려는 콘텐츠를 선택할 수 있는 API를 제공하며 애플리케이션에 맞는 개발자 컨트롤 및 토글도 제공합니다 또한 모든 필터와 컨트롤을 즉시 업데이트할 수 있습니다
프레임워크는 디스플레이의 기본 해상도와 프레임 속도까지 높은 품질과 성능을 제공하며 글로벌 보호 장치로 개인 정보도 보호합니다
이 세션에선 ScreenCaptureKit 프레임워크의 기본을 알려드립니다
기본을 이해하고 나면 'Take ScreenCaptureKit to the next level'에서 더 고급 주제를 살펴보세요
먼저 프레임워크의 주요 기능을 살펴보겠습니다
다음으로 API 개요에서 ScreenCaptureKit 주요 구성을 다룰 겁니다
그런 다음 필터 및 구성으로 스트림을 설정하는 방법을 보여 드리겠습니다
마지막으로 동영상과 오디오 샘플을 애플리케이션으로 스트리밍하는 법을 안내합니다
ScreenCaptureKit의 주요 기능부터 시작하겠습니다
ScreenCaptureKit으로 공유 및 필터링할 콘텐츠 유형을 지정할 수 있습니다 디스플레이, 애플리케이션 및 창의 모든 조합에서 화면 콘텐츠와 함께 제공되는 오디오를 캡처할 수 있습니다
ScreenCaptureKit은 다양한 개발자 컨트롤을 지원합니다 픽셀 형식, 색 공간 프레임 속도, 해상도 등입니다 오디오에선 샘플 속도와 채널 수 등을 제공합니다
이 모든 필터와 구성은 즉석에서 조정할 수 있습니다 애플리케이션 설계에 융통성이 늘어납니다
최대 48kHz 스테레오 및 디스플레이 기본 해상도와 프레임 속도의 동영상 샘플을 전달하기 위해 ScreenCaptureKit은 성능에 중점을 두고 있으며 기존 캡처보다 CPU 오버헤드가 낮은 Mac GPU를 활용합니다 물론 ScreenCaptureKit은 개인 정보를 염두에 두고 구축돼서 프레임워크를 사용하는 모든 애플리케이션에 글로벌 개인 정보 보호 기능을 제공합니다
프레임워크는 동영상 및 오디오 콘텐츠를 캡처하기 전에 동의가 필요하며 선택은 시스템 환경 설정에 있는 화면 녹화 개인 정보 보호 설정에 저장됩니다
이제 ScreenCaptureKit이 무엇인지 보았으니 API에서 가장 중요한 개념 몇 가지를 보여드리겠습니다 ScreenCaptureKit 프레임워크는 SCStream을 중심으로 합니다
SCStream은 시작 및 중지와 같은 제어 방법을 처리하고 SCShareableContent와 함께 생성됩니다 SCContentFilter 및 SCStreamConfiguration
이러한 객체는 캡처하려는 콘텐츠와 캡처 방법을 결정합니다
객체가 생성되고 시작되면 SCStreamOutput 프로토콜을 통해 미디어 샘플이 애플리케이션에 전달됩니다 잠시 후에 더 자세히 설명하겠습니다
이제 API로 애플리케이션의 스트림을 설정하는 법입니다
다음은 스트림을 설정할 때 익숙해져야 하는 객체입니다
캡처 대상과 캡처 품질 성능을 결정하는 객체입니다
제일 먼저 SCShareableContent입니다
이 바탕 화면엔 창, 애플리케이션 디스플레이 자체가 있습니다
ScreenCaptureKit에는 공유하려는 콘텐츠를 구축하는 데 사용할 수 있는 각 클래스가 있습니다
우선 SCDisplay를 살펴봅시다
ScreenCaptureKit은 읽기 전용 속성을 써서 디스플레이를 SCDisplays로 분류합니다 디스플레이 식별자와 크기 속성인 너비 및 높이가 포함됩니다
디스플레이 내에는 여러 애플리케이션이 실행 중일 수 있으며 각 애플리케이션에는 해당 SCRunningApplication이 있습니다
SCRunningApplications에는 애플리케이션 수준 정보에 대한 읽기 전용 속성이 있습니다 번들 식별자, 애플리케이션 이름 프로세스 식별자가 예시입니다
여기서는 Keynote와 Safari용 SCRunningApplication이 있습니다
물론 이러한 애플리케이션에는 창이 있습니다
그 창에는 읽기 전용 속성이 포함된 SCWindow가 있습니다 창 ID, 프레임, 제목 창이 화면에 있는지 최소화됐는지 등을 정의합니다
SCWindow에는 소유 애플리케이션도 있습니다
이 경우 두 Safari SCWindows에는 동일한 Safari 소유 애플리케이션이 있습니다
SCWindows SCRunningApplications 및 SCDisplays는 결합하여 SCShareableContent에서 공유할 수 있는 콘텐츠를 제공합니다 장치에서 공유 가능한 모든 콘텐츠의 목록을 가져오거나 특정 매개변수를 지정할 수 있습니다
화면에 있는 모든 애플리케이션과 창을 나열해서 공유하고 싶은 것을 선택하게 하려 한다고 가정합시다 ScreenCaptureKit에는 간단한 API가 있습니다
이 짧은 코드 조각은 developer.apple.com에서 가져온 캡처 샘플 코드입니다
화면에 있는 창만 SCShareableContent를 반환하며 관련 SCWindows, SCApplications SCDisplays가 포함됩니다
이제 공유 가능한 콘텐츠가 있으므로 필터를 만들 수 있습니다
SCContentFilters에는 두 가지 주요 유형이 있습니다 창을 여러 디스플레이에서 이동 시 창을 캡처하는 디스플레이 독립 창 필터 특정 창 및 애플리케이션을 포함하거나 제외할 수 있는 디스플레이 종속 필터
여기서 짚고 넘어갈 부분은 오디오 캡처 필터링은 애플리케이션 수준에서만 가능하다는 점입니다
필터가 무엇인지 보여주기 위해 몇 가지 예를 보여 드리겠습니다
keynote 창을 공유하는 데만 관심이 있다고 상상해 보십시오
디스플레이 독립 창 필터를 선택해서 디스플레이를 가로질러 이동할 때 창을 캡처합니다
디스플레이에 있는 모든 콘텐츠를 공유하고 싶더라도 제외하고 싶은 특정 콘텐츠가 있을 수 있습니다 예를 들어 거울의 방 효과를 피하고 싶다면 캡처 애플리케이션을 제외하세요
또한 특정 창이나 애플리케이션에 민감한 정보가 있어서 제외하고 싶을 수도 있습니다 이 모든 시나리오는 SCContentFilter에 의해 처리되므로 코드로 이동헤 이 작업을 수행하는 방법을 살펴보겠습니다
이전에 보여드린 코드 스니펫입니다
공유 가능한 콘텐츠가 쿼리된 후 코드는 캡처 샘플 앱과 같은 번들 식별자를 가진 애플리케이션을 찾습니다
그럼 디스플레이 종속 콘텐츠 필터가 스트림에서 앱을 제외합니다
콘텐츠 필터 외에도 ScreenCaptureKit은 스트림별로 조정할 수 있는 품질 및 성능 컨트롤을 제공합니다
SCStreamConfiguration에서 설정할 수 있습니다
일부 동영상 컨트롤에는 출력 해상도, 프레임 속도 및 마우스 커서 표시 여부가 포함됩니다
오디오 쪽에서는 오디오 활성화, 샘플 속도 변경 채널 수 조정이 가능합니다
이런 매개변수가 작용하는 시나리오를 안내해 드리겠습니다
메모나 스프레드시트같이 텍스트 선명도가 중요하고 움직임이 적은 화면 콘텐츠를 공유할 때는 캡처의 출력 해상도를 4k, 초당 10프레임으로 설정합니다
콘텐츠에 오디오가 없기 때문에 오디오를 비활성화 상태로 둘 수도 있습니다
하지만 최근 휴가 동영상처럼 움직임이 많은 콘텐츠의 경우 해상도보다 프레임 속도를 우선해야 합니다 출력 해상도를 1080p로 낮추고 초당 프레임을 60으로 증가시킵니다
커서 움직임이 주의를 산만하게 할 수 있기 때문에 커서를 숨기는 게 좋습니다
더욱 몰입감 있는 경험을 위해 오디오 캡처를 활성화할 수도 있습니다
이러한 모든 컨트롤은 SCStreamConfiguration에서 여러 속성을 통해 설정할 수 있습니다
다음은 움직임이 많은 콘텐츠를 공유하기 위한 구성 예시입니다
캡처의 출력 해상도는 1080p로 설정되었습니다 초당 60프레임으로 캡처하기 위해 최소 프레임 간격을 60분의 1로 설정합니다
마지막으로 스트림 구성으로 커서를 숨깁니다
오디오는 먼저 capturesAudio를 true로 설정하여 활성화하고 샘플 속도를 48kHz로 채널 수를 2로 설정합니다
SCContentFilter 및 SCStreamConfiguration을 쓰면 애플리케이션에 따라 화면 캡처를 설정하는 데 필요한 정보가 있습니다
이제 취합해서 SCStream을 만들 수 있습니다
다시 개요로 돌아가 보겠습니다
원하는 필터 및 구성으로 스트림을 초기화해야 합니다
또한 오류를 처리하기 위해 선택적 대리자를 전달할 수도 있습니다
설정이 끝나면 캡처 시작을 호출할 수 있으며 ScreenCaptureKit은 샘플이 있을 때 SCStream에 샘플을 제공합니다
필터와 구성이 생성되면 코드에서 스트림을 쉽게 시작할 수 있습니다 보여드리겠습니다
다시 한번 원하는 필터와 구성으로 SCStream 객체를 초기화할 수 있습니다
캡처 샘플 프로젝트에서 self는 오류 처리 대리자로 전달됩니다
SCStream이 생성되면 이제 startCapture를 호출할 수 있습니다
스트림을 초기화하고 시작한 후에는 미디어 샘플을 애플리케이션으로 가져와야 합니다
오디오 및 동영상 샘플은 CMSampleBuffers 형식으로 애플리케이션에 전송됩니다
스트림에서 해당 미디어 샘플을 가져오려면 SCStreamOutput 프로토콜을 스트림에 구현할 객체를 추가해야 합니다
스트림 출력을 추가할 때 핸들러 큐를 지정할 수도 있습니다
추가 디스패치 없이 샘플을 특정 대기열로 전달하려는 경우에 유용할 수 있습니다
대기열을 지정하지 않으면 기본 대기열이 사용됩니다
스트림이 시작되고 출력이 추가되면 ScreenCaptureKit은 새 샘플을 사용할 수 있을 때 콜백을 제공합니다
이제 코드에서 미디어 샘플을 가져오는 법을 보여드리겠습니다
다음은 새 미디어 샘플을 사용할 수 있을 때 호출되는 SCStreamOutputProtocol을 구현한 것입니다
ScreenCaptureKit은 이러한 샘플을 CMSampleBuffers로 제공하고 스트림 및 샘플 유형을 제공합니다
샘플 버퍼 핸들러를 구현한 후 스트림 출력을 추가하기만 하면 됩니다
이를 통해 스트림에서 미디어 샘플이 원하는 콘텐츠와 원하는 형식으로 애플리케이션에 전달됩니다
ScreenCaptureKit은 CMSampleBuffers 형식으로 샘플을 제공하므로 샘플 사용법에 대해 알아봅시다
동영상 측면에서 CMSampleBuffer는 IOSurface를 지원합니다
ScreenCaptureKit은 SCStreamFrameInfo의 CMSampleBuffer에 대한 첨부 파일도 제공합니다
이 첨부 파일은 수신하는 동영상 샘플에 대한 정보를 제공합니다
스트림의 현재 상태에 대한 프레임 상태를 확인하세요 완전한 프레임 상태는 새 동영상 프레임이 있음을 나타냅니다 유휴 프레임 상태는 동영상 샘플이 변경되지 않았으므로 새로운 IOSurface가 없음을 의미합니다
그렇지 않으면 제공된 샘플이 CMSampleBuffer와 같으므로 기존 CMSampleBuffer 유틸리티를 사용할 수 있습니다
ScreenCaptureKit에는 필터링된 화면 오디오 및 동영상 콘텐츠를 가져오는 데 도움이 되는 API가 있습니다 또한 프레임워크는 애플리케이션의 요구 사항에 맞는 다양한 개발자 컨트롤을 제공합니다
다양한 화면 캡처 경험을 시작하는 데 도움이 되는 몇 가지 기본 사항도 설명했습니다
ScreenCaptureKit 출시와 함께 이전 캡처 프레임워크인 CGDisplayStream 및 CGWindowList는 앞으로 사용되지 않습니다
이번 ScreenCaptureKit 도입으로 여러분도 저처럼 기쁘시다면 좋겠네요!
고급 주제를 볼 준비가 되면 'Take ScreenCaptureKit to the next level'로 이동하세요
시청해 주셔서 감사합니다!
-
-
6:53 - Creating a SCShareableContent object
// Creating a SCShareableContent object // Get the content that's available to capture. let content = try await SCShareableContent.excludingDesktopWindows( false, onScreenWindowsOnly: true )
-
8:32 - Creating a SCContentFilter object
// Creating a SCContentFilter object // Get the content that's available to capture. let content = try await SCShareableContent.excludingDesktopWindows( false, onScreenWindowsOnly: true ) // Exclude the sample app by matching the bundle identifier. let excludedApps = content.applications.filter { app in Bundle.main.bundleIdentifier == app.bundleIdentifier } // Create a content filter that excludes the sample app. filter = SCContentFilter(display: display, excludingApplications: excludedApps, exceptingWindows: [])
-
10:23 - Creating a SCStreamConfiguration object
// Creating a SCStreamConfiguration object let streamConfig = SCStreamConfiguration() // Set output resolution to 1080p streamConfig.width = 1920 streamConfig.height = 1080 // Set the capture interval at 60 fps streamConfig.minimumFrameInterval = CMTime(value: 1, timescale: CMTimeScale(60)) // Hides cursor streamConfig.showsCursor = false // Enable audio capture streamConfig.capturesAudio = true // Set sample rate to 48000 kHz stereo streamConfig.sampleRate = 48000 streamConfig.channelCount = 2
-
11:46 - Creating and starting a SCStream object
// Creating and starting a SCStream object // Create a capture stream with the filter and stream configuration stream = SCStream(filter: filter, configuration: streamConfig, delegate: self) // Start the capture session try await stream?.startCapture() // ... // Error handling delegate func stream(_ stream: SCStream, didStopWithError error: Error) { DispatchQueue.main.async { self.logger.error("Stream stopped with error: \(error.localizedDescription)") self.error = error self.isRecording = false } }
-
13:07 - Getting media samples
// SCStreamOutput protocol implementation func stream(_ stream: SCStream, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, of type: SCStreamOutputType) { switch type { case .screen: handleLatestScreenSample(sampleBuffer) case .audio: handleLatestAudioSample(sampleBuffer) } } // ... // Create a capture stream with the filter and stream configuration stream = SCStream(filter: filter, configuration: streamConfig, delegate: self) // Add a stream output to capture screen and audio content try stream?.addStreamOutput(self, type: .screen, sampleHandlerQueue: screenFrameOutputQueue) try stream?.addStreamOutput(self, type: .audio, sampleHandlerQueue: audioFrameOutputQueue) // Start the capture session try await stream?.startCapture()
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.