前段时间有碰到Android用户使用系统录屏发来的一些bug重现录像,iOS端不会用系统录屏的用户都是拍视频联系产品然后反馈给我们开发,这中间有的时候挺耗费时间和精力的,空下来就琢磨了下iOS的录屏使用。录屏用得比较多的是苹果自带的ReplayKit框架,不需要导包,使用比较便捷,而且耗费内存较小,基本忽略不计,这也是我选择ReplayKit的原因,如对功能研究较感兴趣的同学可以忽略本篇。
我使用的手机是锤子M1的是比较老的版本,我对照着锤子做了一个简单的demo,效果图如下:
效果图
系统版本9.0以下ReplayKit是不可使用的,所以在使用前一定要判断系统版本是否符合要求,在Targets->Build Settings->iOS Deployment Target中设置的版本号高于9.0也可使用,也可加if #avaliable(iOS 9.0,*)判断减少此类风险,这边是个大坑,我写的demo中Timer等需要10.0以上版本,所以请勿抬杠,个人因情况而定。
Targets->Build Settings->iOS Deployment Target
工具条对应的文件
“展示录屏控件”触发方法,在给ReplayToolsView中的关闭按钮和录屏开始按钮加事件的时候我是使用的闭包,这样可以控制效果图中红色按钮的状态;对红色按钮的状态判断是为了避免多次点击按钮后ReplayToolsView的叠加;replayVideoView.addGestureRecognizer给replayVideoView添加移动手势,王者荣耀中在录屏时按钮是固定的,以下demo中的录屏可以在整个app中使用,包括记录页面跳转过程等。
@IBAction func showActionView(_ sender: UIButton) {
if !self.showViewBtn.isSelected {
let replayVideoView = ReplayToolsView(frame: CGRect(x: 20, y: self.view.bounds.height-100, width: self.view.bounds.width-40, height: 50))
//使用block代替在view中编写关闭方法,添加对“app录屏”按钮的选中状态设置
replayVideoView.closeBlock = { () in
//此处设置结束录制后将replayVideoView移除,也可以隐藏isHidden,在此处和startRecordingScreen方法中将view改成隐藏,replayVideoView需要改为全局变量使用
replayVideoView.removeFromSuperview()
self.showViewBtn.isSelected = !self.showViewBtn.isSelected
}
replayVideoView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(dragFunction)))
replayVideoView.actionBlock = {
self.startRecordingScreen(replayVideoView)
replayVideoView.closeButton.isHidden = replayVideoView.actionButton.isSelected
}
let window = UIApplication.shared.keyWindow
window!.addSubview(replayVideoView)
self.showViewBtn.isSelected = !self.showViewBtn.isSelected
}
}
// Janise: 设置拖动手势(可用于拖动控件后设置控件依赖位置,此处只设置可在y轴方向上移动,如需要在x方向上移动,可对x位置修改)
@objc func dragFunction(_ pan: UIPanGestureRecognizer) {
let point = pan.translation(in: view)
if let v = pan.view {
//设置移至顶部和底部时不可移动,64为个人主观设置值,可根据个人需要更改
if (v.frame.origin.y > 64 && point.y < 0)
|| (v.frame.origin.y + v.frame.height < (UIApplication.shared.keyWindow?.frame.height)! && point.y > 0) {
v.center.y = v.center.y + point.y
}
pan.setTranslation(.zero, in: view)
}
}
// Janise: 开始录制屏幕(考虑问题,可否像android那样在录屏时不将ReplayVideoToolView视图作为屏幕的一部分录制,我暂时还没找到方法)
/// 开始录屏(遗留问题:初次录屏时会询问用户是否同意使用录屏功能,但是时间在用户点击录屏按钮时已开始计时,与用户同意使用录屏功能时间点有时间差,这部分需要解决)
///
/// - Parameter toolView: 自制黑色半透明录屏视图(用于图标的展示修改和时间的变化)
@objc func startRecordingScreen(_ toolView: ReplayToolsView) {
// 检测设备是否支持录屏功能
if RPScreenRecorder.shared().isAvailable && systemVersionAvaliable() {
//录屏按钮是否选中
if toolView.actionButton.isSelected {
//停止计时
self.time?.invalidate()
self.time = nil
toolView.seconds = 0
//选中状态下停止录制
RPScreenRecorder.shared().stopRecording { (previewCon, error) in
if let errors = error {
print(errors)
}
if let controller = previewCon {
controller.previewControllerDelegate = self
UIApplication.shared.keyWindow?.rootViewController?.present(controller, animated: true, completion: nil)
}
}
toolView.actionButton.isSelected = false
toolView.removeFromSuperview()
self.showViewBtn.isSelected = !self.showViewBtn.isSelected
return
}else {
//开始计时
self.time = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { (timer) in
toolView.seconds += 1
})
//未选中状态下开始录屏
RPScreenRecorder.shared().startRecording { (err) in
if let error = err {
print(error)
}
}
toolView.actionButton.isSelected = true
}
}else {
// //正式编写时需将两种提示分开展示,权限与版本两个不可合二为一
// let alert = UIAlertController(title: "提示", message: "请先授予app录屏权限,系统版本低于9.0不支持录屏功能,请升级版本后使用该功能", preferredStyle: .alert)
// self.present(alert, animated: true, completion: nil)
}
}
/// 视频播放
///
/// - Parameter previewController: 视频预览播放器
func previewControllerDidFinish(_ previewController: RPPreviewViewController) {
//关闭视频预览
previewController.dismiss(animated: true, completion: nil)
}
/// 判断版本是否在9.0版本及以上版本
///
/// - Returns: 布尔值
func systemVersionAvaliable() -> Bool {
if #available(iOS 9.0, *) {
return true
}
return false
}
replayVideoView的编写较为简单,此处不做展示。
我没有添加麦克风录音功能,startRecording(withMicrophoneEnabled:true...在10.0版本已被弃用,我在找其他的方法来替代。
RPScreenRecorder.shared().startRecording(withMicrophoneEnabled:true) { (<#Error?#>)in
<#code#>
}
ReplayKit不可以与AVPlayer同用,会出现兼容问题,录屏功能只能在真机上使用,虚拟机不支持,我是用的Swift编写,网上较多的使用OC,IOS 一个很好的录制屏幕实现IOS功能 - 飞翔的熊blabla - CSDN博客csdn上这篇写得比较好。
以上代码我传到了GitHub上,地址是demo
网友评论