• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

iOS-Swift使用ReplayKit实现录屏功能

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

iOS-Swift使用ReplayKit实现录屏功能

前段时间有碰到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以上版本,所以请勿抬杠,个人因情况而定。


“展示录屏控件”触发方法,在给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


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
6.1 使用扩展(extension)扩展类型的属性 [Swift原创教程]发布时间:2022-07-14
下一篇:
如何在 Swift 中进行错误处理发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap