AVURLAsset получение размера видео

Это довольно неприятно. Я пытаюсь получить размер AVURLasset, но стараюсь избегать naturalSize поскольку Xcode говорит мне, это устарело в iOS5.

но: какая замена?

Я не могу найти никаких подсказок о том, как получить видео-Размеры без использования "naturalsize"...

6 ответов


Я только что проверил документацию в интернете, и naturalSize метод устарел для объекта AVAsset. Однако всегда должен быть AVAssetTrack, который ссылается на AVAsset, и AVAssetTrack имеет naturalSize метод, который можно назвать.

naturalSize

естественные размеры медиаданных, на которые ссылается трек. (только для чтения)

@property (неатомный, только для чтения) CGSize naturalSize

в наличии

доступно в iOS 4.0 и более поздних версиях. Объявлено В AVAssetTrack.h

Via:ссылка AVAssetTrack для iOS


на предупреждение об устаревании официальной документации предлагает: "используйте naturalSize и preferredTransform, при необходимости, видеодорожек актива (см. также tracksWithMediaType:)."

Я изменил мой код:

CGSize size = [movieAsset naturalSize];

to

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

теперь это менее красиво и менее безопасно, но не сломается, когда они отбросят этот метод.


разрешение в 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))
}

Для 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))
}

решения без preferredTransform не возвращают правильные значения для некоторых видео на новейших устройств!


предупреждение об осуждении гласит:

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

поэтому нам нужен AVAssetTrack, а мы хотим ее naturalSize и preferredTransform. К этому можно получить доступ со следующим:

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

актив - это очевидно, ваше AVAsset.


чтобы получить размерность AVAsset, вы должны вычислить объединение всех визуальных дорожек rects (после применения их соответствующего предпочтительного преобразования):

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;

методы, которые полагаются на CGSizeApplyAffineTransform сбой, когда ваш актив содержит треки с нетривиальным аффинным преобразованием (например, повороты на 45 градусов) или если ваш актив содержит треки с различным происхождением (например, два трека, играющие бок о бок с началом второго трека, увеличенным на ширину первого дорожка.)

посмотреть: MediaPlayerPrivateAVFoundationCF::sizeChanged()at https://opensource.apple.com/source/WebCore/WebCore-7536.30.2/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp


Это довольно простое расширение для AVAsset на Swift 4 чтобы получить размер видео, Если доступно:

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
    }
}