介绍
ReplayKit是与iOS 9一起引入的新框架。它使游戏开发人员可以使玩家轻松记录和共享游戏玩法。 除了录制和共享,ReplayKit还包括一个功能齐全的用户界面,玩家可以用来编辑其视频剪辑。
ReplayKit产生的录音具有高清晰度,并且创建时耗电量和性能损失最小。 ReplayKit的功能可用于运行A9,A8或A9片上系统的每个设备(每个支持Metal的设备),运行iOS 9或更高版本。
先决条件
本教程要求您在OS X Yosemite或更高版本上运行Xcode 7+。 如果要在设备上测试示例项目,则还需要支持ReplayKit的设备。 您还需要从GitHub下载入门项目。
1.开始录音
使用ReplayKit录制游戏玩法始于RPScreenRecorder
类和可用于您的应用程序的sharedRecorder()
。 该记录器负责检查设备记录,开始,停止和丢弃记录的能力,还可以选择启用设备的麦克风以允许玩家在游戏音频上添加自己的实时语音评论。
打开您从GitHub下载的入门项目,然后转到GameViewController.swift 。 在此文件的顶部,为ReplayKit框架添加导入语句。
import ReplayKit
接下来,在GameViewController
类中实现startRecording(_:)
方法。 当用户点击“ 开始录制”按钮时,将调用此方法。
func startRecording(sender: UIButton) {
if RPScreenRecorder.sharedRecorder().available {
RPScreenRecorder.sharedRecorder().startRecordingWithMicrophoneEnabled(true, handler: { (error: NSError?) -> Void in
if error == nil { // Recording has started
sender.removeTarget(self, action: "startRecording:", forControlEvents: .TouchUpInside)
sender.addTarget(self, action: "stopRecording:", forControlEvents: .TouchUpInside)
sender.setTitle("Stop Recording", forState: .Normal)
sender.setTitleColor(UIColor.redColor(), forState: .Normal)
} else {
// Handle error
}
})
} else {
// Display UI for recording being unavailable
}
}
让我们逐步介绍该方法。 我们通过sharedRecorder()
方法访问可用于我们的应用程序的RPScreenRecorder
实例,并检查记录是否可用于该设备。
如果有记录可用,我们通过在共享记录器对象上调用startRecordingWithMicrophone(_:handler:)
方法来开始记录。 此方法的参数是布尔值(表示是否要使用设备的麦克风)和完成处理程序。 完成处理程序可以访问一个可选的错误对象,如果发生问题,该对象将由ReplayKit框架返回给您。 如果框架没有引发错误,我们将调整按钮的目标和外观,以便用户可以在准备就绪时停止录制。
生成并运行您的应用程序,然后点击绿色按钮以试用该应用程序。 您将看到按下绿色按钮时,场景中的粒子系统会生成粒子。 如果点击开始录制 ,您将看到以下警报:
请注意,此警报将在您每次开始在应用程序中记录时出现。 但是,一旦用户选择了这些选项之一,便会记住他们的首选项,并且在接下来的八分钟内不会显示任何警报。
从警报中选择这些选项之一后,“ 开始录制”按钮应变成红色的“ 停止录制”按钮。
2.停止,丢弃和编辑记录
既然我们的应用程序能够开始ReplayKit录音,那么现在该学习完成后如何处理这些录音了。 实施stopRecording(_:)
的方法GameViewController
类。
func stopRecording(sender: UIButton) {
RPScreenRecorder.sharedRecorder().stopRecordingWithHandler { (previewController: RPPreviewViewController?, error: NSError?) -> Void in
if previewController != nil {
let alertController = UIAlertController(title: "Recording", message: "Do you wish to discard or view your gameplay recording?", preferredStyle: .Alert)
let discardAction = UIAlertAction(title: "Discard", style: .Default) { (action: UIAlertAction) in
RPScreenRecorder.sharedRecorder().discardRecordingWithHandler({ () -> Void in
// Executed once recording has successfully been discarded
})
}
let viewAction = UIAlertAction(title: "View", style: .Default, handler: { (action: UIAlertAction) -> Void in
self.presentViewController(previewController!, animated: true, completion: nil)
})
alertController.addAction(discardAction)
alertController.addAction(viewAction)
self.presentViewController(alertController, animated: true, completion: nil)
sender.removeTarget(self, action: "stopRecording:", forControlEvents: .TouchUpInside)
sender.addTarget(self, action: "startRecording:", forControlEvents: .TouchUpInside)
sender.setTitle("Start Recording", forState: .Normal)
sender.setTitleColor(UIColor.blueColor(), forState: .Normal)
} else {
// Handle error
}
}
}
再一次,让我们一步一步地介绍此方法。 我们在共享记录器对象上调用stopRecordingWithHandler(_:)
方法。 在此完成处理程序中,我们通过检查previewController
存在来验证录制是否成功完成。
我们使用两个动作创建一个UIAlertController
,一个用于丢弃记录,一个用于查看记录。 如果用户选择放弃录音,则调用discardRecordingWithHandler(_:)
。 请注意,只有在录制完成后才能成功调用此方法。 如果在录制过程中调用此方法,则不会引发任何错误,但是也不会丢弃任何录制数据。
如果用户选择查看记录,我们将提供stopRecordingWithHandler(_:)
方法提供给我们的previewController
,它是RPPreviewController
类的实例,用户可以在其中预览,编辑和共享他们的记录。 预览控制器是唯一有权访问ReplayKit生成的视频文件的对象,并负责保存/共享该记录。
最后,我们将按钮恢复到其原始状态,以便用户愿意时可以进行另一次录制。
再次构建并运行您的应用,然后开始录制。 一旦您按停止记录按钮,您应该看到以下警报:
如果然后按“ 视图”选项,则会显示以下视图控制器。
在此屏幕上,您可以编辑视频,然后按“ 保存”按钮将其保存到设备的相机胶卷中。 您也可以通过按左下角的按钮来共享它。
请注意,在编写本教程时,无论是设计使然还是由于ReplayKit框架中的错误,一旦将记录保存到相机胶卷上都无法确认。
3.排除接口元素
您可能已经注意到顶部和底部按钮在应用程序录制的录像中也可见。 它们包含在最终视频中。 当ReplayKit记录您的应用程序时,它将所有内容记录在您应用程序的主UIWindow
实例中。 幸运的是,ReplayKit会自动从记录中排除任何传入的通知和用户输入。
要从记录中排除用户界面元素,您需要将它们放置在它们自己的单独的UIWindow
实例中。 让我们看看它是如何工作的。 添加一个属性, UIWindow!
类型的buttonWindow
UIWindow!
,到GameViewController
类。
var buttonWindow: UIWindow!
接下来,将GameViewController
类的addButtons(_:)
方法的当前实现替换为以下实现:
func addButtons(buttons: [UIButton]) {
self.buttonWindow = UIWindow(frame: self.view.frame)
self.buttonWindow.rootViewController = HiddenStatusBarViewController()
for button in buttons {
self.buttonWindow.rootViewController?.view.addSubview(button)
}
self.buttonWindow.makeKeyAndVisible()
}
在addButtons(_:)
,我们创建一个新的UIWindow
对象,向其中添加按钮,并使它可见。 请注意, HiddenStatusBarViewController
类是自定义类,我已将其添加到入门项目中。 这样可以确保状态栏在新窗口中保持隐藏状态。
最后,用以下实现替换stopRecording(:_)
方法的实现:
func stopRecording(sender: UIButton) {
RPScreenRecorder.sharedRecorder().stopRecordingWithHandler { (previewController: RPPreviewViewController?, error: NSError?) -> Void in
if previewController != nil {
let alertController = UIAlertController(title: "Recording", message: "Do you wish to discard or view your gameplay recording?", preferredStyle: .Alert)
let discardAction = UIAlertAction(title: "Discard", style: .Default) { (action: UIAlertAction) in
RPScreenRecorder.sharedRecorder().discardRecordingWithHandler({ () -> Void in
// Executed once recording has successfully been discarded
})
}
let viewAction = UIAlertAction(title: "View", style: .Default, handler: { (action: UIAlertAction) -> Void in
self.buttonWindow.rootViewController?.presentViewController(previewController!, animated: true, completion: nil)
})
alertController.addAction(discardAction)
alertController.addAction(viewAction)
print(self.buttonWindow.rootViewController)
self.buttonWindow.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
sender.removeTarget(self, action: "stopRecording:", forControlEvents: .TouchUpInside)
sender.addTarget(self, action: "startRecording:", forControlEvents: .TouchUpInside)
sender.setTitle("Start Recording", forState: .Normal)
sender.setTitleColor(UIColor.blueColor(), forState: .Normal)
} else {
// Handle error
}
}
}
唯一的不同是,我们使视图控制器在新的,最顶部的窗口中处理所有演示。 这样可以确保所有内容都能正确显示,并且可以与用户界面进行交互。
再次运行您的应用程序并进行新的录制。 您会看到按钮在视频中不再可见:
4.委托协议
虽然在本教程中未使用,但与ReplayKit关联的协议有两种,共有四种。 让我们看看什么时候应该使用它们。
RPScreenRecorderDelegate
协议定义以下方法:
-
screenRecorder(_:didStopRecordingWithError:previewViewController:)
:每当在录制过程中发生错误时,都会调用此方法。 如果ReplayKit可以从此错误中恢复并完成录制,则还将为您提供预览视图控制器,您可以将其呈现给用户。 -
screenRecorderDidChangeAvailability(_:)
:每当录制由于其他操作而变得可用或不可用时,都会调用此方法。 例如,当您连接或断开AirPlay时,可能会发生这种情况。
RPPreviewViewControllerDelegate
协议定义以下方法:
- 一旦用户关闭
RPPreviewViewController
实例,就会调用previewViewControllerDidFinish(_:)
。 -
previewViewController(_:didFinishWithActivityTypes:)
被称为在同一时间previewViewControllerDidFinish(_:)
,但它提供了一个额外的UIActivity
参数。
请注意,如果您实现RPPreviewViewControllerDelegate
方法之一,则您有责任在适当的时候关闭预览视图控制器。
5.重要说明
最后,我将告诉您使用ReplayKit时要记住的一些关键事项。
- 每个应用程序一次只能存储一个记录。 开始新的录制后,如果以前的录制存在,它将自动被丢弃并且不再可用。
- 尽快丢弃录音。 为确保设备的本地存储不会充满不必要的视频数据,请在得知用户以后不会或无法访问其记录后立即丢弃记录。 在本教程中,我们遵循最佳实践,在知道用户不想查看记录后立即将其丢弃。
- 显示录音指示符。 就像我们在本教程中所做的那样,在使用ReplayKit时,尤其是在使用设备的麦克风时,显示录制指示器对于良好的用户体验至关重要。
- 仔细选择要从录音中排除的用户界面元素。 选择将哪些界面元素放置在单独的窗口中时,请选择任何不重要或不影响游戏本身的项目。 其中包括录制指示器,虚拟控件和菜单按钮之类的内容。
- 您没有直接访问最终视频文件的权限。 只有ReplayKit在存储中保存对您的应用程序录制的引用,并通过
RPPreviewViewController
使这些录制对用户可见。 出于隐私原因,您的应用程序永远无法直接访问ReplayKit录音。 例如,如果您要将游戏记录上传到自己的服务器上,则必须创建一个共享扩展名,该扩展名将显示在预览视图控制器显示的共享表中。 - ReplayKit支持父母控制。 即使您的应用程序在兼容设备上运行,而没有其他应用程序在后台运行,由于父母的控制,仍然可以阻止开始录制。 这意味着您始终需要检查是否可以录制视频。
- 最后,即使Apple已将ReplayKit面向游戏开发人员以允许游戏玩家共享游戏玩法,也没有什么可以阻止您在常规应用程序中使用ReplayKit。 ReplayKit适用于使用Xcode 7和iOS 9 SDK构建的每个应用程序。 如果您在应用程序中使用过它,我鼓励您使用这个出色的框架。
结论
现在,您应该可以轻松使用新的ReplayKit框架来录制应用程序的屏幕,并可以由用户编辑和共享。 总体而言,ReplayKit是一个非常紧凑但功能强大的框架,使开发人员可以轻松地在其应用程序中创建由用户共享的录音。
与往常一样,请确保在下面的评论中留下任何评论或反馈。
翻译自: https://code.tutsplus.com/tutorials/ios-9-an-introduction-to-replaykit--cms-25458