前言

提到短视频修正,咱们或许会第一时刻想到FFmpegOpenGL ES这些让人望而生畏的庞大结构,固然音视频开发的入门的确需求一定的根底,可是只是依托于苹果为咱们供给的AVFoundation结构,咱们依然能够在短视频修正范畴做许多作业。本系列文章围绕iOS平台上短视频修正功用中AVFoundation扮演的人物展开讨论,本篇首要介绍学习AVFoundation结构需求了解的根底模块和相关的数据类型及注意事项。

一、 AVFouondation结构概述

AVFoundation 是在 iOS、macOS、watchOS 和 tvOS 上处理多媒体数据的功用齐全的结构。运用AVFoundation,咱们能够播映、创立和修正 QuickTime movie和 MPEG-4 文件,播映 HLS 流,并将强壮的媒体修正功用构建到咱们的应用程序中。

1.1 iOS多媒体结构系统

咱们首要来看AVFouondation结构在苹果的多媒体结构系统中的方位。在iOS的多媒系统统中,高层级的AVKit供给了 高度封装的播映器操控类AVPlayerViewController 、用于切换播映路由(投屏)的AVRoutePickerView,以及完成画中画播映作用的AVPictureInPictureController。低层级的结构首要以C接口为主,其间:

  • Core Audio 最底层的音频处理接口,直接驱动设备的音频硬件,对音乐游戏或专业的音频修正软件供给了全面的支撑。Audio Unit供给了包括组成乐器声响、回声消除、混音、声响均衡等相关接口。

Audio Unit现已迁移到 Audio Toolbox Framework了。

  • Core Video 为其相对的Core Media供给图片缓存(CVPixelBuffer)和缓存池(CVPixelBufferPool)支撑,供给了一个能够对数字视频逐帧拜访的接口,以及对Metal(CVMetalTexture) 、OpenGL(CVOpenGLTexture) 以及OpenGLES(CVOpenGLESTexture)的支撑。
  • Core Media 界说和封装了AVFoundation等更上层的媒体结构需求的媒体处理流水线(包括时刻信息)以及其间运用的接口和数据类型(CMSampleBufferCMTime)。运用 Core Media 层的接口和数据类型能够高效的处理媒体采样数据、办理采样数据队列(CMSimpleQueueCMBufferQueue)。
  • Core Animation 是iOS中动画相关的结构,AVFoundation结合Core Animation让开发者能够在视频修正和播映进程中增加动画和贴纸作用。

短视频编辑中的AVFoundation框架(一)框架概述与基础

而AVFoundation位于高层级结构和低层级结构之间,封装了低层级结构才能完成的功用,供给了OC和Swift语言的接口,同时苹果在迭代进程中不断优化AVFoundation这种中间层结构的性能,很好地支撑了新的设备和视频格局。

1.2 AVFoundation各模块简介

AVFoundation官方文档介绍:AVFoundation结构结合了六个首要技术范畴,这些范畴覆盖了在Apple平台上录制、处理、组成、操控、导入和导出视听媒体的首要功用。而API官方文档将AVFoundation分成了Assets媒体资源、Playback播映、Capture录制、Editing修正、Audio音频、Speech(语音播报)六个功用模块。

短视频编辑中的AVFoundation框架(一)框架概述与基础

  • Assets:供给加载、查看和导出媒体资源和元数据信息的功用,也能够运用AVAssetReaderAVAssetWriter对媒体样本数据进行样本级读写,运用AVAssetImageGenerator获取视频缩略图,运用AVCaption进行字幕创作(mac os)等。
  • Playback:供给对AVAsset的播映和播映操控的功用,能够运用AVPlayer播映一个项目,也能够运用AVQueuePlayer播映多个项目,AVSynchronizedLayer能够让咱们结合Core Animation将动画层与播映视图层进行同步,完成播映中的诸如贴纸、文字等作用。
  • Capture:用于拍照相片、录制音频和视频,经过装备内置摄像头和麦克风或外部录制设备,能够构建自界说相机功用,操控相片和视频拍照的输出格局,或许直接修正音视频数据流作为自界说输出。
  • Editing:用于将来自多个来源的音频和视频轨迹组合、修正和从头混合到一个AVMutableComposition中,能够运用AVAudioMixAVVideoComposition别离操控音频混合和视频组成的细节。
  • Audio:播映、录制和处理音频;装备应用程序的系统音频行为。苹果又在iOS14.5整合了一个AVFAudio结构,内容与这部分完全相同,或许未来会把音频部分单独处理。
  • Speech:将文本转化为语音音频进行朗读。

在短视频修正中,无论是修正所用的素材仍是修正中处理的半成品亦或是最终导出的成品,咱们都在跟AVAsset或其子类打交道,其所在的Assets模块作为AVFoundation媒体处理的根底是需求首要学习的内容。

二、 根底模块-Assets

2.1 AVAsset & AVAssetTrack

AVAsset是一个笼统类和不可变类,界说了媒体资源混合出现的方式,将媒体资源的静态特点模块化成一个整体。它供给了对基本媒体格局的笼统,这意味着无论是处理Quick Time Movie仍是MP3音频,对开发者和对结构其余部分而言,面临的只要资源这个概念。

AVAsset一般经过其子类AVURLAsset实例化,其间的参数”URL”能够来自远程或许本地甚至是流媒体,使咱们无须重视其来源,只须专注于处理AVAsset本身。

运用下面代码示例中的办法创立回来的都是AVURLAsset的实例。办法二中的options能够用来来自界说AVURLAsset的初始化以满意特定需求。例如,经过HLS流创立AVURLAsset,运用{AVURLAssetAllowsCellularAccessKey: @NO}作为options的参数,能够阻止在运用蜂窝网络时检索其媒体数据。而与视频修正密切相关的是AVURLAssetPreferPreciseDurationAndTimingKey,用于指示资源是否供给准确的”duration”值和准确的随机拜访,视频修正需求准确的值,建议运用”YES”,不过这种精度或许需求进行额定的解析而导致更长的加载时刻。

许多容器格局为准确计时供给了足够的摘要信息,并不需求额定的解析来预备,例如QuickTime Movie和MPEG-4文件。

AVAsset *asset = [AVAsset assetWithURL:url];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:@{AVURLAssetPreferPreciseDurationAndTimingKey: @YES}];

一个AVAsset实例是一个或多个AVAssetTrack实例的容器,该实例是对媒体的共同类型”轨迹”进行的建模。一个简单的视频文件一般包括一个音频轨迹和一个视频轨迹,也或许包括一些补充内容,如隐藏式字幕、字幕,也或许包括描绘媒体内容的元数据(AVMetadataItem)。

短视频编辑中的AVFoundation框架(一)框架概述与基础

隐藏式字幕即“Closed Caption”,简称CC字幕。大多数CC字幕和剧本是一样的,里边除了对白之外,还有场景中发生的声响和配乐等的描绘,首要是为了听障人士所设置的,“Closed”一词也阐明了并不是默许开启的状况,与之相对的是“Open Caption”,也便是一般所说的字幕,而与对话语言相同的字幕称为”Caption“,不同的(即翻译)称为“Subtitle”。

创立一个AVAsset是一个轻量级操作,由于AVAsset的底层媒体数据采用了推迟加载的设计,直到获取时才会进行加载,并且特点的获取是同步进行的,假如没有进行提前进行异步加载直接去拜访它的特点会堵塞调用线程,不过这也要取决于要拜访的媒体数据的巨细和方位。为了防止堵塞线程,咱们最好在运用之前进行异步加载特点。AVAsset和AVAssetTrack都遵循了AVAsynchronousKeyValueLoading协议,能够进行异步加载特点和获取加载状况。

@protocol AVAsynchronousKeyValueLoading
// 异步加载包括在keys数组中的特点,在handler中运用statusOfValueForKey:error:办法判别加载是否完成。
- (void)loadValuesAsynchronouslyForKeys:(NSArray<NSString *> *)keys completionHandler:(nullable void (^)(void))handler;
// 获取key特点加载的状况,status为AVKeyValueStatusLoaded为加载完成。
- (AVKeyValueStatus)statusOfValueForKey:(NSString *)key error:(NSError * _Nullable * _Nullable)outError;

WWDC2021What’s new in AVFoundation提到,针对swift API引入了async/await,让咱们得以运用与同步编程类似的操控流来进行异步编程。

let asset = AVAsset (url: assetURL)
let duration = trv await asset.load(.duration)
// 咱们也能够加载多个特点,运用元组接纳回来值:
let (duration, tracks) = try await asset.load(.duration, .tracks)

AVAsset的特点:

短视频编辑中的AVFoundation框架(一)框架概述与基础

代码示例中tracks特点回来的是一个AVAsset实例包括的所有AVAssetTrack实例的数组,苹果也供给了依据特定标准(如轨迹ID、媒体类型和特征)检索轨迹子集的办法如下,这也是修正模块中取出某种类型的轨迹常用的办法。

// 依据TrackID检索轨迹
- (void)loadTrackWithTrackID:(CMPersistentTrackID)trackID completionHandler:(void (^)(AVAssetTrack * _Nullable_result, NSError * _Nullable))completionHandler;
// 依据媒体类型检索轨迹子集
- (voidloadTracksWithMediaType:(AVMediaType)mediaType completionHandler:(void (^)(NSArray<AVAssetTrack *> * _Nullable NSError * _Nullable))completionHandler;
// 依据媒体特征检索轨迹子集
- (void)loadTracksWithMediaCharacteristic:(AVMediaCharacteristic)mediaCharacteristic completionHandler:(void (^)(NSArray<AVAssetTrack *> * _Nullable, NSError * _Nullable))completionHandler;

其间AVMediaType常用的有:音频AVMediaTypeAudio、视频AVMediaTypeVideo、字幕AVMediaTypeSubtitle、元数据AVMediaTypeMetadata等。

AVMediaCharacteristic用于界说媒体数据特征,例如是否包括HDR视频轨迹AVMediaCharacteristicContainsHDRVideo,是否包括可听内容AVMediaCharacteristicAudible等。

2.2 元数据

媒体容器格局存储关于其媒体的描绘性元数据,每种容器格局都有自己共同的元数据格局,AVFoundation经过运用其AVMetadataItem类简化了对元数据的处理,在最基本的方式中,AVMetadataItem的实例是一个键值对,表明单个元数据值,比方电影的标题或专辑的插图。

要高效地运用AVMetadataItem,咱们需求了解AVFoundation是怎么安排元数据的。为了简化元数据项的查找和过滤,AVFoundation结构将相关元数据分组到键空间中:

  • 特定格局的键空间。AVFoundation结构界说了几个特定格局的键空间,它们大致与特定容器或文件格局相关,例如 QuickTime(QuickTime 元数据和用户数据)或 MP3 (ID3)。可是,单个资源或许包括跨多个键空间的元数据值。要检索资源的特定格局元数据的完好调集,能够运用metadata特点。
  • Common键空间。有几个常见的元数据值,例如电影的创立日期或描绘,能够存在于多个键空间中。为了帮助规范化对这个公共元数据的拜访,该结构供给了一个common键空间,它答应拜访几个键空间共有的一组有限元数据值。要检索资源的公共元数据调集,能够直接运用commonMetadata特点。

除此之外,咱们还能够经过调用AVAssetavailableMetadataFormats特点来确认资源包括哪些元数据格局。此特点回来包括每个元数据格局的字符串标识符数组。然后运用它的metadataForFormat:办法,经过传递恰当的格局标识符来检索特定于格局的元数据值。

一个iPhone13 Pro拍照的HDR视频文件的元数据:

creationDate :  2022-03-01T18:16:17+0800
location : +39.9950+116.4749+044.903/
make: Apple
model:  iPhone 13 Pro
software: 15.3.1

尽管本系列文章旨在不过多重视音视频编解码格局,可是拿到一个视频文件(.mov),假如依然想获取视频样本的编码类型(h264/hevc)、转化函数(ITU_R_709_2/ITU_R_2100_HLG)等,获取音频样本的采样率、通道数、位深等格局信息,咱们应该从哪里入手呢?前面咱们介绍了在一个AVAsset资源中以轨迹(track)的方式把音频、视频等数据别离进行了单独的建模,假如要获取视频样本格局的信息,只要依据媒体类型检索相应的视频轨迹,获取assetTrack的formatDescriptions特点,即可拿到视频样本的格局信息CMVideoFormatDescription的调集,相同还有CMAudioFormatDescriptionCMClosedCaptionFormatDescription等用于描绘各自轨迹样本的数据格局。

// 获取数据样本格局信息
AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
NSArray *videoFormats = VideoTrack.formatDescriptions;

上述视频文件中的视频轨迹格局描绘信息如下:

"<CMVideoFormatDescription 0x2834305a0 [0x1dbce41b8]> {
	mediaType:'vide' 
	mediaSubType:'hvc1' 
	mediaSpecific: {
        codecType: 'hvc1'		
        dimensions: 1920 x 1080 
	} 
	extensions: {{
        AmbientViewingEnvironment = {length = 8, bytes = 0x002fe9a03d134042};
        BitsPerComponent = 10;
        CVFieldCount = 1;
        CVImageBufferChromaLocationBottomField = Left;
        CVImageBufferChromaLocationTopField = Left;
        CVImageBufferColorPrimaries = \"ITU_R_2020\";
        CVImageBufferTransferFunction = \"ITU_R_2100_HLG\";
        CVImageBufferYCbCrMatrix = \"ITU_R_2020\";
        Depth = 24;
        FormatName = HEVC;
        FullRangeVideo = 0;
        RevisionLevel = 0;
        SampleDescriptionExtensionAtoms =     {
        dvvC = {
            length = 24, 
            bytes = 0x010010254000000000000000000000000000000000000000
            };
        hvcC = {
            length = 125, 
            bytes = 0x01022000 0000b000 00000000 78f000fc ... 2fe9a03d 13404280 };
    };
        SpatialQuality = 512;
        TemporalQuality = 512;
        VerbatimSampleDescription = {
            length = 289, 
            bytes = 0x00000121 68766331 00000000 00000001 ... 3d134042 00000000 };
        Version = 0;
}}
}"

2.3 视频预览

在短视频修正中将播映导出前的视频资源称为预览,实际上播映归于AVFoundation中Playback模块的内容,可是本系列文章要点不在播映器上,咱们简单介绍一下预览AVAsset运用的类AVPlayer

AVPlayer的初始化需求一个AVPlayerItem目标,它用来办理资源目标,供给播映数据源的类,要播映一个视频,只运用AVPlayer的话,只要声响没有画面,要显现画面咱们还需求AVPlayerLayer

// 1.实例化AVAsset
AVAsset *asset = [AVAsset assetWithURL:url];
// 2.经过asset创立AVPlayerItem
AVPlayerItem* item = [[AVPlayerItem alloc] initWithAsset:asset];
// 3.创立AVPlayer
AVPlayer* player = [AVPlayer playerWithPlayerItem:item];
// 4.创立AVPlayerLayer用来显现视频
AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
// 5.将AVPlayerLayer增加到视图层级中
[self.view.layer addSublayer:playerLayer];
// 6.播映
[player play];

2.4 获取视频缩略图

一般在视频导出前会有一个选择视频封面的功用,该功用需求供给视频缩略图的列表,要获取视频的缩略图需求运用AVAssetImageGenerator,运用AVAsset实例创立 AVAssetImageGenerator目标的办法如下:

+ (instancetype)assetImageGeneratorWithAsset:(AVAsset *)asset;
- (instancetype)initWithAsset:(AVAsset *)asset;

假如需求准确时刻截图,能够运用按照如下办法将前后时刻容忍度设为kCMTimeZero,设置maximumSize特点能够指定截取画面的巨细。

// 准确时刻获取缩略图
imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
// 指定缩略图画面的巨细
imageGenerator.maximumSize = CGSizeMake(100, 100);

然后调用如下办法来获取某个时刻的缩略图,或许多个时刻的缩略图:

// 获取指定时刻requestedTime的视频缩略图
- (nullable CGImageRef)copyCGImageAtTime:(CMTime)requestedTime actualTime:(nullable CMTime *)actualTime error:(NSError * _Nullable * _Nullable)outError;
// 获取多个时刻的缩略图,每生成一张图片,都会调用一次handler
- (void)generateCGImagesAsynchronouslyForTimes:(NSArray<NSValue *> *)requestedTimes completionHandler:(AVAssetImageGeneratorCompletionHandler)handler;
// 上述办法的handler的类型界说,actualTime为缩略图所处的真实时刻
typedef void (^AVAssetImageGeneratorCompletionHandler)(CMTime requestedTime, CGImageRef _Nullable image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError * _Nullable error);

三、 常用数据类型

3.1 CMTime & CMTimeRange

在获取视频缩略图中咱们需求传入一个用于表明某个时刻的类型CMTime,一般咱们以为用于表明时刻的一般是NSTimeInterval(double类型),在AVFoundation中的AVAudioPlayerAVAudioRecorder处理时刻能够运用,可是浮点型的不准确性(简单的舍入就会导致丢帧),无法用于更多的高级时基媒体的开发中,所以Core Media供给了这样一个结构体来表明时刻:

typedef struct
{
   CMTimeValue    value;        
   CMTimeScale    timescale;
   CMTimeFlags    flags;
   CMTimeEpoch    epoch;
} CMTime;

其间CMTimeFlags是一个位掩码用于表明时刻的指定状况,例如判别数据是否有效,CMTimeEpoch表明纪元,一般是0。咱们要点重视表明时刻的CMTimeValue和CMTimeScale,一个CMTime表明的时刻 = value / timescale,timescale表明将时刻划分了多少份,value表明该时刻含有多少份,为满意大部分常用的视频频率24FPS、25FPS、30FPS,一般咱们会将timescale设为他们的公倍数600。

咱们能够运用如下办法创立一个CMTime:

CMTime time1 = CMTimeMake(3, 1); // 3 / 1 = 3s
CMTime time2 = CMTimeMakeWithSeconds(5, 1); 5s timescale = 1
NSDictionary *timeData = @{(id)kCMTimeValueKey : @2,
                           (id)kCMTimeScaleKey : @1,
                           (id)kCMTimeFlagsKey : @1,
                           (id)kCMTimeEpochKey : @0};
CMTime time3 = CMTimeMakeFromDictionary((__bridge CFDictionaryRef)timeData); 
// 特殊值
// 表明0时刻
CMTime time4 = kCMTimeZero; 
// 表明时刻不合法
CMTime time5 = kCMTimeInvalid; 

CMTime的运算:

// 加
CMTimeAdd(<#CMTime lhs#>, <#CMTime rhs#>)
// 减
CMTimeSubtract(<#CMTime lhs#>, <#CMTime rhs#>)
// 比较
CMTimeCompare(<#CMTime time1#>, <#CMTime time2#>)
// 校验
CMTIME_IS_VALID(<#time#>)
CMTIME_IS_INVALID(<#time#>)
// print
CMTimeShow(<#CMTime time#>)

CMTimeRange用于表明一个时刻规模,由两个CMTime值组成,第一个界说时刻规模的开始时刻,第二个界说时刻规模的持续时刻。

typedef struct
{
    CMTime          start;
    CMTime          duration;
} CMTimeRange;

咱们能够运用如下办法创立一个CMTimeRange:

CMTime beginTime = CMTimeMake(5, 1);
CMTime endTime = CMTimeMake(12, 1);
CMTimeRange timeRange1 = CMTimeRangeMake(beginTime, endTime);
CMTimeRange timeRange2 = CMTimeRangeFromTimeToTime(beginTime, endTime);
// 特殊值
// 表明0长度的时刻规模
CMTimeRange timeRange3 = kCMTimeRangeZero;
// 表明时刻规模不合法
CMTimeRange timeRange4 = kCMTimeRangeInvalid;

CMTimeRange的运算:

// 取两个CMTimeRange的交集
CMTimeRangeGetIntersection(<#CMTimeRange range#>, <#CMTimeRange otherRange#>)
// 取两个CMTimeRange的并集
CMTimeRangeGetUnion(<#CMTimeRange range#>, <#CMTimeRange otherRange#>)
// 是否包括某个时刻CMTime
CMTimeRangeContainsTime(<#CMTimeRange range#>, <#CMTime time#>)
// 是否包括某个时刻规模
CMTimeRangeContainsTimeRange(<#CMTimeRange range#>, <#CMTimeRange otherRange#>)
// 校验
CMTIMERANGE_IS_VALID(<#range#>)
CMTIMERANGE_IS_INVALID(<#range#>)
// print
CMTimeRangeShow(<#CMTimeRange range#>)

3.2 CMSampleBuffer

运用AVFoundation处理样本级的数据时要经常跟CMSampleBuffer打交道,例如AVFoundation的Capture模块相机采集的数据输出类型、AVAssetReaderAVAssetWriter读取和写入进程中操作的数据类型等。

CMSampleBuffer相同来自Core Media结构,它是系统用来经过媒体管道移动媒体样本数据的中心根底目标,CMSampleBuffer的人物是将根底的样本数据进行封装并供给格局描绘时刻信息

官方的文档介绍,它包括0个或多个特定媒体类型(音频、视频、混合等)的紧缩(或未紧缩)样本,CMSampleBuffer能够包括:

  • 样本数据。包括以下两者中的一个:

    • 一个或多个媒体样本的CMBlockBufferCMBlockBuffer为编码的数据,并未进行解码。
    • 一个或多个媒体样本的CVPixelBufferCVPixelBuffer为编码前或解码后的数据。
      短视频编辑中的AVFoundation框架(一)框架概述与基础
  • 时刻信息。CMSampleBuffer还包括表明当时样本的显现时刻(Presentation Time Stamp)的pts,表明样本的编码时刻(Decode Time Stamp)的dts,dts首要用于视频的解码,假如解码时刻与显现时刻顺序共同,其值能够设置为kCMTimeInvalid。能够别离运用CMSampleBufferGetPresentationTimeStampCMSampleBufferGetDecodeTimeStamp获取pts和dts。

  • 格局信息。格局信息封装在CMFormatDescription目标中。能够别离运用CMVideoFormatDescriptionGetCodecTypeCMVideoFormatDescriptionGetDimensions获取编码类型和视频尺寸。除此之外还能够运用CMGetAttachment检索字典获取元数据:

CFDictionaryRef metadataDictionary = CMGetAttachment(sampleBuffer, CFSTR("MetadataDictionary", NULL);

3.3 CVPixelBuffer

CVPixelBufferRef是像素缓冲区类型,像素缓冲区类型基于图画缓冲区类型,归于Core Video结构的数据类型。

typedef CVImageBufferRef CVPixelBufferRef;

CVPixelBufferRef里包括许多图片相关特点,比较重要的有widthheightPixelFormatType等。除了常见的RGB32以外,还能够支撑比方 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange这种YUV多平面的数据格局,经过CVPixelBufferGetBaseAddressOfPlane能够得到每个平面的数据指针。假如运用CPU拜访像素数据,在获取Address之前需求调用CVPixelBufferLockBaseAddress

CMSampleBuffer的一个实例在对应的CVPixelBuffer中包括了视频帧的数据。咱们能够运用CMSampleBufferGetImageBuffer获取:

CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(<#A CMSampleBuffer#>);

四、 注意事项

4.1 隐私权限

AVFoundation中的Capture模块触及运用设备的相机和麦克风,对图片与视频文件的读取与保存触及对用户相册的拜访,这些都被苹果列为用户的隐私权限,咱们需求在Xcode的info.plist增加响应的申请拜访权限阐明。下面列举了部分权限与其对应的key值。

隐私数据 key
相册(读权限) Privacy – Photo Library Usage Description
相册(写权限) Privacy – Photo Library Additions Usage Description
麦克风 Privacy – Microphone Usage Description
相机 Privacy – Camera Usage Description

4.2 装备AVAudioSession

iOS设备的音频环境相对mac os较为杂乱,苹果供给了AVAudioSession音频会话,在应用程序和操作系统之间扮演中间人的人物,咱们只需指明应用程序的音频行为即可将对音频行为的办理托付给AVAudioSession。默许的音频会话预装备了以下行为:

  • 支撑音频播映,但不答应录制音频。
  • 静音形式会使应用程序播映的任何音频静音。
  • 锁定设备会使app的音频静音。
  • 当应用程序播映音频时,它会使任何其他背景音频静音。 iOS供给六个Category可供选择:

AVAudioSessionCategoryAudioProcessing在iOS10.0现已抛弃。

Category 播映/录制 是否中止其他音频 静音或锁屏形式是否静音
SoloAmbient 仅播映
Ambient 仅播映
MultiRoute 播映和录制
PlayAndRecord 播映和录制 默许YES,能够重写为NO
Playback 仅播映 默许YES,能够重写为NO
Record 仅录制 否(锁屏下仍可录制,需求装备后台形式UIBackgroundModes)

除此之外,音频会话还供给了用于监听如电话呼入、闹钟响起引起的音频中止的通知AVAudioSessionInterruptionNotification,以及例如耳机插入造成的路由线路变更的通知AVAudioSessionRouteChangeReason

4.3 多线程

AVFoundation的构建考虑到了当时的硬件环境和应用程序,其设计进程高度依靠多线程机制。咱们在运用的进程中,要清晰所调用的API默许作业在哪个线程,或许需求作业在哪个线程,保证对UI的处理及时回到主线程来进行,防止耗时的操作堵塞主线程。

总结

本篇作为AVFoundation系列文章的开篇,首要介绍了AVFoundation的概述和各模块的基本功用,之后经过AVAssets模块的学习咱们建立了一个从轨迹(track)的视点看待音视频文件的视界,了解了常用的数据类型以及运用AVFoundation的注意事项。下一篇咱们将从短视频修正第一步素材的增加与处理方面介绍AVFoundation结构供给的支撑。

参考链接

AVFoundation AVAudioSession音频会话 CMSampleBuffer