这里我们要研究直播技术首先需要对AVFoundation熟悉掌握

  • AVFoundation拍照和录制视频

AVFoundation中提供了很多现成的播放器和录音机,但是事实上它还有更加底层的内容可以供开发者使用。因为AVFoundation中抽了很多和底层输入、输出设备打交道的类,依靠这些类开发人员面对的不再是封装好的音频播放器AVAudioPlayer、录音机(AVAudioRecorder)、视频(包括音频)播放器AVPlayer,而是输入设备(例如麦克风、摄像头)、输出设备(图片、视频)等。首先了解一下使用AVFoundation做拍照和视频录制开发用到的相关类:

AVCaptureSession:媒体(音、视频)捕获会话,负责把捕获的音视频数据输出到输出设备中。一个AVCaptureSession可以有多个输入输出:

AVCaptureDevice:输入设备,包括麦克风、摄像头,通过该对象可以设置物理设备的一些属性(例如相机聚焦、白平衡等)。

AVCaptureDeviceInput:设备输入数据管理对象,可以根据AVCaptureDevice创建对应的AVCaptureDeviceInput对象,该对象将会被添加到AVCaptureSession中管理。

AVCaptureOutput:输出数据管理对象,用于接收各类输出数据,通常使用对应的子类AVCaptureAudioDataOutput、AVCaptureStillImageOutput、AVCaptureVideoDataOutput、AVCaptureFileOutput,该对象将会被添加到AVCaptureSession中管理。注意:前面几个对象的输出数据都是NSData类型,而AVCaptureFileOutput代表数据以文件形式输出,类似的,AVCcaptureFileOutput也不会直接创建使用,通常会使用其子类:AVCaptureAudioFileOutput、AVCaptureMovieFileOutput。当把一个输入或者输出添加到AVCaptureSession之后AVCaptureSession就会在所有相符的输入、输出设备之间建立连接(AVCaptionConnection): 

AVCaptureVideoPreviewLayer:相机拍摄预览图层,是CALayer的子类,使用该对象可以实时查看拍照或视频录制效果,创建该对象需要指定对应的AVCaptureSession对象。

使用AVFoundation拍照和录制视频的一般步骤如下:

  1. 创建AVCaptureSession对象。
  2. 使用AVCaptureDevice的静态方法获得需要使用的设备,例如拍照和录像就需要获得摄像头设备,录音就要获得麦克风设备。
  3. 利用输入设备AVCaptureDevice初始化AVCaptureDeviceInput对象。
  4. 初始化输出数据管理对象,如果要拍照就初始化AVCaptureStillImageOutput对象;如果拍摄视频就初始化AVCaptureMovieFileOutput对象。
  5. 将数据输入对象AVCaptureDeviceInput、数据输出对象AVCaptureOutput添加到媒体会话管理对象AVCaptureSession中。
  6. 创建视频预览图层AVCaptureVideoPreviewLayer并指定媒体会话,添加图层到显示容器中,调用AVCaptureSession的startRuning方法开始捕获。
  7. 将捕获的音频或视频数据输出到指定文件。
#import "ViewController.h"
#define WIDTH [UIScreen mainScreen].bounds.size.width
#define HEIGHT [UIScreen mainScreen].bounds.size.height
@interface ViewController ()<AVCaptureVideoDataOutputSampleBufferDelegate>
@property (nonatomic,strong)AVCaptureSession *session;
@property (nonatomic,strong)AVCaptureVideoPreviewLayer *preViewLayer;
@end @implementation ViewController{ AVCaptureConnection *_videoConnection;//输入输出建立连接
AVCaptureConnection *_audioConnection;
} - (void)viewDidLoad {
[super viewDidLoad];
[self initView];
// Do any additional setup after loading the view, typically from a nib.
} -(void)initView{ //初始化会话
NSError * error = nil;
self.session = [[AVCaptureSession alloc] init];
// ???
self.session.sessionPreset = AVCaptureSessionPresetMedium;
//设置摄像头
AVCaptureDevice * device = [self cameraWithPosition:AVCaptureDevicePositionFront];
//获取输入设备
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (error) {
NSLog(@"%@",error);
}
//添加输入设备
if ([_session canAddInput:input]) {
[self.session addInput:input];
}
//获取输出设备
AVCaptureVideoDataOutput * output = [[AVCaptureVideoDataOutput alloc] init];
dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
[output setSampleBufferDelegate:self queue:queue]; output.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange] forKey:(NSString *)kCVPixelBufferPixelFormatTypeKey];
output.alwaysDiscardsLateVideoFrames = YES; [self startRuning];
//添加输出设备
if ([self.session canAddOutput:output]) {
[self.session addOutput:output];
} //创建浏览层,用于展示
self.preViewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
self.preViewLayer.frame = CGRectMake(0, 0, WIDTH, 500);
self.preViewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//填充模式
[self.view.layer addSublayer:self.preViewLayer]; //
_videoConnection = [output connectionWithMediaType:AVMediaTypeVideo]; } -(void)startRuning{ [self.session startRunning];
} // 选择是前摄像头还是后摄像头
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition) position {
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices) {
if ([device position] == position) {
return device;
}
}
return nil;
} // 关键方法,捕获摄像头每一帧的画面并编码
-(void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { if (connection == _videoConnection) { // [_manager264 encoderToH264:sampleBuffer]; } if (connection == _audioConnection) {
NSLog(@"yy");
}
}
@end

iOS开发直播需要的准备的更多相关文章

  1. 【Swift】iOS开发历险记(二)

    前言 这个系列主要是一些开发中遇到的坑记录分享,有助于初学者跨过这些坑,攒够 7 条发一篇. 声明  欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯 ...

  2. 深入理解iOS开发中的BitCode功能

    前言 做iOS开发的朋友们都知道,目前最新的Xcode7,新建项目默认就打开了bitcode设置.而且大部分开发者都被这个突如其来的bitcode功能给坑过导致项目编译失败,而这些因为bitcode而 ...

  3. iOS 视频直播

    ijkplayer 是一款做视频直播的框架, 基于ffmpeg, 支持 Android 和 iOS, 网上也有很多集成说明, 但是个人觉得还是不够详细, 在这里详细的讲一下在 iOS 中如何集成ijk ...

  4. IOS开发关于测试的好的网址资源

    1. 高级自动化单元测试,推荐看LeanCloud 工程师的李智维的自动化单元测试的直播录影李智维的演示github 2.iOS开发-单元测试 这只是一篇简单的ios测试介绍 3.iOS单元测试 来自 ...

  5. iOS:iOS开发非常全的三方库、插件等等

    iOS开发非常全的三方库.插件等等 github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自git ...

  6. iOS开发——高级UI&带你玩转UITableView

    带你玩装UITableView 在实际iOS开发中UITableView是使用最多,也是最重要的一个控件,如果你不会用它,那别说什么大神了,菜鸟都不如. 其实关于UItableView事非常简单的,实 ...

  7. iOS开发系列

    因为最近面试了一些人,校招.初中级.高级.架构师,各种级别的,发现大家水平差异很大,有的高级的工程师很多问题都回答不上来,所以想梳理下iOS的知识点,写成一个系列,如果时间允许的话,会录制成视频放到网 ...

  8. 【Swift】iOS开发笔记(二)

    前言 这个系列主要是一些开发中遇到的坑记录分享,有助于初学者跨过这些坑,攒够 7 条发一篇. 声明  欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯 ...

  9. iOS开发之资料收集

    github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自github:https://github ...

随机推荐

  1. 【手把手教你Maven】构建过程

    Maven是一款进行 依赖管理.项目构建.信息管理 为一体的工具. 它不像Make具有复杂的命令.也不像Ant需要手动编写大量的重复代码就能进行项目的构建: 还能提供强大的依赖库管理,避免jar包混乱 ...

  2. 分享一个前辈的NPOIhelper

    即拿即用: 首先要下载npoi的dll,此不赘述,接着添加引用: using NPOI.HPSF; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel ...

  3. 《UML大战需求分析》阅读笔记06

    对<UML>撒站需求分析的阅读现在已到达尾声,虽然读这本书是应老师的要求,但是在后期的阅读中也逐渐喜欢上这本书,在阅读的过程中不断领会需求分析与UML之间的联系,让在软件需求分析阶段有了更 ...

  4. wordpress 分类相关

    分类类型,层级 wp中的分类.文章类型(post,page,video,image).标签.自定义分类.自定义标签都是分类形式.有些分类是有层级关系,有些没有.如图: taxonomy分类(categ ...

  5. [dpdk] 熟悉SDK与初步使用 (四)(L3 Forwarding源码分析)

    接续前节:[dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析) 前文中的最后一个问题,搁置,并没有找到答案.所以继续阅读其他例子的代码,想必定能在其他位置看到答案. ...

  6. 微信小程序-WXSS

    WXSS(WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式. WXSS 用来决定 WXML 的组件应该怎么显示. 为了适应广大的前端开发者,我们的 WXSS 具有 ...

  7. RelativeLayout中实现控件平分屏幕

    <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_con ...

  8. 2.4.1 用NPOI操作EXCEL--画线(转)

    之所有说NPOI强大,是因为常用的Excel操作她都可以通过编程的方式完成.这节开始,我们开始学习NPOI的画图功能.先从最简单的开始,画一条直线:对应的代码为: HSSFSheet sheet1 = ...

  9. 关于InvokeRequired与Invoke

    from:http://www.th7.cn/Program/net/201306/140033.shtml Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性.因此,如果从另一个线程调 ...

  10. Redhat 7 或者 CentOS 7 密码破解

    1.在如下界面按 e 2.在 linux16 这一行的最后面添加 rd.break,然后按 ctrl + x 进入单用户模式 3.以读写的方式重新挂载 sysroot 4.切换到 sysroot 目录 ...