iOS 9:ReplayKit简介

标签: 游戏  java  数据库  python  android

介绍

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

版权声明:本文为cunjie3951原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cunjie3951/article/details/106922604

智能推荐

剑指offer 合并两个排序的链表

题目 链接:https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/ 思路 我想的是,与合并两个有序数组一样的思维,新建一个链表,然后判断谁的值大,进而在新的链表上面进行插入。 看书思路 合并链表是一个递归问题:合并一个节点后可以转化为一个子问题。终止条件是其中一个链表为空 代码 链表反转也可以用递归解决...

Java编程思想 第三章:操作符

Java中的操作符和c/c++中的操作符基本一致,因为我之前学习过C语言和C++,所以本章的内容大部分都已熟知,下面只做简单的介绍。 Java操作符及优先级 Java中的操作符包括算术操作符,关系操作符,逻辑操作符,位运算符、自操作运算符、移位运算符、赋值运算符和其他运算符。 算术操作符:包括加减乘除和取余(%),优先级乘除取余高于加减,都是双元运算符,其中加法(+)可以用来连接两个字符串,比如:...

JetBrains 系列开发工具,如何配置 `SCSS` `File Watcher` ,相关输出配置参数详解:webStorm phpStorm IDEA

JetBrains 系列开发工具,如何配置 SCSS File Watcher ,相关输出配置参数详解:webStorm phpStorm IDEA 前言 你目前已经了解了如何使用 SCSS 进行开发,了解了该文章的内容:『 SCSS 日常用法 』 在 JetBrains 系列开发工具中通过 FileWatcher 进行编译的 SCSS 文件都是通过 sass 这个程序进行的。『 如何添加 Fil...

C语言小函数—二进制与十六进制

测试如下 “` int main() { long int num = 15; } “`...

仿微博或微信的文章多图显示(自定义MultiImageView)

按照一般的规矩,先上张图来供大伙看看 如果大致是大伙们需要实现的功能,不烦一观 自定义MultiImageView 工具类 具体使用 app.gradle中添加依赖 implementation 'com.github.bumptech.glide:glide:4.8.0' AndroidManifest.xml中配置联网权限 <uses-permission android:name=&q...

猜你喜欢

经典进程同步和互斥问题

经典进程同步与互斥问题 前言 一、生产者-消费者问题 1.问题描述 2.问题分析 3.代码 二、读者-写者问题 1.问题描述&&分析 2.代码 三、哲学家进餐问题 1.问题描述&&分析 2.代码 四、理发师问题 1.问题描述&&分析 2.代码 前言 在多道程序设计环境中,进程同步是一个非常重要的问题,下面讨论几个经典的进程同步问题。 一、生产者-消费...

java设计模式——ThreadLocal线程单例

1、定义一个ThreadLocal线程单例,代码如下: 2、定义一个多线程类,代码如下: 3、定义一个测试类,代码如下: 4、输出结果,如下图:...

【tensorflow】线性模型实战

线性模型:y = 1.477 * x + 0.089   1. 采样数据 采样噪声eps在均值0,方差0.01的高斯分布中,而后在均匀分布U(0,1)中,区间[-10,10]进行n=100次随机采样:   2. 计算误差 循环计算每个点的预测值与真是值之间差的平方并累加,从而获得训练集上的均芳误差损失值。   3. 计算梯度   4. 梯度更新 对权重w和偏...

常见损失函数和评价指标总结(附公式&代码)

网上看到一篇很实用的帖子关于常见损失函数和评价指标,收藏下来 本文转载于https://zhuanlan.zhihu.com/p/91511706 ------------------------------------------------------------------------------------------------------------------------------...

为什么 4G/5G 的直播延时依然很高

通信技术的发展促进了视频点播和直播业务的兴起,4G 和 5G 网络技术的进步也使得流媒体技术变得越来越重要,但是网络技术并不能解决流媒体直播的高延迟问题。 本文不会介绍网络对直播业务的影响,而是会分析直播中常见的现象 — 主播和观众之间能够感觉到的明显网络延迟。除了业务上要求的延迟直播之外,有哪些因素会导致视频直播的延迟这么高呢? live-streaming  图 1 - ...