Why AVPlayer always nil

I do not understand why AVPlayer is always nil

 Unexpectedly found nil while unwrapping an Optional value

struct SatelliteVideoView: View {
   
  init() {
    player = AVPlayer(url: URL(string: "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4")!)
  }
   
  var body: some View {
    VideoPlayer(player: player!)
}

The documentation uses this code.

Answered by chitgoks in 737402022

@Claude31 it seems the problem is with the instantation of AVPlayer inside init(). honeslty, i have no clue why it behaves this way. If i specify the url when the variable is declared, it works. I followed the sample here

https://www.swiftanytime.com/videoplayer-in-swiftui/

and it works if it is coded like this

@State var player = AVPlayer(url: URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4")!)  

but, if it is done like this, it does not work

init() {
    if let url = URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4") {
      player = AVPlayer(url: url)
    }
 }

Thoughts?

Did you try directly your url ? I tested, it is a broken link.

You should ask directly to the company (learningContainer) to check in Wordpress what is the exact url of the file. maybe the date 2020/05 has changed ?

Note: this code is prone to crash:

    VideoPlayer(player: player!)

forcing an unwrap without checking for nil is dangerous. You'd better write

if  player != nil {   VideoPlayer(player: player!) }

Same here

    player = AVPlayer(url: URL(string: "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4")!)

You'd better write

if let url = URL(string: "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4" {
    player = AVPlayer(url: url)
}
Accepted Answer

@Claude31 it seems the problem is with the instantation of AVPlayer inside init(). honeslty, i have no clue why it behaves this way. If i specify the url when the variable is declared, it works. I followed the sample here

https://www.swiftanytime.com/videoplayer-in-swiftui/

and it works if it is coded like this

@State var player = AVPlayer(url: URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4")!)  

but, if it is done like this, it does not work

init() {
    if let url = URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4") {
      player = AVPlayer(url: url)
    }
 }

Thoughts?

Could you show more code ? We do not see where var player is declared.

Is there a statement as:

@State var player : AVPlayer?

New url works, the first one don't in Safari (but works in Chrome).

Seems i missed some code. here's the right one

struct SatelliteVideoView: View { 
  @State private var player: AVPlayer?
   
  init() {
    if let url = URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4") {
      player = AVPlayer(url: url)
    }
  }
   
  var body: some View {
    if player != nil {
      VideoPlayer(player: player!)
    }
  }
}
Accepted Answer

CoI tested with somme dummy code.

Problem comes from the fact that player is defined as a State var:

This show : player is nil

struct SatelliteVideoView: View {
  @State private var player: AVPlayer?
   
  init() {
    if let url = URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4") {
        print(url)
      player = AVPlayer(url: url)
    } else {
        print("url is nil")
    }
  }
   
  var body: some View {
    if player != nil {
      Text("player is not nil") // VideoPlayer(player: player!)
    } else {
        Text("player is nil")
    }
  }
}

But here, player is not nil:

struct SatelliteVideoView: View {
  /*@State*/ private var player: AVPlayer?
   
  init() {
    if let url = URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4") {
        print(url)
      player = AVPlayer(url: url)
    } else {
        print("url is nil")
    }
  }
   
  var body: some View {
    if player != nil {
      Text("player is not nil") // VideoPlayer(player: player!)
    } else {
        Text("player is nil")
    }
  }
}

Or, if you define player as AVPlayer and not optional, it works:

struct SatelliteVideoView: View {
  @State private var player: AVPlayer
   
  init() {
    if let url = URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4") {
      player = AVPlayer(url: url)
    } else {
        player = AVPlayer()
    }
  }
   
  var body: some View {
      Text("player is not nil") // VideoPlayer(player: player!)
  }
}

Reason is detailed here: https://stackoverflow.com/questions/56691630/swiftui-state-var-initialization-issue

  • you cannot change the value of a state var in its struct
  • but you can initialise it.

So if you declare as optional AVPlayer, it is initialised as nil. No possible to change later in init().

But if you simply declare as AVPlayer, it is not yet initialised, hence you can set it in init()

 it probably will work if it is a state optional but i set the value after a button click?

No, you cannot do it in the struct where the State var is defined.

Don't forget to close the thread on the answer that explained why it was nil. Good continutaion.

My last comment was wrong. You cannot set it in init(), nor directly in the struct code, but you can set it in a button action (hopefully)

import AVFoundation
struct SatelliteVideoView: View {
  @State private var player: AVPlayer?
   
  var body: some View {
    if player != nil {
      Text("player is not nil") // VideoPlayer(player: player!)
    } else {
        Text("player is nil")
    }
      Button(action: {
          if let url = URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4") {
              player = AVPlayer(url: url)
          }
      }) {
          Text("play")
      }

  }
}

Sorry for the confusion.

Why AVPlayer always nil
 
 
Q