首页 > 其他分享 >iOS开发基础107-直播

iOS开发基础107-直播

时间:2024-07-16 18:29:17浏览次数:14  
标签:status NSLog self iOS 直播 void liveSession streamingSession 107

在 iOS 平台上,直播技术已经很成熟,有许多强大的第三方框架可以帮助开发者轻松实现直播功能。当前主流的直播第三方框架包括但不限于:

  1. LFLiveKit:一款开源的直播推流 SDK。
  2. PLMediaStreamingKit:由云天存提供的一站式音视频解决方案。
  3. AliyunPlayer:阿里云提供的音视频播放解决方案。
  4. Agora SDK:声网提供的大规模实时视频通讯解决方案。

以下将详细介绍 LFLiveKit 和 PLMediaStreamingKit 的使用,并给出相应的示例代码。

一、LFLiveKit

1. LFLiveKit 安装

要使用 LFLiveKit 首先需要通过 CocoaPods 添加到你的项目。

在你的 Podfile 文件中添加如下内容:

pod 'LFLiveKit'

然后运行 pod install

2. 配置和使用

Import LFLiveKit 的头文件:

#import <LFLiveKit/LFLiveKit.h>
创建直播会话

LFLiveKit 提供了多种配置选项。首先,你需要创建一个 LFLiveSession,这是 LFLiveKit 的核心类,负责管理音视频捕获和推流处理。

- (LFLiveSession*)liveSession {
    if (!_liveSession) {
        // 自定义音频和视频配置
        LFLiveAudioConfiguration *audioConfiguration = [LFLiveAudioConfiguration defaultConfiguration];
        LFLiveVideoConfiguration *videoConfiguration = [LFLiveVideoConfiguration defaultConfiguration];
        
        _liveSession = [[LFLiveSession alloc] initWithAudioConfiguration:audioConfiguration videoConfiguration:videoConfiguration];
        _liveSession.delegate = self;
        _liveSession.preView = self.view; // 设置预览视图
    }
    return _liveSession;
}
请求权限

在 iOS 开发中,需要请求相机和麦克风权限。以下是请求权限代码:

- (void)requestAccessForVideo {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (status == AVAuthorizationStatusNotDetermined) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if (granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.liveSession setRunning:YES];
                });
            }
        }];
    } else if (status == AVAuthorizationStatusAuthorized) {
        [self.liveSession setRunning:YES];
    }
}

- (void)requestAccessForAudio {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    if (status == AVAuthorizationStatusNotDetermined) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
            if (granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.liveSession setRunning:YES];
                });
            }
        }];
    } else if (status == AVAuthorizationStatusAuthorized) {
        [self.liveSession setRunning:YES];
    }
}
开始直播

配置完 LFLiveStreamInfo 对象,并调用 startLive: 方法开始直播。

- (void)startLive {
    LFLiveStreamInfo *streamInfo = [LFLiveStreamInfo new];
    streamInfo.url = @"rtmp://your_server/live_stream";
    [self.liveSession startLive:streamInfo];
}

- (void)stopLive {
    [self.liveSession stopLive];
}
处理直播状态变化

通过实现 LFLiveSessionDelegate,可以监测广播的状态变更。

- (void)liveSession:(LFLiveSession *)session liveStateDidChange:(LFLiveState)state {
    switch (state) {
        // 在每个状态变化时的对应处理
        case LFLiveReady:
            NSLog(@"Ready to start live streaming");
            break;
        case LFLivePending:
            NSLog(@"Connecting...");
            break;
        case LFLiveStart:
            NSLog(@"Live streaming started");
            break;
        case LFLiveStop:
            NSLog(@"Live streaming stopped");
            break;
        case LFLiveError:
            NSLog(@"Live streaming error");
            break;
        case LFLiveRefresh:
            NSLog(@"Live streaming refreshing");
            break;
    }
}
完整示例:

完整的 ViewController.m 看起来如下:

#import "ViewController.h"
#import <LFLiveKit/LFLiveKit.h>

@interface ViewController () <LFLiveSessionDelegate>
@property (nonatomic, strong) LFLiveSession *liveSession;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self requestAccessForVideo];
    [self requestAccessForAudio];
    [self startLive];
}

- (LFLiveSession*)liveSession {
    if (!_liveSession) {
        LFLiveAudioConfiguration *audioConfiguration = [LFLiveAudioConfiguration defaultConfiguration];
        LFLiveVideoConfiguration *videoConfiguration = [LFLiveVideoConfiguration defaultConfiguration];
        
        _liveSession = [[LFLiveSession alloc] initWithAudioConfiguration:audioConfiguration videoConfiguration:videoConfiguration];
        _liveSession.delegate = self;
        _liveSession.preView = self.view;
    }
    return _liveSession;
}

- (void)requestAccessForVideo {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (status == AVAuthorizationStatusNotDetermined) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if (granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.liveSession setRunning:YES];
                });
            }
        }];
    } else if (status == AVAuthorizationStatusAuthorized) {
        [self.liveSession setRunning:YES];
    }
}

- (void)requestAccessForAudio {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    if (status == AVAuthorizationStatusNotDetermined) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
            if (granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.liveSession setRunning:YES];
                });
            }
        }];
    } else if (status == AVAuthorizationStatusAuthorized) {
        [self.liveSession setRunning:YES];
    }
}

- (void)startLive {
    LFLiveStreamInfo *streamInfo = [LFLiveStreamInfo new];
    streamInfo.url = @"rtmp://your_server/live_stream";
    [self.liveSession startLive:streamInfo];
}

- (void)stopLive {
    [self.liveSession stopLive];
}

- (void)liveSession:(LFLiveSession *)session liveStateDidChange:(LFLiveState)state {
    switch (state) {
        case LFLiveReady:
            NSLog(@"Ready to start live streaming");
            break;
        case LFLivePending:
            NSLog(@"Connecting...");
            break;
        case LFLiveStart:
            NSLog(@"Live streaming started");
            break;
        case LFLiveStop:
            NSLog(@"Live streaming stopped");
            break;
        case LFLiveError:
            NSLog(@"Live streaming error");
            break;
        case LFLiveRefresh:
            NSLog(@"Live streaming refreshing");
            break;
    }
}
@end

二、PLMediaStreamingKit

1. PLMediaStreamingKit 安装

使用 CocoaPods 安装:

pod 'PLMediaStreamingKit'

运行 pod install 之后,在项目的任意位置导入 PLMediaStreamingKit

#import <PLMediaStreamingKit/PLMediaStreamingKit.h>

2. 配置和使用

创建推流会话

PLMediaStreamingSession 是此框架的核心类,用于音视频捕获、编码和推流。

- (PLMediaStreamingSession *)streamingSession {
    if (!_streamingSession) {
        PLVideoCaptureConfiguration *videoConfiguration = [PLVideoCaptureConfiguration defaultConfiguration];
        PLAudioCaptureConfiguration *audioConfiguration = [PLAudioCaptureConfiguration defaultConfiguration];
        
        PLVideoStreamingConfiguration *videoStreamingConfiguration = [PLVideoStreamingConfiguration defaultConfiguration];
        PLAudioStreamingConfiguration *audioStreamingConfiguration = [PLAudioStreamingConfiguration defaultConfiguration];
        
        _streamingSession = [[PLMediaStreamingSession alloc] initWithVideoCaptureConfiguration:videoConfiguration
                                                           audioCaptureConfiguration:audioConfiguration
                                                        videoStreamingConfiguration:videoStreamingConfiguration
                                                       audioStreamingConfiguration:audioStreamingConfiguration];
        
        _streamingSession.delegate = self;
        _streamingSession.previewView = self.view;
    }
    return _streamingSession;
}
检查并请求权限

和 LFLiveKit 类似,我们需要请求相机和麦克风的权限:

- (void)requestAccessForVideo {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (status == AVAuthorizationStatusNotDetermined) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if (granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.streamingSession startCaptureSession];
                });
            }
        }];
    } else if (status == AVAuthorizationStatusAuthorized) {
        [self.streamingSession startCaptureSession];
    }
}

- (void)requestAccessForAudio {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    if (status == AVAuthorizationStatusNotDetermined) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
            if (granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.streamingSession startCaptureSession];
                });
            }
        }];
    } else if (status == AVAuthorizationStatusAuthorized) {
        [self.streamingSession startCaptureSession];
    }
}
开始直播

创建一个 PLStream 对象,包含推流的 URL 和其他配置信息,并启动推流。

- (void)startStreaming {
    PLStream *stream = [PLStream new];
    stream.url = @"rtmp://your_server/live_stream";
    
    [self.streamingSession startWithStream:stream feedback:^(PLStreamStartStateFeedback *feedback) {
        if (feedback.state == PLStreamStartStateSuccess) {
            NSLog(@"Streaming Started Successfully");
        } else {
            NSLog(@"Failed to start streaming: %@", feedback.error.localizedDescription);
        }
    }];
}

- (void)stopStreaming {
    [self.streamingSession stop];
}
处理推流状态变化

通过实现 PLMediaStreamingSessionDelegate 的相关方法,可以监测推流状态的变化。

- (void)mediaStreamingSession:(PLMediaStreamingSession *)session streamStatusDidUpdate:(PLStreamStatus *)status {
    NSLog(@"Stream status: %@", status);
}

- (void)mediaStreamingSession:(PLMediaStreamingSession *)session didDisconnectWithError:(NSError *)error {
    NSLog(@"Stream disconnected with error: %@", error.localizedDescription);
}
完整示例:

完整的 ViewController.m 可以如下:

#import "ViewController.h"
#import <PLMediaStreamingKit/PLMediaStreamingKit.h>

@interface ViewController () <PLMediaStreamingSessionDelegate>
@property (nonatomic, strong) PLMediaStreamingSession *streamingSession;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self requestAccessForVideo];
    [self requestAccessForAudio];
}

- (PLMediaStreamingSession *)streamingSession {
    if (!_streamingSession) {
        PLVideoCaptureConfiguration *videoConfiguration = [PLVideoCaptureConfiguration defaultConfiguration];
        PLAudioCaptureConfiguration *audioConfiguration = [PLAudioCaptureConfiguration defaultConfiguration];
        
        PLVideoStreamingConfiguration *videoStreamingConfiguration = [PLVideoStreamingConfiguration defaultConfiguration];
        PLAudioStreamingConfiguration *audioStreamingConfiguration = [PLAudioStreamingConfiguration defaultConfiguration];
        
        _streamingSession = [[PLMediaStreamingSession alloc] initWithVideoCaptureConfiguration:videoConfiguration
                                                                   audioCaptureConfiguration:audioConfiguration
                                                            videoStreamingConfiguration:videoStreamingConfiguration
                                                           audioStreamingConfiguration:audioStreamingConfiguration
                                                                                 stream:nil];
        
        _streamingSession.delegate = self;
        _streamingSession.previewView = self.view;
    }
    return _streamingSession;
}

- (void)requestAccessForVideo {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (status == AVAuthorizationStatusNotDetermined) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if (granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.streamingSession startCaptureSession];
                });
            }
        }];
    } else if (status == AVAuthorizationStatusAuthorized) {
        [self.streamingSession startCaptureSession];
    }
}

- (void)requestAccessForAudio {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    if (status == AVAuthorizationStatusNotDetermined) {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
            if (granted) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.streamingSession startCaptureSession];
                });
            }
        }];
    } else if (status == AVAuthorizationStatusAuthorized) {
        [self.streamingSession startCaptureSession];
    }
}

- (void)startStreaming {
    PLStream *stream = [PLStream new];
    stream.url = @"rtmp://your_server/live_stream";
    
    [self.streamingSession startWithStream:stream feedback:^(PLStreamStartStateFeedback *feedback) {
        if (feedback.state == PLStreamStartStateSuccess) {
            NSLog(@"Streaming Started Successfully");
        } else {
            NSLog(@"Failed to start streaming: %@", feedback.error.localizedDescription);
        }
    }];
}

- (void)stopStreaming {
    [self.streamingSession stop];
}

- (void)mediaStreamingSession:(PLMediaStreamingSession *)session streamStatusDidUpdate:(PLStreamStatus *)status {
    NSLog(@"Stream status: %@", status);
}

- (void)mediaStreamingSession:(PLMediaStreamingSession *)session didDisconnectWithError:(NSError *)error {
    NSLog(@"Stream disconnected with error: %@", error.localizedDescription);
}
@end

标签:status,NSLog,self,iOS,直播,void,liveSession,streamingSession,107
From: https://www.cnblogs.com/chglog/p/18305877

相关文章

  • web直播
    步骤一:开通腾讯云直播服务步骤二:获取推流URL想要简单获取一个推流URL,可以参考文档:快速获得地址想要了解推流地址和直播间ID的关系,可以参考文档:后台自动拼装想要了解如果保护自己的推流地址不被盗用,可以参考文档:防盗链签名步骤三:获取播放URL步骤四:配置推流端测试时使用ObsS......
  • iOS开发基础105-Xcode收集Crashs的各种方法
    Xcode提供了一整套工具和功能来帮助开发者收集、分析和处理应用崩溃报告。通过这些工具,开发者可以追踪和解析崩溃日志,以更加准确和及时地修复问题。以下是详细介绍Xcode工具收集崩溃报告的各种方法。一、通过设备获取崩溃报告1.连接设备将iOS设备通过USB连接到您的Mac......
  • iOS开发基础106-Instruments
    Instruments是苹果公司提供的一款强大的分析和性能调试工具,集成在Xcode开发环境中。Instruments可帮助开发者分析和优化iOS、macOS应用,检测性能瓶颈、内存泄漏、CPU使用率、磁盘I/O等问题,从而提升应用的效率和用户体验。以下详细介绍Instruments的主要功能和使用方法......
  • 直播预约丨《指标体系建设实战》第四期:如何构建全面的指标管理体系
    指标是反映企业的各项核心业务活动、管理成效的数据体系,指标体系作为联结业务逻辑与数据实体的关键桥梁,是构建高质量数据统计的基础单元,并在量化业务绩效和效果评估中扮演着核心角色。为了更好地服务于客户并提供切实可行的实践指导,自4月24日起,袋鼠云将推出全新《指标体系建设实......
  • iOS开发基础104-正向代理和反向代理
    正向代理和反向代理是计算机网络中两种重要的技术,它们在网络请求的传递和管理上扮演着不同的角色。下面将详细介绍这两者的概念、优缺点,并探讨它们在iOS开发中的应用。一、正向代理1.概念正向代理是一种代理服务器,客户端向代理服务器发送请求,由代理服务器转发请求到目标服务器......
  • iOS开发基础103-APP之间跳转
    iOS提供了多种方式来实现应用之间的相互跳转。其中,URLSchemes和UniversalLinks是两种主要的方法。下面详细介绍这两种方法,并提供相应的示例代码,同时对它们的优缺点进行分析。一、URLSchemes1.什么是URLSchemesURLSchemes是一种基于URL的通讯方式,允许一个应用通过指定的UR......
  • iOS开发基础102-后台保活方案
    iOS系统在后台执行程序时,有严格的限制,为了更好地管理资源和电池寿命,iOS会限制应用程序在后台的运行时间。然而,iOS提供了一些特定的策略和技术,使得应用程序可以在特定场景下保持后台运行(即“后台保活”)。以下是iOS中几种常见的后台保活方案,并附上示例代码:一、后台任务利用beginBa......
  • iOS开发基础101-指纹和面部识别
    在iOS开发中,使用FaceID和TouchID可以为用户提供安全的生物识别认证,而手势识别(GestureRecognition)可以增加用户交互的便利性和灵活性。下面将详细介绍这三种技术,并给出如何封装一个统一的工具类来供外部使用。一、FaceID与TouchID1.设置与配置在使用FaceID和TouchID之前,需要在......
  • 数字人直播:超越传统,探索直播的全新领域
    在这个数字化时代,直播已经成为了一种不可或缺的营销手段。然而,随着技术的发展,数字人直播正逐渐成为电商行业的新宠。那么,什么是数字人直播呢?简单来说,数字人直播就是通过AI技术创造出的虚拟人物进行直播。这些虚拟人物可以模仿真人的动作、表情和声音,甚至能够进行一定程度的智能......
  • 题解:P10724 [GESP202406 七级] 区间乘积
    思路看到\(a_i\)很小,不难想到状压一类的东西。考虑把每个数的质因数当做二进制位,这个二进制位的\(1/0\)代表含有这个质因数的奇偶,再做一个异或前缀和,显然完全平方数的质因子个数一定为偶数,根据异或的性质,两个相同的数异或才为\(0\)所以只需要找到异或前缀和中相同的数的个......