我有一个大约 10 秒长的视频,我想在我的一个 SwiftUI 视图中作为全屏背景图像循环播放。我怎样才能实现这个?
第一个想法是与 Swift 合作import AVFoundation
,但不确定这是否是正确的道路。
您可以使用AV
框架系列和UIViewRepresentable
去做这个:
import SwiftUI
import AVKit
struct PlayerView: UIViewRepresentable {
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PlayerView>) {
}
func makeUIView(context: Context) -> UIView {
return PlayerUIView(frame: .zero)
}
}
为了使视频循环播放,我添加了一个观察者并设置actionAtItemEnd
to .none
支持循环。
当视频结束时,它将执行playerItemDidReachEnd(...)
方法并寻找视频的开头并保持循环。
该示例指向远程视频 URL。如果您想指向应用程序中的文件,您可以使用Bundle.main.url
这样做:
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
}
}
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
PlayerView()
.edgesIgnoringSafeArea(.all)
}
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)