ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
ReplayKitによるローリングクリップ
ゲームやAppで、誰かの素晴らしい瞬間を見逃すことはもうありません。過去のビデオやオーディオサンプルのローリングバッファを提供するReplayKitの最新のアップデート(クリップスクリーンレコーディング)について紹介します。忘れられない瞬間が起きたとき、それを記録して人々のために保存し、最も関連性の高いときにそれらのクリップを表示する方法をご確認ください。最後に、ReplayKitをiOSやmacOSのAppに統合する方法を紹介します。
リソース
関連ビデオ
WWDC21
WWDC20
-
ダウンロード
ようこそ 「ReplayKitによるローリングクリップ」へ ReplayKitチームの ソフトウェアエンジニアの Ernestです 今日はApp内でのハイライトを 録画する方法を紹介します まずReplayKitの概要を解説します
ReplayKitはApp画面と音声を 録画する方法です マニュアル動画を作るときや ゲームプレイを公開したいとき App内で画面収録して動画を作成し 保存して友人と共有できます 作った動画をより細かく 加工したいとき フィルタやオーバーレイが必要なら App内画面録画で可能です それにより 音声・動画サンプルを Appの処理に直接送り 作成するコンテンツを 完全にコントロールできます ゲームをプレイする次に 楽しいのは ゲーム実況観戦です App内ブロードキャストで簡単に サードパーティ配信サービスに Appをストリームし 世界中から視聴できます 我々の従来の録画機能は 幅広い用途に 対応していますが ひとつ未対応でした ユーザーが敵を全滅させ 次のレベルに進むとき その瞬間を友人と 共有したいとします でもそのレベルが初めてで エキサイティングな展開を 想定していないと 最高の瞬間をキャプチャできません 現行では 全ハイライトを残すには 全ゲームプレイの 記録が必要です その結果巨大な動画ができ 容量を圧迫し 短く編集するには時間もかかります ハイライトの瞬間を 全てその都度 記録したいですよね さらにReplayKitが それをやってくれて ハイライト動画を 渡してくれるとしたら? 今回うれしいことに そんな新機能をご紹介できます クリップレコーディングです この機能では 音声や動画サンプルの ローリングバッファを保存します クリップのエクスポートが呼び出されると 直前の最長15秒の動画を書き出します これで録画の開始のタイミングを 指定する必要がなくなり 書き出しのタイミングを指定する だけで済みます
クリップを書き出す方法は複数あります App内にUIボタンや コントローラ対応を 追加すれば ユーザーが手動で 録画するタイミングを指定できます ボタンのタップだけで 欲しい瞬間そのものの 動画が撮れます App内にトリガーを入れて 自動録画することも可能です これでいつでも 最高の瞬間を残せます 完璧なコンボや ラスボス撃退 最高速度達成などなど クリップを使って 個々にカスタマイズされた 体験を作成することもできます カスタムオーバーレイを入れて そこから動画のリストを表示したり ハイライト動画を レベルの最後に表示し 共有可能にもできます
クリップレコーディングはiOSと macOSで利用可能で 強力な機能として既存の 録画やキャプチャ ブロードキャスト のAPIに加わります 他の機能と同様 クリップレコーディングは HD画質で 性能上のインパクトは低く プライバシー保護も 組み込まれています 内部の処理は どうなっているか 見てみましょう クリップレコーディングのAPIは3つ 開始 停止 書き出しがあり バッファを開始するには RPScreenRecorderを呼び出し sharedRecorderの 単一インスタンスを得ます 共有インスタンスでは startClipBuffering APIを 呼び出せます するとReplayKitがAppから 画面録画と音声サンプルを ローリングバッファに保存します ReplayKitは 新たなサンプルを得るたび 15秒より前のサンプルを 削除します ローリングバッファ開始後 ReplayKitは Appからの 書き出し指示を待機します Appは 書出しクリップAPIを呼ぶだけで ReplayKitがそれ以降を処理し 指定の瞬間の動画を返します バッファが不要になった時や 例えばApp内ブロードキャスト等の ReplayKitの他の機能を利用する際 停止APIを呼べば ReplayKitが セッションを止めます
これを踏まえ このAPI実装のサンプルを お見せします このサンプルプロジェクトを ご存じかもしれません 昨年も使いましたから 今回はクリップの コードが加わりました コードを見てみましょう 他の録画セッションと同じく IBActionが クリップ開始ボタンと 関連付けられています このボタンは バッファしていない時は バッファを開始 すでにバッファが動いている 時は停止します 次にクリップバッファの 開始後を見てみます これはバッファを 開始するコードです 共有録画インスタンスが RPScreenRecorderで得られ startClipBufferingを 完了ハンドラで呼び出せます 完了ハンドラの中で 開始の試行中に起きたエラーに 対応しておきます UIの更新など エラーがない場合も UIを更新して 録画を開始したことを示す 必要があります
停止のメソッドも このサンプルにあります ここで共有インスタンスを得ますが この場合呼ぶのは停止APIです 完了ハンドラでも 停止の試行中に起きた エラー対応をします UIも更新し録画停止を伝えます
開始と停止のコードを 見てきたので 次はクリップの書き出しです これは書き出しボタンと 関連付いたIBActionのコードです このアクションは ユーザーが動画を 作りたい時にトリガーされます ただしこの方法に限らず App内のトリガーを使って 自動に書き出すことも可能です ここでは 録画が有効になっていて ボタンも その前のstartClipBuffering メソッドで有効になっていれば exportClip関数が呼び出されます exportClip APIを呼ぶには URLと動画のクリップの長さを指定します
開始と停止のAPIと同様に エラーには完了ハンドラで 対応しておきます エラーがなければ 指定のURLで動画を得られます クリップにより独自のユーザー体験を 構築できます このサンプルコードでは クリップは写真に保存
以上です 3つのAPIでクリップレコーディングを Appに組み込めます クリップには所定のURLで 直接アクセスでき 独自のApp内体験を 構築できます 前述の通り 別の方法として ゲームコントローラ対応の 追加があります ゲームコントローラの フレームワークには クリップレコーディングが 組み込まれています ゲームコントローラから 書き出したクリップは 写真Appかデスクトップに 直接保存されます そのため作成されたクリップを Appで使うには ReplayKit clips APIを 実装する必要があります ReplayKitとゲームコントローラ フレームワークを融合するには キー値による監視を 使用可能と記録中 両方のプロパティに対し RPScreenRecorder上で 指定するのが良いです RPScreenRecorderDelegateの プロトコルに従い Appの状態を必要に応じ 更新できるようにします クリップレコーディングを Appに統合するのは それくらい簡単です クリップレコーディングを使えば わくわくする瞬間を リアルタイムで捉えられます たくさんのクリップを使った 新たなユーザー体験を 楽しみにしています ご視聴 ありがとうございます 素晴らしいWWDCを [音楽]
-
-
5:19 - Start clip buffering
// Start clip buffering API call func startClipBuffering() { RPScreenRecorder.shared().startClipBuffering { error in if error != nil { print("Error attempting to start Clip Buffering") // Update the app recording state and UI. self.setClipState(active: false) } else { // No error encountered attempting to start a clip session. // Update the app recording state and UI. self.setClipState(active: true) // Set up camera View. self.setupCameraView() } } }
-
5:46 - Stop clip buffering
// Stop clip buffering func stopClipBuffering() { RPScreenRecorder.shared().stopClipBuffering { error in if error != nil { print("Error attempting to stop clip buffering") } // Update the app recording state and UI. self.setClipState(active: false) // Tear down camera view. self.tearDownCameraView() } }
-
6:13 - Export clip button
// Export clip button @IBAction func exportClipButtonTapped(_ sender: Any) { // If clip buffering is active, export clip if self.isActive && self.getClipButton.isEnabled { exportClip() } }
-
6:41 - Export clip
// Export clip func exportClip() { let clipURL = getAppTempDirectory() let interval = TimeInterval(5) print("Generating clip at URL: \(clipURL)") RPScreenRecorder.shared().exportClip(to: clipURL, duration: interval) { error in if error != nil { print("Error attempting to export clip") } else { // No error, so save clip at URL to photos self.saveToPhotos(tempURL: clipURL) } } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。