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

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

Но: Что замена?

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

Ответы

Ответ 1

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

naturalSize

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

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

Доступность

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

Через: Ссылка на AVAssetTrack для iOS

Ответ 2

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

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

CGSize size = [movieAsset naturalSize];

к

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

Теперь он менее симпатичный и менее безопасный, но не будет ломаться, когда он откажется от этого метода.

Ответ 3

Разрешение в Swift:

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

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

Ответ 4

Предупреждение об отказе говорит:

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.

Ответ 5

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

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() в https://opensource.apple.com/source/WebCore/WebCore-7536.30.2/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp

Ответ 6

Это довольно простое расширение для 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
    }
}