【问题标题】:AVURLAsset getting video sizeAVURLAsset 获取视频大小
【发布时间】:2012-05-13 02:37:35
【问题描述】:

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

但是:替换的是什么?

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

【问题讨论】:

    标签: xcode ios5 avurlasset


    【解决方案1】:

    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 的解决方案不会为最新设备上的某些视频返回正确的值!

    【讨论】:

      【解决方案2】:

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

      naturalSize

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

      @property(nonatomic, readonly) CGSize naturalSize

      可用性

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

      通过:AVAssetTrack Reference for iOS

      【讨论】:

      • nautralSize 在 iOS 5 中已弃用
      • 刚刚检查了答案中链接中的文档,它没有被弃用,它在 ObjC 和 Swift 中都可用
      • 文档中有 2 个naturalSizeAVURLAsset.naturalSize 已弃用,但 [[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize] 不是
      • 我的答案指定了 AVAssetTrack 方法,该方法未被弃用,并且是 Dave 在下面的第二行代码中指定的...看来我只是没有添加代码行我的回答。
      • Sooo 每个人都转而做与不推荐使用的方法基本相同的事情。太好了。
      【解决方案3】:

      deprecation warning on the official documentation 建议“酌情使用资产视频轨道中的naturalSizepreferredTransform(另请参阅tracksWithMediaType:)。”

      我将代码更改为:

      CGSize size = [movieAsset naturalSize];
      

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

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

      【讨论】:

        【解决方案4】:

        弃用警告说:

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

        asset 显然是你的 AVAsset

        【讨论】:

        • 嗯,按照您的建议应用变换会导致我的宽度为负:(
        • @Goz 只需使用fabsf() 规范化维度组件即可。
        【解决方案5】:

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

        【讨论】:

        • 谢谢 - 不过,该应用程序是用 Objective-C 编写的(我还没有重写它)。我会检查一下是否可以调整您的扩展...
        • 您好,我也遇到了同样的问题,您找到解决方案了吗?因为在我的情况下,使用自然大小 + preferredTransform 返回一个过时的值 :( 谢谢
        【解决方案6】:

        要导出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;
        

        当您的资产包含具有非平凡仿射变换的轨道(例如,45 度旋转)或如果您的资产包含具有不同来源的轨道(例如,两个轨道并排播放第二个轨道的原点增加了第一个轨道的宽度)。

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

        【讨论】:

        • Altho David,对于包含一个视频轨道的 AVAsset,@Avt 答案可以正常工作。对吗?
        • @RoiMulia:我认为资产具有非零偏移的单个视频轨道并不常见。为此,您在使用该代码时可能不太可能看到该错误。此外,当资产仅包含一首曲目时,我看到玩家忽略偏移量。如果您关心处理这些边缘情况,我建议您自己试验以验证实际行为。
        【解决方案7】:

        对于 Swift 5

          let assetSize =  asset.tracks(withMediaType: .video)[0].naturalSize
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-07-11
          • 1970-01-01
          • 1970-01-01
          • 2011-05-05
          • 1970-01-01
          • 2011-07-17
          • 2019-01-21
          相关资源
          最近更新 更多