直播近两年持续升温,今年已经达到了一个很是火爆的状态,尤其是游戏加入直播以后,更是火爆非常,一款好的游戏加上直播功能后可以更加的火爆,当然很多都是和平台签约的形式。

ios从9.0开始就已经在支持直播上面做出了很多的开放,ReplayKit的诞生使得ios的录制和播放还有分享等成为了可能,而ReplayKit Live的出现使得平民也可以使用该功能去支持该技术的平台上面开启直播,只需要你在平台上的账户拥有直播权限。下面让我们看看新的freamwork的表述:



WWDC 2016

下面是观看WWDC16 记录的知识片段。

ReplayKit

新特性:

  • Apple TV support
  • Live Broadcasting 直播广播,这个很有用,就是要研究的直播功能
  • 可以记录 Face Time摄像头的内容,增强了麦克风记录API

官方的简介图:


ios开始直播感知_ios开始直播感知




从图中我们可以看到使用新的live技术非常简单,只需要添加一个RPScreenRecorder和一个RPPreviewViewController,当然相关的delegate不能少


First:先看看新live技术的使用步骤:


1.为自己的游戏工程添加ReplayKit.frameword


2.配置使用照相机和麦克风的权限


3.添加一个接口来实现弹出广播的列表


-(void) startBroadcast
{
    [RPBroadcastActivityViewController loadBroadcastActivityViewControllerWithHandler:^(RPBroadcastActivityViewController * _Nullable broadcastActivityViewController, NSError * _Nullable error) {
        
        NSLog(@"====>>show boradcast view");
        self.broadcastAVC = broadcastActivityViewController;
        self.broadcastAVC.delegate = self;
        //broadcastActivityViewController.delegate = self;
        UIViewController * con = [UIApplication sharedApplication].keyWindow.rootViewController;
        //ipad需要对view进行一些修改,不然可能出现nil的bug
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
        {
            self.broadcastAVC.modalPresentationStyle = UIModalPresentationCurrentContext;
            self.broadcastAVC.popoverPresentationController.sourceView = con.view;
        }
//这里将弹出广播列表的代码放在主进程里面执行以避免界面不展示的情况(或者被其他界面遮挡的情况)
        dispatch_after(0.2, dispatch_get_main_queue(), ^{
            [con presentViewController:self.broadcastAVC animated:YES completion:^{            
                NSLog(@"====>>show boradcast view end ");
            }];
        });     
    }];
}


这里是博主测试是出现的情况图片:


ios开始直播感知_ios_02


情况是调用接口的时候,博主的pad上面并没有安装支持该技术的直播app,弹出了提示去app Store找一个app。


在安装之后就会弹出选择框,供你选择app拉起直播app的登录或者直播界面


Second: 看看以前的录播功能


录播功能主要是录制游戏并保存到相册或者分享出去,具体看代码:建议将直播和录播封装到一个模块中去,方便管理和修改


1.看看h文件


//
//  BQPReplaykit.h
//
//  Created by lining on 17/01/09.
//  Copyright © 2017年 lining. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <ReplayKit/ReplayKit.h>

@interface BQPReplaykit:UIViewController<RPScreenRecorderDelegate,RPPreviewViewControllerDelegate,RPBroadcastActivityViewControllerDelegate>

+ (BQPReplaykit*) sharedInstance;

+ (BOOL) isSupportReplay;

-(void) startRecoder;

-(void) stopRecoder;

-(void) discardRecoder;

-(void) displayRecoder;

-(void) startBroadcast;

@end


很简单就是说明开放的接口和实现功能的viewController和delegate,注意一个shareInstance,这个是为封装准备的OC标准的调用方式GET下,以后就这么封装了


2.看看m文件,有必要的都会在代码中注释


//
//  BQPReplaykit.m
//
//  Created by lining on 17/01/09.
//  Copyright 漏 2017骞?lining. All rights reserved.
//


#import "BQPReplaykit.h"

@interface BQPReplaykit()

@property RPBroadcastActivityViewController *broadcastAVC;
@property RPBroadcastController *broadcastController;
@property RPPreviewViewController *previewController;

@end

@implementation BQPReplaykit

bool isStart = false;
RPScreenRecorder* recoder;

+ (BQPReplaykit*) sharedInstance
{
    static BQPReplaykit* _instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[BQPReplaykit alloc] init];
    });
    return _instance;
}

+ (BOOL) isSupportReplay
{
    return [RPScreenRecorder sharedRecorder].available;
}

-(void) startRecoder
{
    recoder = [RPScreenRecorder sharedRecorder];
    if( !recoder.available ) //not support
    {
        NSLog(@"ReplayKit is not available");
        return;
    }
    
    if( recoder.recording) // starting recoder
    {
        NSLog(@"ReplayKit is recording");
        return;
    }
    
    recoder.delegate = self;
    [recoder startRecordingWithMicrophoneEnabled:YES handler:^(NSError * _Nullable error) {
        if(error)
        {
            NSLog(@"Start recoder error: %@",error.localizedDescription);
        }
    }];
}


-(void) stopRecoder
{
    recoder = [RPScreenRecorder sharedRecorder];
    
    if( !recoder.recording) //not start recording
    {
        return;
    }
    
    [recoder stopRecordingWithHandler:^(RPPreviewViewController * _Nullable previewViewController, NSError * _Nullable error) {
        if(error)
        {
            NSLog(@"Stop recording error: %@",error.localizedDescription);
            return;
        }
        else
        {
            if(previewViewController != nil)
            {
                previewViewController.previewControllerDelegate = self;
                self.previewController = previewViewController;
                [self startBroadcast];
            }
        }
    }];
    
}
//注意清空录制,必须在stop之后调用,并且只能清空本次的录制内容
-(void) discardRecoder
{
    recoder = [RPScreenRecorder sharedRecorder];
    
    if( recoder.recording ) // recording
    {
        return;
    }
    
    [recoder discardRecordingWithHandler:^{
        NSLog(@"discard Recording complete");
        self.previewController = NULL;
    }];
}
//预览接口,放在stop里面调用是最好的效果,如果游戏想要自己定制预览界面,就自己封装一个保存录制内容在相册的接口,然后从相册里面预览视屏放到自定义的界面展示即可
-(void) displayRecoder
{
    if(self.previewController != nil);
    {
        UIViewController * con = [UIApplication sharedApplication].keyWindow.rootViewController;

        if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
        {
            self.previewController.modalPresentationStyle = UIModalPresentationCurrentContext;
            self.previewController.popoverPresentationController.sourceView = con.view;
        }
        
        [con presentViewController:self.previewController animated:YES completion:^{
        NSLog(@"Displaying...");
        }];
    }
    
}
//关闭预览的回调
- (void)previewControllerDidFinish:(RPPreviewViewController *)previewController
{
    if(previewController != NULL)
    {
        [previewController dismissViewControllerAnimated:YES completion:^{}];
    }  
}
//拉起直播广播列表的接口
-(void) startBroadcast
{
    [RPBroadcastActivityViewController loadBroadcastActivityViewControllerWithHandler:^(RPBroadcastActivityViewController * _Nullable broadcastActivityViewController, NSError * _Nullable error) {
        
        NSLog(@"====>>show boradcast view");
        self.broadcastAVC = broadcastActivityViewController;
        self.broadcastAVC.delegate = self;
        self.broadcastAVC.modalPresentationStyle = UIModalPresentationPopover;
        //broadcastActivityViewController.delegate = self;
        UIViewController * con = [UIApplication sharedApplication].keyWindow.rootViewController;
         
            [con presentViewController:self.broadcastAVC animated:YES completion:^{
                
                NSLog(@"====>>show boradcast view end ");
            }];     
    }];
}
//
- (void)broadcastActivityViewController:(RPBroadcastActivityViewController *)broadcastActivityViewController didFinishWithBroadcastController:(RPBroadcastController *)broadcastController error:(NSError *)error
{
    [self.broadcastAVC dismissViewControllerAnimated:YES completion:nil];
    self.broadcastController = broadcastController;
    [broadcastController startBroadcastWithHandler:^(NSError * _Nullable error) {
        
        if( !error)
        {
            //set live button enable
            NSLog(@"----------Live Srart------");
        }
        else
        {
            NSLog(@"startBroadcastWithHandler error: %@",error);
        }
    }];
}
@end


测试结果如图:


ios开始直播感知_封装_03


调用startRecoder的效果,预览的效果图我就不贴了,自己测试下看看吧,感觉苹果做的预览还是不错的。



新添加的注意项


如果当前使用的是ipad在presentView之前必须修改

//ipad需要修改显示方式
            if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
            {
                self.broadcastAVC.popoverPresentationController.sourceRect = CGRectMake(pointX, pointY, width, height);
                self.broadcastAVC.popoverPresentationController.sourceView = con.view;
                
            }