— 第2章：Using Assets - 使用Assets
— 第3章：Playback - 播放
— 第4章：Editing - 编辑
— 第5章：Still and Video Media Capture - 静态视频媒体捕获
— 第6章：Export - 输出
— 第7章：Time and Media Representations 时间和媒体表现

CSDN博客：

— 第2章：Using Assets - 使用Assets
— 第3章：Playback - 播放
— 第4章：Editing - 编辑
— 第5章：Still and Video Media Capture - 静态视频媒体捕获
— 第6章：Export - 输出
— 第7章：Time and Media Representations 时间和媒体表现

# Time and Media Representations - 时间和媒体表现

Time-based audiovisual data, such as a movie file or a video stream, is represented in the AV Foundation framework by AVAsset. Its structure dictates much of the framework works. Several low-level data structures that AV Foundation uses to represent time and media such as sample buffers come from the Core Media framework.

## Representation of Assets - 资产的表示

AVAsset is the core class in the AV Foundation framework. It provides a format-independent abstraction of time-based audiovisual data, such as a movie file or a video stream. The primary relationships are shown in Figure 6-1. In many cases, you work with one of its subclasses: You use the composition subclasses when you create new assets (see Editing), and you use AVURLAsset to create a new asset instance from media at a given URL (including assets from the MPMedia framework or the Asset Library framework—see Using Assets).

AVAssetAV Foundation 框架的核心类。它提供了一个格式 — 与基于时间的视听数据的抽象无关，比如电影文件或视频流。主要的关系如图 6-1所示。在很多情况下，你都与它的一个子类一起工作：当你创建新的资产（见 Editing）使用组件的子类，并使用 AVURLAsset 从给定 URL 的媒体来创建一个新的资产实例。（包括来自 MPMedia 框架或者 Asset Library framework 的资产，见Using Assets

![Figure 6-1 AVAsset provides an abstraction of time-based audiovisual data](http://ww1.sinaimg.cn/large/a9c4d5f6gw1f6kx28dgzuj20lc0cojri.jpg)

An asset contains a collection of tracks that are intended to be presented or processed together, each of a uniform media type, including (but not limited to) audio, video, text, closed captions, and subtitles. The asset object provides information about whole resource, such as its duration or title, as well as hints for presentation, such as its natural size. Assets may also have metadata, represented by instances of AVMetadataItem.

A track is represented by an instance of AVAssetTrack, as shown in Figure 6-2. In a typical simple case, one track represents the audio component and another represents the video component; in a complex composition, there may be multiple overlapping tracks of audio and video.

![Figure 6-2 AVAssetTrack](http://ww3.sinaimg.cn/large/a9c4d5f6gw1f6kxhx9jerj20n009f0st.jpg)

A track has a number of properties, such as its type (video or audio), visual and/or audible characteristics (as appropriate), metadata, and timeline (expressed in terms of its parent asset). A track also has an array of format descriptions. The array contains CMFormatDescription objects (see CMFormatDescriptionRef), each of which describes the format of media samples referenced by the track. A track that contains uniform media (for example, all encoded using to the same settings) will provide an array with a count of 1.

A track may itself be divided into segments, represented by instances of AVAssetTrackSegment. A segment is a time mapping from the source to the asset track timeline.

# Representations of Time - 时间的表示

Time in AV Foundation is represented by primitive structures from the Core Media framework.

AV Foundation 中的时间是由来自 Core Media framework 的原始结构体表示的。

### CMTime Represents a Length of Time - CMTime 表示时间的长度

CMTime is a C structure that represents time as a rational number, with a numerator (an int64_t value), and a denominator (an int32_t timescale). Conceptually, the timescale specifies the fraction of a second each unit in the numerator occupies. Thus if the timescale is 4, each unit represents a quarter of a second; if the timescale is 10, each unit represents a tenth of a second, and so on. You frequently use a timescale of 600, because this is a multiple of several commonly used frame rates: 24 fps for film, 30 fps for NTSC (used for TV in North America and Japan), and 25 fps for PAL (used for TV in Europe). Using a timescale of 600, you can exactly represent any number of frames in these systems.

CMTime 是一个C语言的结构体，以一个有理数表示时间，有一个分子（一个 int64_t 值）和一个分母（一个 int32_t 时间刻度）。在概念上讲，时间刻度指定一秒中每个单元占据的分数。因此如果时间刻度为 4，每个单元代表一秒的四分之一；如果时间刻度为 10，每个单元代表一秒的十分之一，等等。经常使用时间刻度为 600，因为这是因为这是几种常用帧速率的倍数：24 fps的电影， 30 fpsNTSC（用在北美洲和日本的电视），25 fpsPAL（用于欧洲电视）。使用 600的时间刻度，可以在这些系统中精确的表示任意数量的帧。

In addition to a simple time value, a CMTime structure can represent nonnumeric values: +infinity, -infinity, and indefinite. It can also indicate whether the time been rounded at some point, and it maintains an epoch number.

#### Using CMTime - 使用 CMTime

You create a time using CMTimeMake or one of the related functions such as CMTimeMakeWithSeconds (which allows you to create a time using a float value and specify a preferred timescale). There are several functions for time-based arithmetic and for comparing times, as illustrated in the following example:

For a list of all the available functions, see CMTime Reference.

#### Special Values of CMTime - CMTime 的特殊值

Core Media provides constants for special values: kCMTimeZero, kCMTimeInvalid, kCMTimePositiveInfinity, and kCMTimeNegativeInfinity. There are many ways in which a CMTime structure can, for example, represent a time that is invalid. To test whether a CMTime is valid, or a nonnumeric value, you should use an appropriate macro, such as CMTIME_IS_INVALID, CMTIME_IS_POSITIVE_INFINITY, or CMTIME_IS_INDEFINITE.

Core Media 提供了特殊值的常量：kCMTimeZerokCMTimeInvalidkCMTimePositiveInfinity，以及 kCMTimeNegativeInfinity。有许多方法，例如，其中 CMTime 结构体可以表示一个无效的时间。为了测试CMTime 是否是无效的，或者是一个非数字值，应该使用一个适当的宏，比如 CMTIME_IS_INVALIDCMTIME_IS_POSITIVE_INFINITY，或者 CMTIME_IS_INDEFINITE

You should not compare the value of an arbitrary CMTime structure with kCMTimeInvalid.

#### Representing CMTime as an Object - CMTime表示为一个对象

If you need to use CMTime structures in annotations or Core Foundation containers, you can convert a CMTime structure to and from a CFDictionary opaque type (see CFDictionaryRef) using the CMTimeCopyAsDictionary and CMTimeMakeFromDictionary functions, respectively. You can also get a string representation of a CMTime structure using the CMTimeCopyDescription function.

#### Epochs - 纪元

The epoch number of a CMTime structure is usually set to 0, but you can use it to distinguish unrelated timelines. For example, the epoch could be incremented through each cycle using a presentation loop, to differentiate between time N in loop 0 and time N in loop 1.

CMTime 结构体的纪元数量通常设置为 0，但是你可以用它来区分不相关的时间轴。例如，纪元可以通过使用演示循环每个周期递增，区分循环0中的时间 N与循环1中的时间 N

### CMTimeRange Represents a Time Range - CMTimeRange表示一个时间范围

CMTimeRange is a C structure that has a start time and duration, both expressed as CMTime structures. A time range does not include the time that is the start time plus the duration.

You create a time range using CMTimeRangeMake or CMTimeRangeFromTimeToTime. There are constraints on the value of the CMTime epochs:

• CMTimeRange structures cannot span different epochs.
• The epoch in a CMTime structure that represents a timestamp may be nonzero, but you can only - perform range operations (such as CMTimeRangeGetUnion) on ranges whose start fields have the - same epoch.
• The epoch in a CMTime structure that represents a duration should always be 0, and the value must be nonnegative.

CMTimeRange 是一个 C语言结构体，有开始时间和持续时间，即表示为 CMTime 结构体。时间范围不包括开始时间加上持续时间。

• CMTimeRange 结构体不能跨越不同的纪元。
• CMTime 结构体中的纪元，表示一个时间戳可能是非零，但你只能在其开始字段具有相同纪元的范围内执行范围操作（比如 CMTimeRangeGetUnion）。
• CMTime 结构体中的纪元，表示持续时间应该总是为 0，并且值必须是非负数。

#### Working with Time Ranges - 与时间范围工作

Core Media provides functions you can use to determine whether a time range contains a given time or other time range, to determine whether two time ranges are equal, and to calculate unions and intersections of time ranges, such as CMTimeRangeContainsTime, CMTimeRangeEqual, CMTimeRangeContainsTimeRange, and CMTimeRangeGetUnion.

Core Media 提供了一些功能，可用于确定一个时间范围是否包含一个特定的时间或其他时间范围，确定两个时间范围是否相等，并计算时间范围的接口和相交范围，比如 CMTimeRangeContainsTimeCMTimeRangeEqualCMTimeRangeContainsTimeRange，以及 CMTimeRangeGetUnion

Given that a time range does not include the time that is the start time plus the duration, the following expression always evaluates to false:

For a list of all the available functions, see CMTimeRange Reference.

#### Special Values of CMTimeRange - CMTimeRange 的特殊值

Core Media provides constants for a zero-length range and an invalid range, kCMTimeRangeZero and kCMTimeRangeInvalid, respectively. There are many ways, though in which a CMTimeRange structure can be invalid, or zero—or indefinite (if one of the CMTime structures is indefinite. If you need to test whether a CMTimeRange structure is valid, zero, or indefinite, you should use an appropriate macro: CMTIMERANGE_IS_VALID, CMTIMERANGE_IS_INVALID, CMTIMERANGE_IS_EMPTY, or CMTIMERANGE_IS_EMPTY.

Core Media 分别提供一个长度为0的范围和一个无效范围，就是kCMTimeRangeZerokCMTimeRangeInvalid。有很多种方法，尽管 CMTimeRange 结构可以是无效的，或为零，或是不确定的（如果CMTime 结构是不确定的）。如果你需要测试 CMTimeRange 结构体是否是有效的，零，或者不确定，你应该使用适当的宏：CMTIMERANGE_IS_VALIDCMTIMERANGE_IS_INVALIDCMTIMERANGE_IS_EMPTY，或者 CMTIMERANGE_IS_INDEFINITE

You should not compare the value of an arbitrary CMTimeRange structure with kCMTimeRangeInvalid.

#### Representing a CMTimeRange Structure as an Object - 将 CMTimeRange 结构体表示为对象

If you need to use CMTimeRange structures in annotations or Core Foundation containers, you can convert a CMTimeRange structure to and from a CFDictionary opaque type (see CFDictionaryRef) using CMTimeRangeCopyAsDictionary and CMTimeRangeMakeFromDictionary, respectively. You can also get a string representation of a CMTime structure using the CMTimeRangeCopyDescription function.

## Representations of Media - 媒体的表示

Video data and its associated metadata are represented in AV Foundation by opaque objects from the Core Media framework. Core Media represents video data using CMSampleBuffer (see CMSampleBufferRef). CMSampleBuffer is a Core Foundation-style opaque type; an instance contains the sample buffer for a frame of video data as a Core Video pixel buffer (see CVPixelBufferRef). You access the pixel buffer from a sample buffer using CMSampleBufferGetImageBuffer:

From the pixel buffer, you can access the actual video data. For an example, see Converting CMSampleBuffer to a UIImage Object.

In addition to the video data, you can retrieve a number of other aspects of the video frame:

• Timing information. You get accurate timestamps for both the original presentation time and - the decode time using CMSampleBufferGetPresentationTimeStamp and - CMSampleBufferGetDecodeTimeStamp respectively.
• Format information. The format information is encapsulated in a CMFormatDescription object (- see CMFormatDescriptionRef). From the format description, you can get for example the pixel - type and video dimensions using CMVideoFormatDescriptionGetCodecType and - CMVideoFormatDescriptionGetDimensions respectively.
• Metadata. Metadata are stored in a dictionary as an attachment. You use CMGetAttachment to retrieve the dictionary:

## Converting CMSampleBuffer to a UIImage Object - 将 CMSampleBuffer 转化为 UIImage 对象

The following code shows how you can convert a CMSampleBuffer to a UIImage object. You should consider your requirements carefully before using it. Performing the conversion is a comparatively expensive operation. It is appropriate to, for example, create a still image from a frame of video data taken every second or so. You should not use this as a means to manipulate every frame of video coming from a capture device in real time.