ios – 如何在SpriteKit SKScene类中启动ReplayKit屏幕录制

ios – 如何在SpriteKit SKScene类中启动ReplayKit屏幕录制,第1张

概述我在我的SpriteKit游戏中实现了ReplayKit,但由于一切都在GameViewController中完成,因此记录按钮显得过早.请参阅下面的GameViewController类: class GameViewController: UIViewController, RPPreviewViewControllerDelegate {var videoRecButton: UIBut 我在我的SpriteKit游戏中实现了ReplayKit,但由于一切都在GameVIEwController中完成,因此记录按钮显得过早.请参阅下面的GameVIEwController类:

class GameVIEwController: UIVIEwController,RPPrevIEwVIEwControllerDelegate {var vIDeoRecbutton: UIbutton!var vIDeoRecImage: UIImage!overrIDe func vIEwDIDLoad() {    super.vIEwDIDLoad()    let skVIEw = self.vIEw as? SKVIEw    if skVIEw?.scene == nil  {        skVIEw?.showsFPS = true        skVIEw?.showsNodeCount = true        skVIEw?.showsPhysics = true        skVIEw?.ignoresSiblingOrder = false        //starting the game with the Poster Scene        let posterScene = PosterScene(size: skVIEw!.bounds.size)        posterScene.scaleMode = .aspectFill        skVIEw?.presentScene(posterScene)    }    vIDeoRecbutton = UIbutton(type: .custom)    vIDeoRecImage = UIImage(named:"vIDeoRecbutton.png")    vIDeoRecbutton.frame = CGRect(x:0,y: 0,wIDth: (vIDeoRecImage?.size.wIDth)!,height: (vIDeoRecImage?.size.height)!)    vIDeoRecbutton.setimage(vIDeoRecImage,for: .normal)    vIDeoRecbutton.addTarget(self,action:#selector(self.vIDeoRecbuttonClicked),for: .touchUpInsIDe)    self.vIEw.addSubvIEw(vIDeoRecbutton)}func vIDeoRecbuttonClicked() {    print("button Clicked")    startRecording()}func startRecording() {    let recorder = rpscreenrecorder.shared()    recorder.startRecording{ [uNowned self] (error) in        if let unwrappedError = error {            print(unwrappedError.localizedDescription)        } else {            self.vIDeoRecbutton.addTarget(self,action:#selector(self.stopRecording),for: .touchUpInsIDe)        }    }}func stopRecording() {    let recorder = rpscreenrecorder.shared()    recorder.stopRecording { [uNowned self] (prevIEw,error) in        self.navigationItem.rightbarbuttonItem = UIbarbuttonItem(Title: "Start",style: .plain,target: self,action: #selector(self.startRecording))        if let unwrappedPrevIEw = prevIEw {            unwrappedPrevIEw.prevIEwControllerDelegate = self            self.present(unwrappedPrevIEw,animated: true)        }    }}func prevIEwControllerDIDFinish(_ prevIEwController: RPPrevIEwVIEwController) {    dismiss(animated: true)}overrIDe var shouldautorotate: Bool {    return true}overrIDe var supportedInterfaceOrIEntations: UIInterfaceOrIEntationMask {    if UIDevice.current.userInterfaceIdiom == .phone {        return .allButUpsIDeDown    } else {        return .all    }}overrIDe func dIDReceiveMemoryWarning() {    super.dIDReceiveMemoryWarning()    // Release any cached data,images,etc that aren't in use.}overrIDe var prefeRSStatusbarHIDden: Bool {    return true}}

>如何从继承自SKScene的类(如GameScene类)调用startRecording和stopRecording函数?
>如何从GameScene类启用,禁用和隐藏vIDeoRecbutton按钮?

UPDATE

根据crashoverrIDe777的答案,我在SKScene类中放置了以下代码,但屏幕记录了导航控制器之前几秒钟,并显示录制视频的预览.录制的视频只是一个黑屏,取消和保存按钮没有响应.

func startRecording() {    let recorder = rpscreenrecorder.shared()    if #available(iOS 10.0,*) {        recorder.startRecording{ [uNowned self] (error) in            if let unwrappedError = error {                print(unwrappedError.localizedDescription)            } else {                self.stopRecording()            }        }    } else {        // Fallback on earlIEr versions    }}func stopRecording() {    let recorder = rpscreenrecorder.shared()    recorder.stopRecording { [uNowned self] (prevIEw,error) in        self.vIEw?.window?.rootVIEwController?.navigationItem.rightbarbuttonItem = UIbarbuttonItem(Title: "Start",action: #selector(self.startRecording))        if let unwrappedPrevIEw = prevIEw {            unwrappedPrevIEw.prevIEwControllerDelegate = self            self.vIEw?.window?.rootVIEwController?.present(unwrappedPrevIEw,animated: true)        }    }}func prevIEwControllerDIDFinish(_ prevIEwController: RPPrevIEwVIEwController) {    vIEw?.window?.rootVIEwController?.dismiss(animated: true)}

我创建了一个记录按钮:

let vIDeoRecbuttonSprite = SKSpriteNode(imagenamed: "vIDeobutton")vIDeoRecbuttonSprite.position = CGPoint(x: self.frame.wIDth/15,y: self.frame.height - self.frame.height/12)self.addChild(vIDeoRecbuttonSprite)overrIDe func touchesBegan(_ touches: Set<UItouch>,with event: UIEvent?) {    for touch: AnyObject in touches {        let location = touch.location(in: self)        if vIDeoRecbuttonSprite.contains(location){            startRecording()        }    }}
解决方法 你不应该在GameVIEwController中创建你的按钮,直接在你的SKScene中创建它.在SpriteKit游戏中使用GameVIEwController for UI并不是一个好习惯.

有很多关于如何在SpriteKit中创建按钮的教程.

关于ReplayKit,您可以直接在所需的SKScene中使用它,只需获取您已经拥有的代码并将其移动到相关场景.

要在SKScene中显示预览视图控制器,您可以这样说

vIEw?.window?.rootVIEwController?.present(unwrappedPrevIEw,animated: true)

我还注意到,在您停止录制后,您正在呈现VIEw控制器.你确定要这样做吗?通常,您在游戏菜单中有一个单独的按钮,您可以在其中观看录制内容.

这是一般代码.我还建议你查看苹果示例游戏DemoBots.

我个人使用Singleton类来管理录制,这样就更容易管理所有方法,因为你需要它来处理不同的场景.要启动类crate一个新的swift文件并添加此代码.

class ScreenRecoder: NSObject {      /// Shared instance      static let shared = ScreenRecorder()      /// PrevIEw controller      var prevIEwController: RPPrevIEwVIEwController?      /// Private singleton init      private overrIDe init() { } }

比开始录制将此方法添加到ScreenRecorder类.

func start() {    let sharedRecorder = rpscreenrecorder.shared()    // Do nothing if screen recording is not available    guard sharedRecorder.isAvailable else { return }    // Stop prevIoUs recording if necessary    if sharedRecorder.isRecording {        stopScreenRecording()    }    print("Starting screen recording")    // Register as the recorder's delegate to handle errors.    sharedRecorder.delegate = self    // Start recording    if #available(iOS 10.0,*) {        #if os(iOS)            sharedRecorder.isMicrophoneEnabled = true            //sharedRecorder.isCameraEnabled = true // fixme        #endif        sharedRecorder.startRecording { [uNowned self] error in            if let error = error as? NSError,error.code != RPRecordingErrorCode.userDeclined.rawValue {                print(error.localizedDescription)                // Show alert                return            }        }    } else {        // Fallback on earlIEr versions        sharedRecorder.startRecording(withMicrophoneEnabled: true) { error in            if let error = error as? NSError,error.code != RPRecordingErrorCode.userDeclined.rawValue {                print(error.localizedDescription)                // Show alert                return            }        }    }}

要停止录音,请拨打此电话您注意到我实际上还没有显示预览,我只是将其存储以供以后使用.这是你通常的做法.

func stop() {    let sharedRecorder = rpscreenrecorder.shared()    // Do nothing if screen recording is not available    guard sharedRecorder.isAvailable else { return }    // Stop recording    sharedRecorder.stopRecording { [uNowned self] (prevIEwVIEwController,error) in        if let error = error {            // If an error has occurred,display an alert to the user.            print(error.localizedDescription)            // Show alert            return        }        print("Stop screen recording")        if let prevIEwVIEwController = prevIEwVIEwController {            // Set delegate to handle vIEw controller dismissal.            prevIEwVIEwController.prevIEwControllerDelegate = self            /*             Keep a reference to the `prevIEwVIEwController` to             present when the user presses on prevIEw button.             */            self.prevIEwVIEwController = prevIEwVIEwController        }    }}

在ScreenRecorder类中创建符合ReplayKit委托的2个扩展.

预览控制器代表

/// RPPrevIEwVIEwControllerDelegate extension ScreenRecorder: RPPrevIEwVIEwControllerDelegate {     /// PrevIEw controller dID finish    func prevIEwControllerDIDFinish(_ prevIEwController: RPPrevIEwVIEwController) {          prevIEwController.dismiss(animated: true,completion: nil)    }}

和录音代表

extension ScreenRecorder: rpscreenrecorderDelegate {      /// Screen recoder dID stop with error      func screenRecorder(_ screenRecorder: rpscreenrecorder,dIDStopRecordingWithError error: Error,prevIEwVIEwController: RPPrevIEwVIEwController?) {         // display the error the user to alert them that the recording Failed.        let error = error as NSError        if error.code != RPRecordingErrorCode.userDeclined.rawValue {            print(message: error.localizedDescription)            // show alert        }         // Hold onto a reference of the `prevIEwVIEwController` if not nil.         if let prevIEwVIEwController = prevIEwVIEwController {             self.prevIEwVIEwController = prevIEwVIEwController              }      }      /// Screen recoder dID change availability      func screenRecorderDIDChangeAvailability(_ screenRecorder: rpscreenrecorder) {           // e.g update your button UI etc           // you can use something like delegation to pass something to your SKScenes     }}

最后创建一个方法来呈现预览.最好通过游戏菜单中的按钮来调用此功能.

func showPrevIEw() {    guard let prevIEwVIEwController = prevIEwVIEwController else { return }    print("Showing screen recording prevIEw")    // `RPPrevIEwVIEwController` only supports full screen modal presentation.    prevIEwVIEwController.modalPresentationStyle = .fullScreen    let rootVIEwController = UIApplication.shared.keyWindow?.rootVIEwController    rootVIEwController?.present(prevIEwVIEwController,animated: true,completion:nil)}

现在,您可以在项目中的任何位置调用方法

ScreenRecorder.shared.start()ScreenRecorder.shared.stop()ScreenRecorder.shared.showPrevIEw() // call stop before calling this

这段代码非常直接来自DemoBots.

我认为处理屏幕录制的最好方法是在主菜单中创建一个自动录制按钮.使用UserDefaults保存它的开/关状态.如果打开它,则在游戏开始时调用startRecording,并在游戏结束时调用停止录制.比您在游戏菜单中显示预览按钮,以便在用户想要的情况下观看录制.

希望这可以帮助

总结

以上是内存溢出为你收集整理的ios – 如何在SpriteKit SKScene类中启动ReplayKit屏幕录制全部内容,希望文章能够帮你解决ios – 如何在SpriteKit SKScene类中启动ReplayKit屏幕录制所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1070763.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存