最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to set video gravity in SwiftUI? - Stack Overflow

programmeradmin6浏览0评论

Video gravity as per .

I needed this because VideoGravity.aspectResizeFill does exactly what I need:

The video preserves its aspect ratio and fills the layer’s bounds.
...
This gravity value may crop the video image along its horizontal or vertical dimension.

I have tried many workarounds including hardcoding the aspect ratio as recommended here, but they were unsatisfactory.

Video gravity as per https://developer.apple/documentation/avfoundation/avplayerlayer/videogravity.

I needed this because VideoGravity.aspectResizeFill does exactly what I need:

The video preserves its aspect ratio and fills the layer’s bounds.
...
This gravity value may crop the video image along its horizontal or vertical dimension.

I have tried many workarounds including hardcoding the aspect ratio as recommended here, but they were unsatisfactory.

Share Improve this question asked Mar 25 at 2:03 Wong Jia HauWong Jia Hau 3,1092 gold badges24 silver badges40 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

This is a particularly tricky question because Video Gravity was introduced in 2014 while SwiftUI was only released in 2019. For reasons unknown, the Video Gravity API was not being ported from UIKit to SwifUI.

Thus, to use Video Gravity in SwiftUI, we have to create a SwiftUI wrapper around a UIKit view as follows:

import AVKit
import SwiftUI

class PlayerUIView: UIView {
    private let playerLayer = AVPlayerLayer()
    private var player: AVPlayer?

    // Default initializer with frame
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupLayer()
    }

    // Required initializer when using Interface Builder
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupLayer()
    }

    // Setup the player layer
    private func setupLayer() {
        playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
        layer.addSublayer(playerLayer)
    }

    // Set a new player
    func setPlayer(_ player: AVPlayer, gravity: AVLayerVideoGravity) {
        self.player = player
        playerLayer.player = player
        playerLayer.videoGravity = gravity
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        playerLayer.frame = bounds
    }
}

struct MyVideoPlayerView: UIViewRepresentable {
    var player: AVPlayer
    var videoGravity: AVLayerVideoGravity

    func makeUIView(context _: Context) -> PlayerUIView {
        let view = PlayerUIView(frame: .zero)
        view.setPlayer(player, gravity: videoGravity)
        return view
    }

    func updateUIView(_: PlayerUIView, context _: Context) {
        // Update the view if needed
    }
}

Usage example:

import AVKit
import SwiftUI

struct MyView: View {
    let player = AVPlayer(url: URL(string: "https://myvideo/abc")!)
    var body: some View {
        MyVideoPlayerView(
            player: player, 
            videoGravity: .resizeAspectFill
        )
        .ignoresSafeArea() // For displaying the video in full screen
    }
}
发布评论

评论列表(0)

  1. 暂无评论