ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
ScreenCaptureKitによるHDRコンテンツのキャプチャ
ScreenCaptureKitを使用して、ハイダイナミックカラーをキャプチャする方法を確認しましょう。HDRのサポート、マイクからのキャプチャ、ファイルへの直接的な収録などの新機能もご紹介します。
関連する章
- 0:00 - Introduction and ScreenCaptureKit recap
- 1:20 - Capture HDR content
- 7:14 - Add microphone output
- 8:41 - Record to file
リソース
関連ビデオ
WWDC24
WWDC23
WWDC22
-
ダウンロード
ようこそ皆さん Benです ScreenCaptureKitチームの ソフトウェアエンジニアです 毎日多くの人が ScreenCaptureKitを使い ビデオ会議で画面を共有し 高品質なストリームを世界中の人と共有し スクリーンショットをキャプチャし リモートデスクトップアプリの サポートをしています ScreenCaptureKitを使うと アプリはシステムのUI体験と統合されます アプリには組み込みのピッカーがあり ストリームコンテンツを 選択できるようになっています
発表者用オーバーレイを利用して アプリの画面共有体験を 強化できます またアプリがシステムUIで何を 共有しているかプレビューできます 今日はScreenCaptureKitを使い アプリで同じような体験を 構築する新しい方法を紹介します アプリにストリーミング機能が あるとします これからはHDRでストリーミングや スクリーンショットをキャプチャできます 現在アプリは画面と音声コンテンツを キャプチャしているかもしれませんが 画面と音声サンプルを 提供するのと同じストリームから マイク出力を得る方法を紹介します
アプリが収録された 画面コンテンツを使用する場合は 便利な収録APIに 興味を持つでしょう ScreenCaptureKitはアセットの 書き込みの詳細をすべて処理します
HDRコンテンツをキャプチャする方法を 理解するために まずは画面と音声のキャプチャの 基本について学びましょう
こちらがSCStreamで アプリで画面や音声の サンプルを受信するためのオブジェクトです 画面全体または特定のウインドウや アプリをキャプチャするために使用します
ストリームにSCContentFilterを渡して 何をキャプチャするかを指定します ストリームの出力を カスタマイズするとします さまざまな解像度やピクセル フォーマットの指定などです それにはSCStreamConfigurationで ストリーム出力をカスタマイズします
ストリームを設定したら SCStreamOutputを使い 画面と音声のサンプルを 受け取ることができます
以上がコンテンツを取り込むための 基本的な構成要素ですが 詳細は以前のScreenCaptureKitの ビデオをご覧ください
今年からHDRコンテンツを 取り込めるようになりました ハイダイナミックレンジ(HDR)は スタンダードダイナミックレンジ (SDR)と比べて より広い範囲の 輝度レベルと色を表示できます HDRはハイコントラストで シャドウとハイライトの両方の ディテールがより鮮明になります
幅広いカラーも提供します
今回SCStreamでは キャプチャしたコンテンツのハイダイナミック レンジを出力可能になりました HDRコンテンツの ストリーミングを受信する人に ソースと同じ豊かな ディテールが再現されます
アプリでHDRキャプチャを有効にするには SCStreamConfigurationに 新しいプロパティを設定して ストリームを設定します プロパティは次の通りです
captureDynamicRangeは ScreenCaptureKitにSDRまたはHDRで 画面コンテンツを出力するよう指示します HDRの場合は hdrLocalDisplayか hdrCanonicalDisplayに設定します ところでローカルディスプレイと 標準ディスプレイの違いとは何でしょうか
ローカルディスプレイを使う時は ScreenCaptureKitに HDRコンテンツの取り込みとレンダリングの 両方を同じ画面で行うと指示しています
標準ディスプレイの場合 取り込んでいるHDRコンテンツを ほかのHDR対応デバイスと 共有できるように最適化します
次に設定するプロパティは pixelFormatです 画像の各ピクセルの色情報を 格納する方法を記述します
HDRの場合は各成分が 10ビット以上のフォーマットを使用します ほとんどの状況では10ビットYCbCrが 最適な選択肢です
3つ目のプロパティは colorSpaceNameで 色の範囲とそれらがデジタル値に マッピングされる方法の 伝達関数を示します HDRにはHLGまたはPQの伝達関数の いずれかが必要です 例えばDisplay P3 PQ色空間です
最後にcolorMatrixですが これはBGRA色空間とYCbCr色空間で 色を変換するために使われます 情報がありすぎると感じるかも しれませんがご心配なく SCStreamConfigurationが 役に立つからです HDR用の2つの便利な プリセットが用意されています captureHDRStreamLocalDisplayと captureHDRStreamCanonicalDisplayです
取り込んだHDRコンテンツの出力先が ローカルディスプレイの場合 ローカルディスプレイ プリセットを使用します この設定にはここに含まれる値が 事前入力されます
HDRコンテンツの出力先が ほかのディスプレイの場合は 標準ディスプレイプリセットを使用します このプリセット値の一覧です アプリに別の出力設定が必要な場合は アプリのニーズに合わせて自由に プロパティを変更できます ではプリセットを使ってHDRをキャプチャする コード例を見てみましょう
まずはSCShareableContentを使い 利用可能なコンテンツのリストを取得します
ここで画面全体をキャプチャするので 画面全体をキャプチャする SCContentFilterを作成します あらかじめ用意されている 新しいAPIを使い HDR標準ディスプレイの 設定を取得します
フィルタと設定を使って SCStreamを作成します
アプリでHDRスクリーンサンプルを 受信するには スクリーンタイプの出力を追加します
最後に配信を開始して HDRサンプルの受信を開始します アプリにストリームではなくスクリーン ショットが1つだけ必要という場合のために SCScreenshotManagerは スクリーンショットAPIを提供しています このAPIを使って HDRでスクリーンショットを 撮ることもできます
SCStreamと同じように SCScreenshotManagerは コンテンツフィルタと ストリーム設定を使用します SCStreamと同じようにHDRスクリーン ショットを撮るためのプリセットもあります ローカルまたは標準ディスプレイで HDRスクリーンショットを撮る際の 推奨プリセット値を示します
ローカルディスプレイプリセットを使って HDRスクリーンショットを撮るコードの例です
最初に行うのはHDRローカル ディスプレイの設定です アプリがスクリーンショットのために CMSampleBuffersを必要とする場合 captureSampleBuffer関数を使います
CGImageが望ましい場合 captureImage関数を使います
新しいAPIを使って ストリームとスクリーンショットの 両方から驚くほど美しいHDRコンテンツを 取得する方法を紹介しました アプリでHDRを活用する方法を さらに詳しく知りたい場合は HDR画像やメディアのサポートに関する こちらのビデオをぜひご覧ください これで ScreenCaptureKitでHDR画像や ビデオのキャプチャを始められます 美しいHDRストリームに合わせて 今年は マイクと システム音声で 収録できるようになりました ストリームに新しい マイク出力を提供することで アプリは3種類のメディアを取り込めます 画面 システム音声 マイクです
アプリがマイク音声を ストリームに取り込むために SCStreamConfigurationは 2つの新しいプロパティを提供します captureMicrophoneを使うと アプリがマイクキャプチャをオンにします microphoneCaptureDeviceIDで どのマイクデバイスを使って 取り込むか選択できます
アプリでマイクのサンプルを受信するには SCStreamOutputを使います それではマイクの音声を 取り込むコードを説明します まずストリーム設定を作成して SCStreamに マイクをキャプチャするよう指示します microphoneCaptureDeviceIDと captureMicrophoneプロパティを設定して デフォルトのマイクを録音します フィルタと設定で SCStreamを作成します ここで新しいマイクタイプの出力を ストリームに追加します 取り込みを開始し SCStreamOutputの didOutputSampleBuffer関数を 使用してサンプルを受信します これだけです アプリはすべての画面 音声 マイクの コンテンツをSCStreamから取得します ストリーム出力を受け取る 一般的な用途の1つは サンプルをファイルに書き込むことです SCStreamに追加された 新しいAPIを使用することで これを実現できます このAPIを使用すると 画面 音声 マイクのコンテンツを 簡単にアプリに収録し保存できます 仕組みを見てみましょう 先ほどと同じようにSCStreamを 設定してコンテンツを取り込みます 収録でも同じストリームを使います 収録するにはこの新しい出力を 追加するだけです SCRecordingOutputConfigurationで SCRecordingOutputを設定できます この設定ではファイルの保存場所 ファイルタイプ ビデオコーデックを指定できます
またストリーム上の収録イベントに 応答するために使用できる新しい SCRecordingOutputDelegate プロトコルもあります では この新しいAPIを使って収録する コードを見ていきましょう まず SCRecordingOutputConfiguration のインスタンスを作成します outputURLを設定し ファイルの保存先を指定します
必要に応じて保存ファイルのファイルタイプや ビデオコーデックをカスタマイズできます 次に 収録設定で SCRecordingOutputインスタンスを作成し イベント受信用のデリゲートを設定します
次に 設定したrecordingOutputを ストリームに追加します startCaptureを呼び出してストリーミングを 開始すると収録も開始されます その後好きな時点で stopCaptureを呼び出し ストリームと収録の両方を停止します ときには収録を停止したあとも ストリーミングを続けたいこともあります コンテンツのストリーミングを続けるには 収録だけを停止するために removeRecordingOutputを呼び出します
収録中 アプリへのイベントの通知は SCRecordingOutputDelegteで行われます 通知が行われるのは 収録開始時 エラー発生時 収録が正常に終了した時です これで収録ファイルをアプリで 使用する準備が整いました
以上です この新しい収録APIにより アプリで簡単かつ便利に 画面 音声 マイクの コンテンツを収録できます
今後はScreenCaptureKitを使い アプリでHDRコンテンツを取り込めます 新しいマイク出力が利用可能となり ストリームからマイクの サンプルを受け取れます そして 新しい収録APIで 画面 音声 マイクの コンテンツを簡単に収録できます ScreenCaptureKitが提供する 素晴らしい機能について 詳しくは以前のビデオをご覧ください ご視聴ありがとうございました
-
-
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. }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。