I am learning SwiftUI, I want to observe an AVPlayer status so I know when the videos is paused or not.
My current approach is more less like this:
- I have VideosView that holds a list of a videos (in ZStack cards).
- VideoViews has a VideosViewModel.
- in VideosView i am calling in onAppear
VideosViewModel.getItems
...
struct ItemModel: Identifiable, Codable, Hashable, Equatable {
var id: String
var author: String // video owner
var url: URL? // url to the video
var player: AVPlayer? // AVPlayer created based on self.url...
mutating func setPlayer(_ avPlayer: AVPlayer) {
self.player = avPlayer
}
}
// vm
class FeedViewModel: ObservableObject {
@Published private(set) var items: [ItemModel] = []
func getItems() async {
do {
// fetch data from the API
let data = try await dataService.fetchFeeds()
// download and attach videos
downloadFeedVideos(data)
} catch {
// ....
}
}
private func downloadFeedVideos(_ feeds: [ItemModel]) {
for index in feeds.indices {
var item = feeds[index]
if let videoURL = item.url {
self.downloadQueue.queueDownloadIfFileNotExists(
videoURL,
DownloadOperation(
session: URLSession.shared,
downloadTaskURL: videoURL,
completionHandler: { [weak self] (localURL, response, error) in
guard let tempUrl = localURL else { return }
let saveResult = self?.fileManagerService.saveInTemp(tempUrl, fileName: videoURL.lastPathComponent)
switch saveResult {
case .success(let savedURL):
DispatchQueue.main.async {
// maybe this is a wrong place to have it?
item.setPlayer(AVPlayer(url: savedURL))
self?.items.append(item)
if self?.items.count ?? 0 > 1 {
// once first video is downloaded, use all device cores to fetch next videos
// all newest iOS devices has 6 cores
self?.downloadQueue.setMaxConcurrentOperationCount(.max)
}
}
case .none: break
case .failure(_):
EventTracking().track("Video download fail", [
"id": item.id,
"ulr": videoURL.absoluteString.decodeURL()
])
}
}), { fileCacheURL in
// file already downloaded
DispatchQueue.main.async {
item.setPlayer(AVPlayer(url: fileCacheURL))
self.items.append(item)
}
})
}
}
}
}
I found this article with some pseudo-code of how to track video playback state but I'm not sure how to implement it in my code....
https://developer.apple.com/documentation/avfoundation/media_playback/observing_playback_state