如何获取AVPlayer中HLS流的视频大小?

问题描述 投票:0回答:4

我试图在播放 hls 流时获取视频分辨率。 我有典型的播放器初始化:

let urlAsset = AVURLAsset(URL: currentVideoUrl)
 self.player=AVPlayer(playerItem: AVPlayerItem(asset:urlAsset))
 .......

我使用 KVO,当我获得 AVPlayerItem 的 ReadyToPlay 状态时,我尝试获取视频大小:

    func resolutionSizeForVideo() {

    guard let videoTrack = self.player.currentItem?.asset.tracksWithMediaType(AVMediaTypeVideo).first else
    { return
    }

    let size = CGSizeApplyAffineTransform(videoTrack.naturalSize, videoTrack.preferredTransform)
    let frameSize = CGSize(width: fabs(size.width), height: fabs(size.height))
    print ("video size: \(frameSize)")

}

问题是 trackWithMediaType() 总是返回空数组(但适用于非流文件,例如 .mov)。

如何获取 AVPlayer 中播放的 HLS 视频的大小 (CGRect)?

ios swift avplayer http-live-streaming
4个回答
15
投票

您是否能够使用此方法至少记录视频信息?

extension AVAsset{
    func videoSize()->CGSize{
        let tracks = self.tracks(withMediaType: AVMediaType.video)
        if (tracks.count > 0){
            let videoTrack = tracks[0]
            let size = videoTrack.naturalSize
            let txf = videoTrack.preferredTransform
            let realVidSize = size.applying(txf)
            print(videoTrack)
            print(txf)
            print(size)
            print(realVidSize)
            return realVidSize
        }
        return CGSize(width: 0, height: 0)
    }

}

let videoAssetSource = AVAsset.init(URL: videoURL)
print("size:",videoAssetSource.videoSize())

14
投票

使用 HLS 时,Tracks 将始终返回 nil。如果您有一个 UIView 子类,它使用 AVPlayerLayer 覆盖其

layerClass
来播放视频,您可以使用

获取大小
playerView.layer.videoRect

这只是视频的大小,而不是整个图层的大小。

或者你可以使用KVO来观察项目的presentationSize

player.addObserver(self, forKeyPath: "currentItem.presentationSize", options: [.Initial, .New], context: nil)

4
投票

你可以简明扼要地这样做:

import AVKit

extension AVAsset {

    var videoSize: CGSize? {
        tracks(withMediaType: .video).first.flatMap {
            tracks.count > 0 ? $0.naturalSize.applying($0.preferredTransform) : nil
        }
    }
}


0
投票

自 iOS 16 起,我们可以使用新的实现,因为以前的实现已被弃用(自 iOS 16 及更高版本起)。

import AVKit
import Foundation

extension AVAsset {
    func videoSize() async throws -> CGSize? {
        guard let track = try await loadTracks(withMediaType: .video).first else { return nil }
        let size = try await track.load(.naturalSize)
        return size
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.