ios平台有哪些游戏支持王者荣耀replaykitt的录屏功能

|||网络存储与CDN数据库安全监控与管理移动与通信视频服务域名服务大数据基础服务大数据可视化服务AI平台服务AI基础服务应用服务稳定安全,高易用可弹性伸缩的计算服务对多台服务器进行流量分发的负载均衡服务可靠、安全、易用的可扩展文件存储多节点全网覆盖、安全稳定的网络加速服务稳定托管的MySQL、SQLServer、MariaDB等关系型数据库兼容Redis和Memcached的分布式存储和缓存服务基于机器学习为用户提供入侵检测和漏洞预警服务4T超大带宽为网站用户抵御DDoS攻击防刷、消息过滤、文件检测全面保障业务安全立体化云产品数据监控,智能化数据分析服务防劫持、智能调度、稳定可靠的移动APP域名解析服务一站式媒体转码分发平台专业域名服务,安全、省心、可信赖域名安全解析备案邮箱可靠、安全、易用,可以按需部署的大数据处理服务实时交互、高效稳定、绚丽震撼的数据可视化解决方案对数据进行机器学习、挖掘和分析的算法平台高效图片处理、全面的图片鉴定和识别服务专业智能高效的语音处理服务提供丰富API的开放语义分析平台基于海量用户画像+实时大数据机器学习的个性化推荐服务
游戏录屏(ReplayKit)
游戏录屏(ReplayKit)
概述录屏功能是iOS 10新推出的特性,苹果在 iOS 9 的 ReplayKit 保存录屏视频的基础上,增加了视频流实时直播功能,官方介绍见 。
录屏的整个流程分为游戏App和直播App两个部分。iOS录屏时并没有让直播App直接运行,而是以扩展程序的形式为游戏App服务。扩展程序也分为两个,一个是用于显示自定义界面,这个界面可以让用户输入标题、显示用户信息等,用户点击确定后转到另一个扩展程序中发送屏幕数据,这个扩展并没有显示UI的能力。整个录屏直播的结构如下图所示。
Broadcast Upload作为一个扩展程序,有单独的进程。iOS系统为了保证系统流畅,给扩展程序的资源相对较少,扩展程序内存占用过大也会被Kill掉。腾讯云RTMP SDK在原有直播的高质量、低延迟的基础上,进一步降低系统消耗,保证了扩展程序稳定。
功能体验由于录屏功能需要游戏和直播软件都支持,才能完成录制的流程。直播软件推荐使用我们的“小直播”,下载地址
随着iOS 10普及,支持录屏的游戏也在普及。如果您没有可录屏的游戏,可下载“坦克之战”这款游戏,点击上方的直播,选择小直播即可开始录屏。
开发环境准备Xcode 准备录屏直播是iOS 10提供的新特性,所以需要Xcode 8及以上的版本,手机也必须升级至iOS 10以上,模拟器无法使用录屏特性。
创建直播扩展在现有工程选择“New”-&&Target…&,选择“Broadcast Upload Extension&,如图所示
配置好Product Name,注意勾选&Include UI Extension&。点“Finish“后可以看到,工程多了两个目录,并且target也多了两个,分别是直播扩展和UI扩展。
iOS 10的Replay Kit支持两种直播方式
将视频和音频编码为一小段mp4文件,交给直播扩展
将屏幕和声音的原始数据交给扩展
方式1延迟高,不灵活,优点是扩展app无须关心编码问题;方式2可以自定义发送的内容,可配置性高。目前SDK仅支持第二种方式。由于Xcode默认使用了方式1,因此需要修改直播扩展Info.plist到如图所示
导入RTMP SDK直播扩展需要导入TXRTMPSDK.framework。扩展导入framework的方式和主App导入方式相同,SDK的系统依赖库也没有区别,具体可参考腾讯云官网《》。
对接流程Step 1: 编写UI扩展游戏App发起直播,首先进入的是UI扩展。这里可以根据您产品需要订制界面。如果您的直播软件需要登录,最好在这里先检查登录态,因为在直播过程中不能显示任何界面。
当用户确认发起直播,UI扩展就可以把启动直播扩展,而且可以带上一些自定义的参数。启动直播扩展示例代码如下
- (void)userDidFinishSetup {
NSURL *broadcastURL = [NSURL URLWithString:@"http://broadcastURL_example/stream1"];
NSString *userID = @"user1";
NSString *endpointURL = @"rtmp://2157./live/xxxxxx";
NSDictionary *setupInfo = @{ @"userID" : userID, @"endpointURL" : endpointURL };
RPBroadcastConfiguration *broadcastConfig = [[RPBroadcastConfiguration alloc] init];
broadcastConfig.clipDuration = 5.0;
[self.extensionContext completeRequestWithBroadcastURL:broadcastURL
broadcastConfiguration:broadcastConfig setupInfo:setupInfo];
Step 2: 创建推流对象工程模版已经为我们创建好直播扩展的基本框架。只需要在SampleHandler.m前添加下面代码
#import "SampleHandler.h"
#import "TXRTMPSDK/TXLiveSDKTypeDef.h"
#import "TXRTMPSDK/TXLivePush.h"
#import "TXRTMPSDK/TXLiveBase.h"
static TXLivePush *s_txLiveP
s_txLivePublisher是我们用于推流的对象。实例化s_txLivePublisher的最佳位置是在-[SampleHandler broadcastStartedWithSetupInfo:]方法中,UI扩展启动推流后会回调这个函数开始直播。
- (void)broadcastStartedWithSetupInfo:(NSDictionary&NSString *,NSObject *& *)setupInfo {
if (s_txLivePublisher) {
[s_txLivePublisher stopPush];
TXLivePushConfig* config = [[TXLivePushConfig alloc] init];
config.customModeType |= CUSTOM_MODE_VIDEO_CAPTURE;
config.autoSampleBufferSize = YES;
config.customModeType |= CUSTOM_MODE_AUDIO_CAPTURE;
config.audioSampleRate = 44100;
config.audioChannels
s_txLivePublisher = [[TXLivePush alloc] initWithConfig:config];
NSString *pushUrl = setupInfo[@"endpointURL"];
[s_txLivePublisher startPush:pushUrl];
s_txLivePublisher的config不能使用默认的配置,需要设置自定义采集视频和音频。关于自定义采集的设置的原理和工作方式,参见腾讯云文档《》。
视频启用autoSampleBufferSize,开启此选项后,您不需要关心推流的分辨率,SDK会自动根据输入的分辨率设置编码器;如果您关闭此选项,那么代表您需要自定义分辨率
推荐开启autoSampleBufferSize,这样可以得到最佳性能。同时,您也不必关心横屏或竖屏
Step 3: 自定义分辨率如果您需不想用屏幕输出的分辨率,也可以指定任意一个分辨率,SDK内部将根据您指定的分辨率进行缩放
config.autoSampleBufferSize = NO;
config.sampleBufferSize = CGSizeMake(640, 360);
Step 4: 发送视频Replay Kit会将音频和视频都以回调的方式传给-[SampleHandler processSampleBuffer:withType]
- (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType {
switch (sampleBufferType) {
case RPSampleBufferTypeVideo:
[s_txLivePublisher sendVideoSampleBuffer:sampleBuffer];
视频sampleBuffer只需要调用-[TXLivePush sendVideoSampleBuffer:]发送即可。
系统分发视频sampleBuffer的频率并不固定,如果画面静止,可能很长时间才会有一帧数据过来。SDK考虑到这种情况,内部会做补帧逻辑,使其达到config所设置的帧率(默认为20fps)。
Step 5: 发送音频音频也是通过-[SampleHandler processSampleBuffer:withType]给到直播扩展,区别在于音频有两路数据:一路来自App内部,一路来自麦克风。
switch (sampleBufferType) {
case RPSampleBufferTypeAudioApp:
case RPSampleBufferTypeAudioMic:
[s_txLivePublisher sendAudioSampleBuffer:sampleBuffer];
SDK不支持同时发送两路数据,您需要跟进情况自己选择使用那一份音频。
Step 6: 暂停与恢复游戏App可以暂停当前直播,此时Samples buffer不再分发到直播扩展,直到用户恢复直播。在自定义采集模式下,SDK需要外部持续提供数据源,否则服务器会因长时间得不到数据而断开直播。
SDK内部对视频有补帧逻辑,没有视频时会重发最后一帧数据,而音频没有补帧逻辑,不向SDK提供数据会导致音画不同步的现象发生。您可以用下面的简单代码,在暂停时向SDK发送静音数据。
static dispatch_source_t s_audioT
- (void)pause {
if (s_audioTimer) {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
s_audioTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(s_audioTimer,DISPATCH_TIME_NOW,20*NSEC_PER_MSEC, 0);
dispatch_source_set_event_handler(s_audioTimer, ^{
static uint8_t _audioData[2048] = {0};
[s_txLivePublisher sendCustomPCMData:_audioData len:sizeof(_audioData)];
dispatch_resume(s_audioTimer);
- (void)resume {
if (s_audioTimer) {
dispatch_cancel(s_audioTimer);
s_audioTimer = 0;
- (void)broadcastPaused {
[self pause];
- (void)broadcastResumed {
[self resume];
Step 7: SDK事件处理事件监听SDK事件监听需要设置TXLivePush的delegate属性,该delegate遵循TXLivePushListener协议。底层的事件会通过-(void) onPushEvent:(int)EvtID withParam:(NSDictionary*)param接口回调过来。
直播扩展由于系统限制,不能触发界面动作,因此也不能主动通知用户推流异常。录屏过程中,一般会收到以下事件。
PUSH_EVT_CONNECT_SUCC
已经成功连接到腾讯云推流服务器
PUSH_EVT_PUSH_BEGIN
与服务器握手完毕,一切正常,准备开始推流
常规事件通常无须处理。
PUSH_ERR_VIDEO_ENCODE_FAIL
视频编码失败
PUSH_ERR_AUDIO_ENCODE_FAIL
音频编码失败
PUSH_ERR_UNSUPPORTED_RESOLUTION
不支持的视频分辨率
PUSH_ERR_UNSUPPORTED_SAMPLERATE
不支持的音频采样率
PUSH_ERR_NET_DISCONNECT
网络断连,且经三次抢救无效,可以放弃治疗,更多重试请自行重启推流
视频编码失败并不会直接影响推流,SDK会做处理以保证后面的视频编码成功。
PUSH_WARNING_NET_BUSY
网络状况不佳:上行带宽太小,上传数据受阻
PUSH_WARNING_RECONNECT
网络断连, 已启动自动重连 (自动重连连续失败超过三次会放弃)
PUSH_WARNING_HW_ACCELERATION_FAIL
硬编码启动失败,采用软编码
PUSH_WARNING_DNS_FAIL
RTMP -DNS解析失败(会触发重试流程)
PUSH_WARNING_SEVER_CONN_FAIL
RTMP服务器连接失败(会触发重试流程)
PUSH_WARNING_SHAKE_FAIL
RTMP服务器握手失败(会触发重试流程)
PUSH_WARNING_SERVER_DISCONNECT
RTMP服务器主动断开连接(会触发重试流程)
警告事件表示内部遇到了一些问题,但并不影响推流。
全部事件定义请参阅头文件“TXLiveSDKEventDef.h”
Step 8: 结束推流结束推流Replay Kit会调用-[SampleHandler broadcastFinished],示例代码
- (void)broadcastFinished {
if (s_txLivePublisher) {
[s_txLivePublisher stopPush];
s_txLivePublisher = nil;
结束推流后,直播扩展进程可能会被系统回收,所以务必在此做好清理工作。
以上信息是否解决您的问题?
提交成功!非常感谢您的反馈,我们会继续努力做到更好!
为了我们更有效的优化资料库,以及针对性的改善我们的服务,我们很需要您进一步的反馈信息:
页面内容不全面,不深入
页面内容更新不及时
描述不够清晰,比较混乱
系统或功能太复杂,同时文档也缺乏足够的引导
移动直播相关文档
Copyright &
腾讯云版权所有iOS9正式版发布 7款完美支持iOS9的手游推荐
[摘要]新系统中关于游戏的新功能就是ReplayKit了,这个新功能支持游戏录屏和回放。小编就为大家分享一下最新的6款完美支持iOS9游戏推荐,一起来看看吧!经过了近三个月的等待,苹果iOS9正式版终于发布了。新系统中关于游戏的新功能就是ReplayKit了,这个新功能支持游戏录屏和回放。通过ReplayKit进行游戏操作录制的过程中,系统会自动暂停所有的通知提醒信息,以避免视频中断。接下来小编就为大家分享一下最新的7款完美支持iOS9游戏推荐,一起来看看吧!▍《二重奏》在App Store中的iOS9游戏推荐中下载了《二重奏》(Duet Game)这款游戏。进入游戏之后,并没有默认弹出任何有关ReplayKit的提示,用户在游戏进程中点击屏幕右上方的回放图标时才会弹出“录制视频和麦克风声音”“仅录屏”以及“不允许”三个选项。在选择录制之后,右上角的回放图标上标记出一个红点,表示正在录制。当用户想要结束录制时再点击一下图标可以查看视频回放,从而选择储存、分享或是放弃。录制的视频可以通过“照片”应用查看,或是通过其他应用分享。苹果希望通过这一特性的加入来增强游戏的社交性,让用户可以有更多的选择与朋友分享历,同时对于目前正在涌现的电竞,电竞直播等网络内容的发展也是一种推动。但目前这一功能过于简单,还无法实现如Everyplay的SDK中的社区功能。▍《摩托赛道CC》iOS9游戏推荐的《摩托赛道CC Raceline CC》是一款赛车竞速类,该作是由开发商Rebellion Games推出的一款摩托竞速大作。游戏名称也可以看出该游戏是以摩托车为主题,采用了第一人称试视角,画面非常逼真绚烂。游戏中玩家还需要控制自己的摩托车,在各种赛道上打败对手即可,听起来是不是很刺激呢,感兴趣的小伙伴们快来加入吧!游戏运用了苹果的Metal技术,在画面上不输给主流的赛车类竞速大作,比如《狂野飙车》系列、《真实赛车3》等大作。而作为为数不多的摩托竞速游戏,媲美主机的游戏画面、真实比例的赛车模型、逼真绚烂的城市夜景都令人心驰神往。操作方面也尽量简化,采用一键触摸操控模式,但依旧可以轻松作出漂移、加速、转弯等灵活流畅的动作。此外,游戏还拥有冠军杯赛、每日任务和BOSS比赛等多种玩法,当然作为赛车游戏自然少不了赛车升级等个性自定义选项,玩家可以用比赛赢取的奖金来升级发动机、变速箱、刹车等部件,个性机车近在咫尺。▍《极速飞行》由游戏厂商PikPok制作的一款竞速跑酷游戏Breakneck《极速飞行》已于今日正式上架App Store。本作以世界末日为大背景,整个世界都被外星人占领,玩家所扮演的主角将驾驶一艘高速行驶的飞行器,躲避外星人的追捕。这将是一场生死攸关的夺命大逃亡。PikPok称,游戏能满足玩家的“疯狂之梦”,玩家将陷入一场又一场超速狂飙且无止境的竞速比赛中。而你不仅要躲避沿途出现的各种障碍物,包括追捕你的外星人,还要收集至关重要的资源。iOS9游戏推荐的这款游戏目标就是要在各种不同的环境中尽可能寻找到获得高分的最佳路线,而这个世界每天都在重置变换中,所以你必须抓紧时间。游戏内还设置了每日任务和每周任务来考验你的能力,有常规赛和排行榜等。▍《冠军召唤》游戏最大的特点就是以10分钟左右的快节奏战斗来定胜负,但如此快节奏的战斗却丝毫没有影响游戏整体的可玩性。早在测试上架期间更是获得众多外媒的一致赞誉,或许是近期内能够与《虚荣》(Vainglory)媲美的好作品。冠军召唤iOS无论是在画面还是在英雄人设上都表现的可圈可点,当然玩法依旧遵循传统的3V3对战方式,比赛节奏较快,通常10分钟就可决定胜负。玩家也将能够连接到世界服务器上,与来自全世界的高手们逐一过招,并最终确立谁才是真正的MOBA王者!另外,游戏适配从iPhone 3GS到iPhone 6s Plus的各种机型,但根据MOBA游戏的特性,想必在平板上的体验会更好。另外游戏内目前暂不支持中文,且要求iOS 8.0或更高的版本。▍《热血街区》这款iOS9游戏推荐的游戏画面类似于模拟城市,也同样都是以上帝视角来建设领地,不同的是这款游戏的玩法并不是模拟经营,而是有些像塔防的攻防模式,我们通过建造一些工事来保卫,并且袭击其他帮派的街区。作为一款3D游戏,《热血街区》的人设以及动作都带有浓重的西方特色,对帮派人士的刻画也十分生动,能让玩家找到黑道的感觉。在你刚加入家族时,你的领地还只是小小的一片,而当你通过火并不断提升影响力后,身为大哥你的领土可不能太寒酸。在你最初的领地周围会有一些还未被占领的售卖中的土地,通过购买可以将这些区域划入你的领地,而家族将会为你支付第一笔扩张费用,当做是是对你的认可以及信任,在你有了一定收入后可以继续扩张领地,成为独占街区的名人。随着游戏的不断换代,越来越多的玩家觉得交互才是游戏最重要的体验,而社区游戏恰恰是以强大的交互功能为卖点。▍《随风飞行》纸飞机是可以和滚铁环、丢四角、火药枪并列的80后儿时必玩游戏,所以iOS9游戏推荐的《随风飞行》(Air Wings)应该是一部相当有“情怀”的游戏,因为它满足了我们孩提时代都曾经有过的幻想:对着机头哈完气,然后将纸飞机掷出之后,希望它们不仅仅只会做出抛物线式的落体运动,而是能够像真的飞机那样战斗,在空中大战一场!主要的动作按键为射击和加速,射击所使用到的弹药有限的,用完之后就要去场景中的补给点进行补充。加速功能虽然很容易由于转弯不足而导致撞(直接撞上障碍物的下场就是Game Over),但它在缠斗中可是不可或缺的一项功能。本作对A7处理器进行特别优化,场景配色非常鲜艳,画面流畅,上手度高,很快就会让人有爱不释手之感。▍《乡村生活》iOS9游戏推荐的《乡村生活:爱》英文名称为Village Life:Love, Marriage and Babies,是iOS平台上的一款模拟经营类游戏,玩家在游戏中要做的就是创建一个欣欣向荣的乌托邦式的乡村,通过不断的经营让我们的每个村民的需求都得到满足。在游戏中我们可以帮助村民收获食物和资源来制作各种工具、玩具和建筑物,然后指导村民完成从出生到第一次约会、结婚、生育等年龄段的生活所需,喜欢模拟经营类游戏的玩家可以下载体验一下。关于IOS9游戏推荐的全部内容就是这些了,由于目前iOS9才刚刚发布。因此能够完美支持的游戏并不多,不过相信各大游戏厂商在接下来的几天都会推出关于新系统的更新,作为玩家的我们可以继续关注哦!
正文已结束,您可以按alt+4进行评论
相关阅读:
相关搜索:
[责任编辑:jojozhu]
热门搜索:
Copyright & 1998 - 2017 Tencent. All Rights Reserved【代码片-1】 IOS Replaykit 手游录屏Demo
标签: ios&&&&视频&&&&游戏&&&&苹果&&&&相册&&&&
#import &ViewController.h&
#import &ReplayKit/ReplayKit.h&
static NSString *StartRecord = @&开始&;
static NSString *StopRecord = @&结束&;
#if TARGET_IPHONE_SIMULATOR
#define SIMULATOR 1
#elif TARGET_OS_IPHONE
#define SIMULATOR 0
#define AnimationDuration (0.3)
@interface ViewController () &RPPreviewViewControllerDelegate&
@property (nonatomic, strong)UIButton *btnS
@property (nonatomic, strong)UIButton *btnS
@property (nonatomic, strong)NSTimer *progressT
@property (nonatomic, strong)UIProgressView *progressV
@property (nonatomic, strong)UIActivityIndicatorView *
@property (nonatomic, strong)UIView *tipV
@property (nonatomic, strong)UILabel *lbT
@property (nonatomic, strong)UILabel *lbT
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
- (void)viewDidAppear:(BOOL)animated {
BOOL isVersionOk = [self isSystemVersionOk];
if (!isVersionOk) {
NSLog(@&系统版本需要是iOS9.0及以上才支持ReplayKit&);
if (SIMULATOR) {
[self showSimulatorWarning];
UILabel *lb =
CGSize screenSize = [UIScreen mainScreen].bounds.
lb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 140)];
lb.font = [UIFont boldSystemFontOfSize:32];
lb.backgroundColor = [UIColor clearColor];
lb.textColor = [UIColor blackColor];
lb.textAlignment = NSTextAlignmentC
lb.numberOfLines = 3;
lb.text = @&苹果ReplayKit Demo&;
lb.center =
CGPointMake(screenSize.width/2, 80);
[self.view addSubview:lb];
//创建按钮
UIButton *btn = [self createButtonWithTitle:StartRecord andCenter:CGPointMake(screenSize.width/2 - 100, 200)];
[self.view addSubview:btn];
self.btnStart =
btn = [self createButtonWithTitle:StopRecord andCenter:CGPointMake(screenSize.width/2 + 100, 200)];
[self.view addSubview:btn];
self.btnStop =
[self setButton:btn enabled:NO];
//loading指示
UIActivityIndicatorView *activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 280, 80)];
[self.view addSubview:view];
view.backgroundColor = [UIColor redColor];
view.layer.cornerRadius = 8.0f;
view.center = CGPointMake(screenSize.width/2, 300);
activity.center = CGPointMake(30, view.frame.size.height/2);
[view addSubview:activity];
[activity startAnimating];
self.activity =
lb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 280, 80)];
lb.font = [UIFont boldSystemFontOfSize:20];
lb.backgroundColor = [UIColor clearColor];
lb.textColor = [UIColor blackColor];
lb.layer.cornerRadius = 4.0;
lb.textAlignment = NSTextAlignmentC
[view addSubview:lb];
self.lbTip =
self.tipView =
[self hideTip];
//显示时间(用于看录制结果时能知道时间)
lb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
lb.font = [UIFont boldSystemFontOfSize:20];
lb.backgroundColor = [UIColor redColor];
lb.textColor = [UIColor blackColor];
lb.layer.cornerRadius = 4.0;
NSDateFormatter * dateFormat = [[NSDateFormatter alloc] init] ;
[dateFormat setDateFormat: @&HH:mm:ss&];
NSString *dateString = [dateFormat stringFromDate:[NSDate date]];
lb.center = CGPointMake(screenSize.width/2, screenSize.height/2 + 100);
lb.textAlignment = NSTextAlignmentC
[self.view addSubview:lb];
self.lbTime =
//进度条 (显示动画,不然看不出画面的变化)
UIProgressView *progress = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, screenSize.width*0.8, 10)];
progress.center = CGPointMake(screenSize.width/2, screenSize.height/2 + 150);
progress.progressViewStyle = UIProgressViewStyleD
progress.progress = 0.0;
[self.view addSubview:progress];
self.progressView =
//更新时间
[NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(updateTimeString)
userInfo:nil
repeats:YES];
#pragma mark - UI控件
//显示 提示信息
- (void)showTipWithText:(NSString *)tip activity:(BOOL)activity{
[self.activity startAnimating];
self.lbTip.text =
self.tipView.hidden = NO;
if (activity) {
self.activity.hidden = NO;
[self.activity startAnimating];
[self.activity stopAnimating];
self.activity.hidden = YES;
//隐藏 提示信息
- (void)hideTip {
self.tipView.hidden = YES;
[self.activity stopAnimating];
//创建按钮
- (UIButton *)createButtonWithTitle:(NSString *)title andCenter:(CGPoint)center {
CGRect rect = CGRectMake(0, 0, 160, 60);
UIButton *btn = [[UIButton alloc] initWithFrame:rect];
btn.layer.cornerRadius = 5.0;
btn.layer.borderWidth = 2.0;
btn.layer.borderColor = [[UIColor blackColor] CGColor];
btn.backgroundColor = [UIColor lightGrayColor];
btn.center =
[btn setTitle:title forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(onBtnPressed:) forControlEvents:UIControlEventTouchDown];
//设置按钮是否可点击
- (void)setButton:(UIButton *)button enabled:(BOOL)enabled {
if (enabled) {
button.alpha = 1.0;
button.alpha = 0.2;
button.enabled =
//提示不支持模拟器
- (void)showSimulatorWarning {
UIAlertAction *actionOK = [UIAlertAction actionWithTitle:@&好的& style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
UIAlertAction *actionCancel = [UIAlertAction actionWithTitle:@&取消& style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@&ReplayKit不支持模拟器& message:@&请使用真机运行这个Demo工程& preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:actionCancel];
[alert addAction:actionOK];
[self presentViewController:alert animated:NO completion:nil];
//显示弹框提示
- (void)showAlert:(NSString *)title andMessage:(NSString *)message {
if (!title) {
title = @&&;
if (!message) {
message = @&&;
UIAlertAction *actionCancel = [UIAlertAction actionWithTitle:@&好的& style:UIAlertActionStyleCancel handler:nil];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:actionCancel];
[self presentViewController:alert animated:NO completion:nil];
//显示视频预览页面,animation=是否要动画显示
- (void)showVideoPreviewController:(RPPreviewViewController *)previewController withAnimation:(BOOL)animation {
__weak ViewController *weakSelf =
//UI需要放到主线程
dispatch_async(dispatch_get_main_queue(), ^{
CGRect rect = [UIScreen mainScreen].
if (animation) {
rect.origin.x += rect.size.
previewController.view.frame =
rect.origin.x -= rect.size.
[UIView animateWithDuration:AnimationDuration animations:^(){
previewController.view.frame =
} completion:^(BOOL finished){
previewController.view.frame =
[weakSelf.view addSubview:previewController.view];
[weakSelf addChildViewController:previewController];
//关闭视频预览页面,animation=是否要动画显示
- (void)hideVideoPreviewController:(RPPreviewViewController *)previewController withAnimation:(BOOL)animation {
//UI需要放到主线程
dispatch_async(dispatch_get_main_queue(), ^{
CGRect rect = previewController.view.
if (animation) {
rect.origin.x += rect.size.
[UIView animateWithDuration:AnimationDuration animations:^(){
previewController.view.frame =
} completion:^(BOOL finished){
//移除页面
[previewController.view removeFromSuperview];
[previewController removeFromParentViewController];
//移除页面
[previewController.view removeFromSuperview];
[previewController removeFromParentViewController];
#pragma mark - 按钮 回调
//按钮事件
- (void)onBtnPressed:(UIButton *)sender {
//点击效果
sender.transform = CGAffineTransformMakeScale(0.8, 0.8);
float duration = 0.3;
[UIView animateWithDuration:duration
animations:^{
sender.transform = CGAffineTransformMakeScale(1.1, 1.1);
}completion:^(BOOL finish){
[UIView animateWithDuration:duration
animations:^{
sender.transform = CGAffineTransformMakeScale(1.0, 1.0);
}completion:^(BOOL finish){ }];
NSString *function = sender.titleLabel.
if ([function isEqualToString:StartRecord]) {
[self startRecord];
else if ([function isEqualToString:StopRecord]) {
[self stopRecord];
- (void)startRecord {
[self setButton:self.btnStart enabled:NO];
NSLog(@&ReplayKit只支持真机录屏,支持游戏录屏,不支持录avplayer播放的视频&);
NSLog(@&检查机器和版本是否支持ReplayKit录制...&);
if ([[RPScreenRecorder sharedRecorder] isAvailable]) {
NSLog(@&支持ReplayKit录制&);
NSLog(@&!!不支持支持ReplayKit录制!!&);
__weak ViewController *weakSelf =
NSLog(@&%@ 录制&, StartRecord);
[self showTipWithText:@&录制初始化& activity:YES];
//在此可以设置是否允许麦克风(传YES即是使用麦克风,传NO则不是用麦克风)
[[RPScreenRecorder sharedRecorder] startRecordingWithMicrophoneEnabled:NO handler:^(NSError *error){
NSLog(@&录制开始...&);
[weakSelf hideTip];
if (error) {
NSLog(@&错误信息 %@&, error);
[weakSelf showTipWithText:error.description activity:NO];
//其他处理
[weakSelf setButton:self.btnStop enabled:YES];
[weakSelf setButton:self.btnStart enabled:NO];
[weakSelf showTipWithText:@&正在录制& activity:NO];
//更新进度条
weakSelf.progressTimer = [NSTimer scheduledTimerWithTimeInterval:0.05f
target:self
selector:@selector(changeProgressValue)
userInfo:nil
repeats:YES];
- (void)stopRecord {
NSLog(@&%@ 录制&, StopRecord);
[self setButton:self.btnStart enabled:YES];
[self setButton:self.btnStop enabled:NO];
__weak ViewController *weakSelf =
[[RPScreenRecorder sharedRecorder] stopRecordingWithHandler:^(RPPreviewViewController *previewViewController, NSError *
if (error) {
NSLog(@&失败消息:%@&, error);
[weakSelf showTipWithText:error.description activity:NO];
[weakSelf showTipWithText:@&录制完成& activity:NO];
//显示录制到的视频的预览页
NSLog(@&显示预览页面&);
previewViewController.previewControllerDelegate = weakS
//去除计时器
[weakSelf.progressTimer invalidate];
weakSelf.progressTimer =
[self showVideoPreviewController:previewViewController withAnimation:YES];
#pragma mark - 视频预览页面 回调
//关闭的回调
- (void)previewControllerDidFinish:(RPPreviewViewController *)previewController {
[self hideVideoPreviewController:previewController withAnimation:YES];
//选择了某些功能的回调(如分享和保存)
- (void)previewController:(RPPreviewViewController *)previewController didFinishWithActivityTypes:(NSSet &NSString *& *)activityTypes {
__weak ViewController *weakSelf =
if ([activityTypes containsObject:@&com.apple.UIKit.activity.SaveToCameraRoll&]) {
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf showAlert:@&保存成功& andMessage:@&已经保存到系统相册&];
if ([activityTypes containsObject:@&com.apple.UIKit.activity.CopyToPasteboard&]) {
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf showAlert:@&复制成功& andMessage:@&已经复制到粘贴板&];
#pragma mark - 计时器 回调
//改变进度条的显示的进度
- (void)changeProgressValue {
float progress = self.progressView.progress + 0.01;
[self.progressView setProgress:progress animated:NO];
if (progress &= 1.0) {
self.progressView.progress = 0.0;
//更新显示的时间
- (void)updateTimeString {
NSDateFormatter * dateFormat = [[NSDateFormatter alloc] init] ;
[dateFormat setDateFormat: @&HH:mm:ss&];
NSString *dateString = [dateFormat stringFromDate:[NSDate date]];
self.lbTime.text =
#pragma mark - 其他
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
//判断对应系统版本是否支持ReplayKit
- (BOOL)isSystemVersionOk {
if ([[UIDevice currentDevice].systemVersion floatValue] & 9.0) {
return NO;
return YES;
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?

我要回帖

更多关于 王者荣耀的replaykit 的文章

 

随机推荐