29

这很令人沮丧。我正在尝试获取 AVURLasset 的大小,但尽量避免,naturalSize因为 Xcode 告诉我,这在 iOS5 中已被弃用。

但是:替代品是什么?

我找不到任何关于如何在不使用«naturalsize»的情况下获得视频尺寸的线索......

4

7 回答 7

46

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

对于斯威夫特 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为最新设备上的某些视频返回正确的值!

于 2015-12-18T22:36:00.640 回答
34

我刚刚在线查看了文档,并且该naturalSize方法已被 AVAsset 对象弃用。但是,应该始终有一个 AVAssetTrack 引用 AVAsset,并且 AVAssetTrack 有一个naturalSize您可以调用的方法。

自然尺寸

轨道引用的媒体数据的自然维度。(只读)

@property(nonatomic, readonly) CGSize naturalSize

可用性

在 iOS 4.0 及更高版本中可用。在 AVAssetTrack.h 中声明

通过:iOS 的 AVAssetTrack 参考

于 2012-05-03T16:17:37.403 回答
26

官方文档中的弃用警告建议,“酌情使用资产视频轨道的naturalSizeand preferredTransform(另请参阅tracksWithMediaType:)。”

我改变了我的代码:

CGSize size = [movieAsset naturalSize];

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

它现在不那么漂亮和不安全了,但是当他们放弃该方法时不会破坏。

于 2013-08-20T00:16:00.953 回答
17

弃用警告说:

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

所以我们需要一个AVAssetTrack,我们想要它的naturalSizepreferredTransform。这可以通过以下方式访问:

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

资产显然是你的AVAsset

于 2015-01-07T19:55:41.197 回答
4

这是Swift 4AVAsset中一个相当简单的扩展,用于获取视频的大小(如果可用):

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
    }
}
于 2018-01-20T21:45:30.420 回答
3

要导出 的维度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 度旋转)或您的资产包含具有不同来源的轨道(例如,两个轨道并排播放而第二个轨道的原点增加了第一条轨道的宽度)。

请参阅:httpsMediaPlayerPrivateAVFoundationCF::sizeChanged() : //opensource.apple.com/source/WebCore/WebCore-7536.30.2/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp

于 2017-03-10T01:21:41.953 回答
2

对于斯威夫特 5

  let assetSize =  asset.tracks(withMediaType: .video)[0].naturalSize
于 2020-08-17T12:39:31.057 回答