这里我们要研究直播技术首先需要对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. 获取程序的SHA1值

    android获取程序的SHA1值 public static String getSHA1(Context context) { try { PackageInfo info = context.g ...

  2. 给Source Insight做个外挂系列之二--将本地代码注入到Source Insight进程

    上一篇文章介绍了如何发现正在运行的“Source Insight”窗口,本篇将介绍“TabSiPlus”是如何进行代码注入的.Windows 9x以后的Windows操作系统都对进程空间进行了严格的保 ...

  3. 代码阅读分析工具Understand 2.0试用

    Understand 2.0是一款源代码阅读分析软件,功能强大.试用过一段时间后,感觉相当不错,确实可以大大提高代码阅读效率.由于Understand功能十分强大,本文不可能详尽地介绍它的所有功能,所 ...

  4. iphone状态栏高度?

      设备分辨率         状态栏高度           导航栏高度 标签栏高度 iPhone6 plus       1242×2208 px           60px           ...

  5. asp.net 重定向的三种方法

    1.Server.Transfer("URL"): 服务器停止解析本页,保存此页转向前的数据后,再使页面转向到newPage.aspx, 并将转向前数据加上newPage.aspx ...

  6. WINDOWS下PhoneGap(Cordova)安装笔记

    1.首先下载Node.js  安装nodejs很简单直接点击安装文件下一步直至成功即可,安装notejs的同时npm也会同时安装 成功后打开notejs的命令行工具 输入“node -v”," ...

  7. 判断ecshop未付款添加去付款按钮

    判断ecshop未付款添加去付款按钮,打开ecshop模板目录下user_transaction.dwt找到{$item.handler} 这个变量 给它下面添加以下代码 {if $item.pay_ ...

  8. iOS 面试题(五):weak 的内部实现原理 --转自唐巧

    问题 weak 变量在引用计数为0时,会被自动设置成 nil,这个特性是如何实现的? 答案 在 Friday QA 上,有一期专门介绍 weak 的实现原理.https://mikeash.com/p ...

  9. rbd cache (一)

    cache 1.why The existence of cache is based on a mismatch between the performance characteristics of ...

  10. Eexcel批量设定单元格条件格式

    最近在整理excel项目记录,觉得有些技巧还是值得拥有,记录备份下,以防将来使用: [工具/原料] excel(office或wps) [方法/步骤] 1.建立一个追踪表如下: 2.选择状态列,建立数 ...