This is my test code for playing video in SwiftUI, the video start playing in first time, but when I update the url for other video it shows like multiple (10-20 times) line of:
"AttributeGraph: cycle detected through attribute"
in Xcode console. From what I see I did not made wrong code for this issue, how ever I also could not find an answer in internet for this logs. The videos are playing after click but each time after updating the url this logs comes out in Xcode.
import SwiftUI
import AVKit
struct ContentView: View {
@State private var AVPlayerURL: URL? = nil
var body: some View {
VStack {
if let AVPlayerURL {
VideoPlayer(player: AVPlayer(url: AVPlayerURL))
}
HStack {
Button("Play video 1") {
AVPlayerURL = Bundle.main.url(forResource: "myVideo1", withExtension: "mp4")
}
Button("Play video 2") {
AVPlayerURL = Bundle.main.url(forResource: "myVideo2", withExtension: "mp4")
}
Button("Play video 3") {
AVPlayerURL = Bundle.main.url(forResource: "myVideo3", withExtension: "mp4")
}
}
}
.padding()
}
}
Here I find a way for solving the issue of Xcode logs.
import SwiftUI
import AVKit
@main
struct AVPlayer_TestApp: App {
var body: some Scene {
WindowGroup {
ContentView().environmentObject(AVPlayerModel.shared)
}
}
}
struct ContentView: View {
@EnvironmentObject var myAVPlayerModel: AVPlayerModel
var body: some View {
VStack {
Group {
if let unwrappedPlayer: AVPlayer = myAVPlayerModel.player {
VideoPlayer(player: unwrappedPlayer)
}
else {
Color.black
}
}
.cornerRadius(5.0)
ButtonView()
}
.padding()
}
}
struct ButtonView: View {
@EnvironmentObject var myAVPlayerModel: AVPlayerModel
var body: some View {
HStack {
Button("Play video 1") {
myAVPlayerModel.AVPlayerURL = Bundle.main.url(forResource: "myVideo1", withExtension: "mp4")
}
Button("Play video 2") {
myAVPlayerModel.AVPlayerURL = Bundle.main.url(forResource: "myVideo2", withExtension: "mp4")
}
Button("Play video 3") {
myAVPlayerModel.AVPlayerURL = Bundle.main.url(forResource: "myVideo3", withExtension: "mp4")
}
}
}
}
class AVPlayerModel: ObservableObject {
static let shared: AVPlayerModel = AVPlayerModel()
@Published var AVPlayerURL: URL? = nil {
didSet(oldValue) {
if let unwrappedAVPlayerURL: URL = self.AVPlayerURL {
if let unwrappedOldValue: URL = oldValue {
if (unwrappedAVPlayerURL != unwrappedOldValue) {
self.player?.pause()
self.player = nil
}
else {
let seekToZero = CMTime(seconds: 0, preferredTimescale: 60000)
self.player?.seek(to: seekToZero, toleranceBefore: .zero, toleranceAfter: .zero)
return
}
}
else {
self.player?.pause()
self.player = nil
}
DispatchQueue.main.async {
if let unwrappedAVPlayerURL: URL = self.AVPlayerURL {
self.player = AVPlayer(url: unwrappedAVPlayerURL)
self.player?.play()
}
}
}
}
}
@Published var player: AVPlayer? = nil
}