AVURLAsset getting video size

前端 未结 7 1824
礼貌的吻别
礼貌的吻别 2020-12-03 16:57

This is pretty frustrating. I\'m trying to get the size of an AVURLasset, but try to avoid naturalSize since Xcode tells me, this is deprecated in iOS5.

<
相关标签:
7条回答
  • 2020-12-03 17:17

    The deprecation warning on the official documentation suggests, "Use the naturalSize and preferredTransform, as appropriate, of the asset’s video tracks instead (see also tracksWithMediaType:)."

    I changed my code from:

    CGSize size = [movieAsset naturalSize];
    

    to

    CGSize size = [[[movieAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize];
    

    It's less pretty and less safe now but won't break when they drop that method.

    0 讨论(0)
  • 2020-12-03 17:18

    To derive the dimension of an AVAsset, you should calculate the union of all the visual track rects (after applying their corresponding preferred transformation):

    CGRect unionRect = CGRectZero;
    for (AVAssetTrack *track in [asset tracksWithMediaCharacteristic:AVMediaCharacteristicVisual]) {
        CGRect trackRect = CGRectApplyAffineTransform(CGRectMake(0.f,
                                                                 0.f,
                                                                 track.naturalSize.width,
                                                                 track.naturalSize.height),
                                                      track.preferredTransform);
        unionRect = CGRectUnion(unionRect, trackRect);
    }
    CGSize naturalSize = unionRect.size;
    

    Methods that rely on CGSizeApplyAffineTransform fail when your asset contains tracks with non-trivial affine transformation (e.g., 45 degree rotations) or if your asset contains tracks with different origins (e.g., two tracks playing side-by-side with the second track's origin augmented by the width of the first track).

    See: MediaPlayerPrivateAVFoundationCF::sizeChanged()at https://opensource.apple.com/source/WebCore/WebCore-7536.30.2/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp

    0 讨论(0)
  • 2020-12-03 17:22

    Resolution in Swift 3:

    func resolutionSizeForLocalVideo(url:NSURL) -> CGSize? {
        guard let track = AVAsset(URL: url).tracksWithMediaType(AVMediaTypeVideo).first else { return nil }
        let size = CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform)
        return CGSize(width: fabs(size.width), height: fabs(size.height))
    }
    

    For Swift 4:

    func resolutionSizeForLocalVideo(url:NSURL) -> CGSize? {
        guard let track = AVAsset(url: url as URL).tracks(withMediaType: AVMediaType.video).first else { return nil }
        let size = track.naturalSize.applying(track.preferredTransform)
        return CGSize(width: fabs(size.width), height: fabs(size.height))
    }
    

    Solutions without preferredTransform do not return correct values for some videos on the latest devices!

    0 讨论(0)
  • 2020-12-03 17:22

    The deprecation warning says:

    Use the naturalSize and preferredTransform, as appropriate, 
    of the asset’s video tracks instead (see also tracksWithMediaType:).
    

    So we need an AVAssetTrack, and we want its naturalSize and preferredTransform. This can be accessed with the following:

    AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
    CGSize dimensions = CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform);
    

    asset is obviously your AVAsset.

    0 讨论(0)
  • 2020-12-03 17:31

    I just checked the documentation online, and the naturalSize method is deprecated for the AVAsset object. However, there should always be an AVAssetTrack which refers to the AVAsset, and the AVAssetTrack has a naturalSize method that you can call.

    naturalSize

    The natural dimensions of the media data referenced by the track. (read-only)

    @property(nonatomic, readonly) CGSize naturalSize

    Availability

    Available in iOS 4.0 and later. Declared In AVAssetTrack.h

    Via: AVAssetTrack Reference for iOS

    0 讨论(0)
  • 2020-12-03 17:31

    This is a fairly simple extension for AVAsset in Swift 4 to get the size of the video, if available:

    extension AVAsset {
        var screenSize: CGSize? {
            if let track = tracks(withMediaType: .video).first {
                let size = __CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform)
                return CGSize(width: fabs(size.width), height: fabs(size.height))
            } 
            return nil
        }
    }
    
    0 讨论(0)
提交回复
热议问题