0%

问题

适配 iPhone X 的过程中发现 prefersHomeIndicatorAutoHidden 不起作用。

原因

keyWindow 之上还有一个 window。
并且大小为 [UIScreen mainScreen].bounds

解决方案

大小修改为 CGRectInset([UIScreen mainScreen].bounds, 0, 1) 就不会影响 prefersHomeIndicatorAutoHidden 生效。

因为 prefersHomeIndicatorAutoHidden 的实现原理不明,解决方案有效性待观察。

CGAffineTransform 定义

从 AVAssetTrack 中可以获取两个信息:视频尺寸& transform:

/* indicates the natural dimensions of the media data referenced by the track as a CGSize */
@property (nonatomic, readonly) CGSize naturalSize;
/* indicates the transform specified in the track's storage container as the preferred transformation of the visual media data for display purposes;
its value is often but not always CGAffineTransformIdentity */
@property (nonatomic, readonly) CGAffineTransform preferredTransform;

视频中存储的信息

一般的对于一个播放的时候是竖着视频(如下)来说
图片2

他存储的可能是一个横着的图像+旋转信息
图片2

阅读全文 »

在模拟器上不起作用

AVVideoCompositionCoreAnimationTool 在模拟器上似乎无法被正常渲染。只能渲染出一个背景色(摊手)

自定义 AVVideoCompositionInstruction 下如果需要使用

那么需要把 enablePostProcessing 参数设为 YES。

坐标系

转化的问题:

动画时间坐标与视频时间坐标不一样

Use this constant to set the CoreAnimation’s animation beginTime property to be time 0.
The constant is a small, non-zero, positive value which prevents CoreAnimation from replacing 0.0 with CACurrentMediaTime.

removedOnCompletion 属性

默认情况下,动画完成后,为提高性能,图层会把动画移除,这样动画的时间一旦过去就无法返回了,但这种逻辑不符合视频动画:因为可能会重新播放等,所以 removedOnCompletion 必须置为NO

添加的 layer 的对渲染树有要求

The videoLayer should be in the animationLayer sublayer tree. The animationLayer should not come from, or be added to, another layer tree.

+(instancetype)videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:(CALayer *)videoLayer inLayer:(CALayer *)animationLayer;

尝试获取动画对应的图像遇到的问题

+ (instancetype)videoCompositionCoreAnimationToolWithAdditionalLayer:(CALayer *)layer asTrackID:(CMPersistentTrackID)trackID;

可以通过这个 API 把 Core Animation 加到一个空的轨道里面。
但是开发阶段,我自己写了一个 AVVideoCompositing,尝试通过 AVAsynchronousVideoCompositionRequest 的

- (nullable CVPixelBufferRef)sourceFrameByTrackID:(CMPersistentTrackID)trackID CF_RETURNS_NOT_RETAINED;

去获取 animation 动画的画面的时候,发现背景色是黑色的,不是不透明的,因此导致我把从其他轨道中获取的图片与动画图片进行合成的时候,这就出问题了。

当时的解决方案:
因为现在水印什么都是白色的,先用一个 CIFilter 把除了白色的部分都过滤掉,然后把处理后的 CIImage 和其他图片进行合成,效果喜人……

其实只需要把 AVVideoCompositionInstruction 的 enablePostProcessing 参数设为 YES。那就不需要通过 sourceFrameByTrackID 去把动画取出来,系统默认会帮你合成

这个 api 只会作用在一个轨道上

AVFoundation calls your applier block once for each frame to be displayed (or processed for export) from the asset’s first enabled video track. In that block, you access the video frame and return a filtered result using the provided

如果你希望实现多轨道的视频合成效果,可能需要自己写一个视频合成器(AVVideoCompositing)了

@interface AVVideoComposition : NSObject <NSCopying, NSMutableCopying> 
/* Indicates instructions for video composition via an NSArray of instances of classes implementing the AVVideoCompositionInstruction protocol.
   For the first instruction in the array, timeRange.start must be less than or equal to the earliest time for which playback or other processing will be attempted
   (note that this will typically be kCMTimeZero). For subsequent instructions, timeRange.start must be equal to the prior instruction's end time. The end time of
   the last instruction must be greater than or equal to the latest time for which playback or other processing will be attempted (note that this will often be
   the duration of the asset with which the instance of AVVideoComposition is associated).
*/
@property (nonatomic, readonly, copy) NSArray<id <AVVideoCompositionInstruction>> *instructions;

第一个 instruction 的 timeRange.start 必须比 composition 的开始时间要早(或者相同)。
接下来的相邻的 instruction 的 timeRange.start 和 timeRange.end 必须相同。
最后一个 instruction 的 timeRange.end 必须比 composition 的结束时间要迟(或者相同)。

阅读全文 »