[木木方文技术分享之音视频二]获取摄像头视频流

添加依赖库


#import <AVFoundation/AVFoundation.h>
//
//  LiveTelecastController.m
//  FFmpegDemo
//
//  Created by huoliquankai on 2017/7/20.
//  Copyright © 2017年 火力全开. All rights reserved.
//

#import "LiveTelecastController.h"
#import <AVFoundation/AVFoundation.h>

@interface LiveTelecastController () <AVCaptureVideoDataOutputSampleBufferDelegate>
{
   
}
@property (nonatomic, strong)AVCaptureSession *session;
@property (nonatomic, strong)AVCaptureDeviceInput *videoInput;
@property (nonatomic, strong)AVCaptureVideoDataOutput *videoDataOutput;
@property (nonatomic, strong)UIView *cameraShowView;
@property (nonatomic, strong)AVCaptureVideoPreviewLayer *previewLayer;
@end

@implementation LiveTelecastController

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self initialSession];
        [self initialCameraShowView];
    }
    return self;
}

- (void)initialSession {
    self.session = [[AVCaptureSession alloc] init];
    self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backCamera] error:nil];
    self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
//  kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange表示设置摄像头返回的数据类型为YUV420SP类型    
NSDictionary *outputSettings = [NSDictionary dictionaryWithObject:
                                    [NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange]
                                                               forKey:(id)kCVPixelBufferPixelFormatTypeKey];
    [self.videoDataOutput setVideoSettings:outputSettings];
    dispatch_queue_t queue = dispatch_queue_create("linlinqi", NULL);
    [self.videoDataOutput setSampleBufferDelegate:self queue:queue];
    if ([self.session canAddInput:self.videoInput]) {
        [self.session addInput:self.videoInput];
    }
    if ([self.session canAddOutput:self.videoDataOutput]) {
        [self.session addOutput:self.videoDataOutput];
    } else {
        NSLog(@"failed get output");
    }
}

- (void)initialCameraShowView {
    self.cameraShowView = [[UIView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:self.cameraShowView];
}

- (AVCaptureDevice *)backCamera {
    return [self cameraWithPosition:AVCaptureDevicePositionBack];
}

- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position {
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) {
        if (device.position == position) {
            return device;
        }
    }
    return nil;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self setUpCameraLayer];
}
//启动摄像头捕获数据
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (self.session) {
        [self.session startRunning];
    }
}

- (void)setUpCameraLayer {
    if (self.previewLayer == nil) {
        self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
        UIView *view = self.cameraShowView;
        CALayer *viewLayer = [view layer];
        [viewLayer setMasksToBounds:YES];
        CGRect bounds = [view bounds];
        [self.previewLayer setFrame:bounds];
        [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
        [viewLayer addSublayer:self.previewLayer];
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

#pragma AVCaptureVideoDataOutputSampleBufferDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    NSLog(@"get data success");
}

@end

获取到的数据格式
CMSampleBuffer 0x15be22d20 retainCount: 1 allocator: 0x1b8606bb8
invalid = NO
dataReady = YES
makeDataReadyCallback = 0x0
makeDataReadyRefcon = 0x0
buffer-level attachments:
Orientation(P) = 1
{Exif}    (P) = <CFBasicHash 0x17427bc00 [0x1b8606bb8]>{type = mutable dict, count = 24,
entries =>
0 : <CFString 0x17404bcd0 [0x1b8606bb8]>{contents = "DateTimeOriginal"} = <CFString 0x17404baf0 [0x1b8606bb8]>{contents = "2017:07:20 16:47:20"}
1 : <CFString 0x1b278f930 [0x1b8606bb8]>{contents = "MeteringMode"} = <CFNumber 0xb000000000000052 [0x1b8606bb8]>{value = +5, type = kCFNumberSInt32Type}
2 : <CFString 0x1b278fe70 [0x1b8606bb8]>{contents = "LensMake"} = Apple
3 : <CFString 0x1b287c480 [0x1b8606bb8]>{contents = "BrightnessValue"} = <CFNumber 0x174035260 [0x1b8606bb8]>{value = +3.32548037588890554872, type = kCFNumberFloat64Type}
6 : <CFString 0x1b278f670 [0x1b8606bb8]>{contents = "FNumber"} = <CFNumber 0x174037e20 [0x1b8606bb8]>{value = +2.20000000000000017764, type = kCFNumberFloat64Type}
7 : <CFString 0x1b278f990 [0x1b8606bb8]>{contents = "FocalLength"} = <CFNumber 0x174037dc0 [0x1b8606bb8]>{value = +4.15000000000000035527, type = kCFNumberFloat64Type}
8 : <CFString 0x1b278f870 [0x1b8606bb8]>{contents = "ShutterSpeedValue"} = <CFNumber 0x174035d00 [0x1b8606bb8]>{value = +6.64385618977472436342, type = kCFNumberFloat64Type}
9 : <CFString 0x1b278fc30 [0x1b8606bb8]>{contents = "SceneType"} = <CFNumber 0xb000000000000012 [0x1b8606bb8]>{value = +1, type = kCFNumberSInt32Type}
10 : <CFString 0x1b278f890 [0x1b8606bb8]>{contents = "ApertureValue"} = <CFNumber 0x174036b20 [0x1b8606bb8]>{value = +2.27500704749987026076, type = kCFNumberFloat64Type}
13 : <CFString 0x1b278fa90 [0x1b8606bb8]>{contents = "ColorSpace"} = <CFNumber 0xb000000000000012 [0x1b8606bb8]>{value = +1, type = kCFNumberSInt32Type}
17 : <CFString 0x1b278fe50 [0x1b8606bb8]>{contents = "LensSpecification"} = (
    "4.15",
    "4.15",
    "2.2",
    "2.2"
)
18 : <CFString 0x1b278fad0 [0x1b8606bb8]>{contents = "PixelYDimension"} = <CFNumber 0xb000000000004383 [0x1b8606bb8]>{value = +1080, type = kCFNumberSInt64Type}
19 : <CFString 0x1b278fcb0 [0x1b8606bb8]>{contents = "WhiteBalance"} = <CFNumber 0xb000000000000002 [0x1b8606bb8]>{value = +0, type = kCFNumberSInt32Type}
23 : <CFString 0x17404e910 [0x1b8606bb8]>{contents = "DateTimeDigitized"} = <CFString 0x17404bca0 [0x1b8606bb8]>{contents = "2017:07:20 16:47:20"}
28 : <CFString 0x1b278f6d0 [0x1b8606bb8]>{contents = "ISOSpeedRatings"} = (
    32
)
31 : <CFString 0x1b278fab0 [0x1b8606bb8]>{contents = "PixelXDimension"} = <CFNumber 0xb000000000007803 [0x1b8606bb8]>{value = +1920, type = kCFNumberSInt64Type}
32 : <CFString 0x1b278fe90 [0x1b8606bb8]>{contents = "LensModel"} = <CFString 0x17427ac80 [0x1b8606bb8]>{contents = "iPhone 6 back camera 4.15mm f/2.2"}
34 : <CFString 0x17404bdc0 [0x1b8606bb8]>{contents = "SubsecTimeOriginal"} = 408
35 : <CFString 0x1b287a4c0 [0x1b8606bb8]>{contents = "ExposureTime"} = <CFNumber 0x174038060 [0x1b8606bb8]>{value = +0.01000000000000000021, type = kCFNumberFloat64Type}
36 : <CFString 0x17404bb20 [0x1b8606bb8]>{contents = "SubsecTimeDigitized"} = 408
37 : <CFString 0x1b278fcf0 [0x1b8606bb8]>{contents = "FocalLenIn35mmFilm"} = <CFNumber 0xb000000000000202 [0x1b8606bb8]>{value = +32, type = kCFNumberSInt32Type}
38 : <CFString 0x1b278f970 [0x1b8606bb8]>{contents = "Flash"} = <CFNumber 0xb000000000000002 [0x1b8606bb8]>{value = +0, type = kCFNumberSInt32Type}
39 : <CFString 0x1b278fbf0 [0x1b8606bb8]>{contents = "SensingMethod"} = <CFNumber 0xb000000000000022 [0x1b8606bb8]>{value = +2, type = kCFNumberSInt32Type}
40 : <CFString 0x1b278f8d0 [0x1b8606bb8]>{contents = "ExposureBiasValue"} = <CFNumber 0xb000000000000005 [0x1b8606bb8]>{value = +0.0, type = kCFNumberFloat64Type}
}

DPIWidth  (P) = 72
{TIFF}    (P) = <CFBasicHash 0x17427a940 [0x1b8606bb8]>{type = mutable dict, count = 7,
entries =>
1 : <CFString 0x1b278f490 [0x1b8606bb8]>{contents = "ResolutionUnit"} = <CFNumber 0xb000000000000022 [0x1b8606bb8]>{value = +2, type = kCFNumberSInt32Type}
2 : Software = 10.3.2
5 : DateTime = <CFString 0x17404ed00 [0x1b8606bb8]>{contents = "2017:07:20 16:47:20"}
6 : <CFString 0x1b278f450 [0x1b8606bb8]>{contents = "XResolution"} = <CFNumber 0xb000000000000482 [0x1b8606bb8]>{value = +72, type = kCFNumberSInt32Type}
9 : Model = iPhone 6
10 : <CFString 0x1b278f470 [0x1b8606bb8]>{contents = "YResolution"} = <CFNumber 0xb000000000000482 [0x1b8606bb8]>{value = +72, type = kCFNumberSInt32Type}
11 : Make = Apple
}

DPIHeight (P) = 72
{MakerApple}(P) = {
    1 = 3;
    10 = 0;
    14 = 0;
    3 =     {
        epoch = 0;
        flags = 1;
        timescale = 1000000000;
        value = 54041253161083;
    };
    4 = 0;
    5 = 193;
    6 = 25;
    7 = 1;
    8 =     (
        "-0.01732243",
        "-0.7562239",
        "-0.6610191"
    );
    9 = 0;
}
formatDescription = <CMVideoFormatDescription 0x17404b640 [0x1b8606bb8]> {
mediaType:'vide'
mediaSubType:'BGRA'
mediaSpecific: {
codecType: 'BGRA'dimensions: 1920 x 1080
}
extensions: {<CFBasicHash 0x1744603c0 [0x1b8606bb8]>{type = immutable dict, count = 6,
entries =>
0 : <CFString 0x1b283b7c8 [0x1b8606bb8]>{contents = "CVImageBufferYCbCrMatrix"} = <CFString 0x1b283b808 [0x1b8606bb8]>{contents = "ITU_R_601_4"}
1 : <CFString 0x1b283b928 [0x1b8606bb8]>{contents = "CVImageBufferTransferFunction"} = <CFString 0x1b283b7e8 [0x1b8606bb8]>{contents = "ITU_R_709_2"}
2 : <CFString 0x1b286e8a0 [0x1b8606bb8]>{contents = "CVBytesPerRow"} = <CFNumber 0xb00000000001e002 [0x1b8606bb8]>{value = +7680, type = kCFNumberSInt32Type}
3 : <CFString 0x1b286e920 [0x1b8606bb8]>{contents = "Version"} = <CFNumber 0xb000000000000022 [0x1b8606bb8]>{value = +2, type = kCFNumberSInt32Type}
5 : <CFString 0x1b283b8a8 [0x1b8606bb8]>{contents = "CVImageBufferColorPrimaries"} = <CFString 0x1b283b7e8 [0x1b8606bb8]>{contents = "ITU_R_709_2"}
6 : <CFString 0x1b283b9a8 [0x1b8606bb8]>{contents = "CVImageBufferChromaLocationTopField"} = <CFString 0x1b283ba08 [0x1b8606bb8]>{contents = "Center"}
}
}
}
sbufToTrackReadiness = 0x0
numSamples = 1
sampleTimingArray[1] = {
{PTS = {54041253161083/1000000000 = 54041.253}, DTS = {INVALID}, duration = {INVALID}},
}
imageBuffer = 0x174124ce0
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容