在 SwiftUI 中,如何将循环添加视频作为全屏背景图像? [英] In SwiftUI, how can I add a video on loop as a fullscreen background image?

查看:31
本文介绍了在 SwiftUI 中,如何将循环添加视频作为全屏背景图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大约 10 秒长的视频,我想在我的其中一个 SwiftUI 视图中作为全屏背景图像循环播放.我该如何实施?

I have a video thats around 10 seconds long that I'd like to play on a loop as a fullscreen background image in one of my SwiftUI Views. How can I implement this?

第一个想法是使用 Swift 的 import AVFoundation,但不确定这是否是正确的路径.

First idea was working with Swift's import AVFoundation, but not sure if this is the right path.

推荐答案

您可以使用 AV 系列框架和 UIViewRepresentable 来做到这一点:

You can use the AV family of frameworks and UIViewRepresentable to do this:

import SwiftUI
import AVKit
import AVFoundation

struct PlayerView: UIViewRepresentable {
    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PlayerView>) {
    }

    func makeUIView(context: Context) -> UIView {
        return PlayerUIView(frame: .zero)
    }
}

为了让视频循环播放,我添加了一个观察者并将 actionAtItemEnd 设置为 .none 以支持循环播放.

In order for the video to loop I have added an observer and set the actionAtItemEnd to .none to support looping.

当视频到达结尾时,它会执行playerItemDidReachEnd(...) 方法并寻找视频的开头并继续循环.

When the video reaches the end it will execute the playerItemDidReachEnd(...) method and seek to the beginning of the video and keep looping.

该示例指向远程视频 URL.如果您想指向应用程序中的文件,您可以使用 Bundle.main.url 来代替:

The example points to a remote video URL. If you want to point to a file within your application you can use Bundle.main.url to do so instead:

if let fileURL = Bundle.main.url(forResource: "IMG_2770", withExtension: "MOV") {
    let player = AVPlayer(url: fileURL)
    // ...
}

class PlayerUIView: UIView {
    private let playerLayer = AVPlayerLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)

        let url = URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")!
        let player = AVPlayer(url: url)
        player.actionAtItemEnd = .none
        player.play()

        playerLayer.player = player
        playerLayer.videoGravity = .resizeAspectFill

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(playerItemDidReachEnd(notification:)),
                                               name: .AVPlayerItemDidPlayToEndTime,
                                               object: player.currentItem)

        layer.addSublayer(playerLayer)
    }

    @objc func playerItemDidReachEnd(notification: Notification) {
        if let playerItem = notification.object as? AVPlayerItem {
            playerItem.seek(to: .zero, completionHandler: nil)
        }
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

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

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

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

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                PlayerView()
                    .edgesIgnoringSafeArea(.all)
            }
        }
    }
}

这篇关于在 SwiftUI 中,如何将循环添加视频作为全屏背景图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆