iOS 13 上的 AVAssetReferenceRestrictions

AVAssetReferenceRestrictions on iOS 13

Workspace: iOS 13.0, Xcode 11.0

TL;DR:iOS13 中的 AVAssetReferenceRestrictions 有问题吗?

第 1 部分:

AVAsset.h中,AVAssetReferenceRestrictions定义为:

  @enum         AVAssetReferenceRestrictions
  @abstract     These constants can be passed in to AVURLAssetReferenceRestrictionsKey to control the resolution of references to external media data.

  @constant     AVAssetReferenceRestrictionForbidNone
    Indicates that all types of references should be followed.
  @constant     AVAssetReferenceRestrictionForbidRemoteReferenceToLocal
    Indicates that references from a remote asset (e.g. referenced via http URL) to local media data (e.g. stored in a local file) should not be followed.
  @constant     AVAssetReferenceRestrictionForbidLocalReferenceToRemote
    Indicates that references from a local asset to remote media data should not be followed.
  @constant     AVAssetReferenceRestrictionForbidCrossSiteReference
    Indicates that references from a remote asset to remote media data stored at a different site should not be followed.
  @constant     AVAssetReferenceRestrictionForbidLocalReferenceToLocal
    Indicates that references from a local asset to local media data stored outside the asset's container file should not be followed.
  @constant     AVAssetReferenceRestrictionForbidAll
    Indicates that only references to media data stored within the asset's container file should be allowed.
*/
typedef NS_OPTIONS(NSUInteger, AVAssetReferenceRestrictions) {
    AVAssetReferenceRestrictionForbidNone = 0UL,
    AVAssetReferenceRestrictionForbidRemoteReferenceToLocal = (1UL << 0),
    AVAssetReferenceRestrictionForbidLocalReferenceToRemote = (1UL << 1),
    AVAssetReferenceRestrictionForbidCrossSiteReference = (1UL << 2),
    AVAssetReferenceRestrictionForbidLocalReferenceToLocal = (1UL << 3),
    AVAssetReferenceRestrictionForbidAll = 0xFFFFUL,

    AVAssetReferenceRestrictionDefaultPolicy = AVAssetReferenceRestrictionForbidLocalReferenceToRemote
};

AVAsset 的 属性 定义为:

@property       referenceRestrictions
@abstract       Indicates the reference restrictions being used by the receiver.
@discussion
    For AVURLAsset, this property reflects the value passed in for AVURLAssetReferenceRestrictionsKey, if any. See AVURLAssetReferenceRestrictionsKey below for a full discussion of reference restrictions. The default value for this property is AVAssetReferenceRestrictionForbidNone.
@property (nonatomic, readonly) AVAssetReferenceRestrictions referenceRestrictions API_AVAILABLE(macos(10.7), ios(5.0), tvos(9.0)) API_UNAVAILABLE(watchos);

因此,尽管 属性 上的文档明确表示默认值为 AVAssetReferenceRestrictionForbidNone,但 AVAssetReferenceRestrictionDefaultPolicy 当前为 AVAssetReferenceRestrictionForbidLocalReferenceToRemote。文档是否未正确更新,或者 AVAssetReferenceRestrictionDefaultPolicy 与我预期的有所不同?

第 2 部分:

在Swift对应物中,它被定义(转换?)如下:

  @enum         AVAssetReferenceRestrictions
  @abstract     These constants can be passed in to AVURLAssetReferenceRestrictionsKey to control the resolution of references to external media data.

  @constant     AVAssetReferenceRestrictionForbidNone
    Indicates that all types of references should be followed.
  @constant     AVAssetReferenceRestrictionForbidRemoteReferenceToLocal
    Indicates that references from a remote asset (e.g. referenced via http URL) to local media data (e.g. stored in a local file) should not be followed.
  @constant     AVAssetReferenceRestrictionForbidLocalReferenceToRemote
    Indicates that references from a local asset to remote media data should not be followed.
  @constant     AVAssetReferenceRestrictionForbidCrossSiteReference
    Indicates that references from a remote asset to remote media data stored at a different site should not be followed.
  @constant     AVAssetReferenceRestrictionForbidLocalReferenceToLocal
    Indicates that references from a local asset to local media data stored outside the asset's container file should not be followed.
  @constant     AVAssetReferenceRestrictionForbidAll
    Indicates that only references to media data stored within the asset's container file should be allowed.

public struct AVAssetReferenceRestrictions : OptionSet {

    public init(rawValue: UInt)

    public static var forbidRemoteReferenceToLocal: AVAssetReferenceRestrictions { get }

    public static var forbidLocalReferenceToRemote: AVAssetReferenceRestrictions { get }

    public static var forbidCrossSiteReference: AVAssetReferenceRestrictions { get }

    public static var forbidLocalReferenceToLocal: AVAssetReferenceRestrictions { get }

    public static var forbidAll: AVAssetReferenceRestrictions { get }

    public static var defaultPolicy: AVAssetReferenceRestrictions { get }
}

这里没有选项AVAssetReferenceRestrictionForbidNone。但是文档明确表示是这样的。那么,到底是谁的错,还是我这边的误会?

第 3 部分:我是如何在这里结束的?

I've had to examine these because we were able to select a video from UIImagePickerController, then export it in AVURLAsset form to use in AVAssetExportSession. Everything was fine, it was working seamlessly until iOS 13.0. The feature works in the devices with iOS 12.4.1 and below.

The usage of AVAssetReferenceRestrictions is in the initializer of the AVURLAsset, and I believe that the default value has changed and it doesn't let us export anymore.

这不是你的错。

直到 2019-06-19,在 Apple referenceRestrictions documentation 中,默认值为 forbidNone:

The default value for this property is forbidNone . See AVURLAssetReferenceRestrictionsKey for a full discussion of reference restrictions.

后来,此页面更改为this

The default value for this property is defaultPolicy. See AVURLAssetReferenceRestrictionsKey for a full discussion of reference restrictions.

默认策略现在是 forbidLocalReferenceToRemote,仅在 iOS 13.

中可用

然而,我们有这段:

For AVURLAsset, this property reflects the value passed in for AVURLAssetReferenceRestrictionsKey, if any.

所以,显然,不传递 restrictionKey 应该与 forbidNone 相同。

你试过吗?

let asset = AVURLAsset(url: url, options: nil)