I hope you're all doing well. Over the past couple of weeks, I've been working on creating a feed with videos, similar to what you see on Instagram. However, I'm facing a bit of a challenge and could use some guidance.
希望你们都过得很好。在过去的几周里,我一直致力于创建一个带有视频的feed,类似于你在Instagram上看到的内容。然而,我正面临着一些挑战,可能需要一些指导。
I'm torn between two approaches: Should I use just one AVPlayer and swap out the playing item each time, or should I have a separate AVPlayer for each cell in the feed?
我在两种方法之间左右为难:我是应该只使用一个AVPlayer,然后每次都换出播放项,还是应该为提要中的每个单元格都有一个单独的AVPlayer?
I've experimented with both methods, and they do work, but I've noticed some performance issues, and to be honest, I'm not entirely satisfied with either solution. I've been searching for best practices and examples, but I'm coming up short. Does anyone have any experience with this or know of any resources or examples that could help me out?
我对这两种方法都进行了试验,它们确实有效,但我注意到了一些性能问题,说实话,我对这两种解决方案都不完全满意。我一直在寻找最佳实践和例子,但我找不到。有谁有这方面的经验,或者知道有什么资源或例子可以帮助我解决这个问题吗?
Any assistance or guidance would be greatly appreciated. Thanks in advance for your help!
What I've got:
如有任何协助或指导,将不胜感激。提前感谢您的帮助!我得到的是:
Video struct:
视频结构:
struct Video: Identifiable {
var id = UUID().uuidString
var player: AVPlayer?
var mediaFile: String
}
Playing Controller:
播放控制器:
struct PlayerViewController: UIViewControllerRepresentable {
var player: AVPlayer?
var isMuted: Bool {
didSet {
VideoConstants.isMuted = isMuted
}
}
let controller = AVPlayerViewController()
func makeUIViewController(context _: Context) -> AVPlayerViewController {
controller.modalPresentationStyle = .fullScreen
controller.player = player
controller.showsPlaybackControls = false
controller.player?.isMuted = isMuted
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: player?.currentItem, queue: .main) { _ in
self.player?.seek(to: CMTime.zero)
self.player?.play()
}
return controller
}
func updateUIViewController(_: AVPlayerViewController, context _: Context) {}
}
I've got cell with properties:
我有一个手机,它的属性是:
@Binding var videoPlayer: Video
And body:
和正文:
var body: some View {
ZStack(alignment: .topLeading) {
GeometryReader { proxy -> Color in
let minY = proxy.frame(in: .global).minY
let size = proxy.size
DispatchQueue.main.async { // calculating center to play video
if -minY < (size.height / 2), minY < (size.height / 2) {
videoPlayer.player?.play()
} else {
videoPlayer.player?.pause()
}
}
return Color.clear
}
VStack {
PlayerViewController(player: videoPlayer.player, isMuted: VideoConstants.isMuted)
.frame(height: 600)
.onTapGesture {
videoPlayer.player?.isMuted.toggle()
}
.overlay(alignment: .bottomTrailing) {}
photoFooter
}
header
.onDisappear {
videoPlayer.player?.pause()
}
}
.background(Color.background.ignoresSafeArea())
}
And on the main Feed View I create video player:
在主Feed视图上,我创建了视频播放器:
@ViewBuilder
func prepareVideo(with model: FeedPostModel) -> some View {
var model = model
if let videoUrl = model.contentVideo?.videoID,
let url = URL(string: NetworkManager.videoDownloadUrl + videoUrl),
let videoPost = model.contentVideo {
let player = AVPlayer(url: url)
let video = Binding {
Video(player: player, mediaFile: videoUrl)
} set: { _, _ in }
ContentPostVideoCell(videoPlayer: video, "many additional fields")
更多回答
我是一名优秀的程序员,十分优秀!