How to show my AVPlayer in a VStack with SwiftUI

2019-07-27 22:08发布

I have created a simple AVPlayer. (If I didn't create it correctly, please help me fixing it...

2条回答
迷人小祖宗
2楼-- · 2019-07-27 22:33

Thanks to Bogdan for the quick answer and for the like to the tutorial!

Here is the code, converted to NSView so it could work for macOS apps...

Here is the struct PlayerView :

struct PlayerView: NSViewRepresentable {
    func updateNSView(_ nsView: NSView, context: NSViewRepresentableContext<PlayerView>) {

    }
    func makeNSView(context: Context) -> NSView {
        return PlayerNSView(frame: .zero)
    }
}

Here is the class, "the meat" like Bogdan said:

class PlayerNSView: NSView{
    private let playerLayer = AVPlayerLayer()

    override init(frame:CGRect){
        super.init(frame: frame)
        let urlVideo = URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")!
        let player = AVPlayer(url: urlVideo)
        player.play()
        playerLayer.player = player
        if layer == nil{
            layer = CALayer()
        }
        layer?.addSublayer(playerLayer)
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func layout() {
        super.layout()
        playerLayer.frame = bounds
    }
}

Finally you can use PlayerView() to add the AVPlayer in the struct ContentView.

查看更多
虎瘦雄心在
3楼-- · 2019-07-27 22:38

Sure, here's the tutorial, by Chris Mash on Medium.

Basically you embed an AVPlayerLayer into a struct conforming to UIViewRepresentable, something you'll do for any UIView component you want to use with SwiftUI.

struct PlayerView: UIViewRepresentable {
  func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PlayerView>) {
  }

  func makeUIView(context: Context) -> UIView {
    return PlayerUIView(frame: .zero)
  }
}

The "meat" of the implementation is done in the PlayerUIView class:

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.play()

    playerLayer.player = player
    layer.addSublayer(playerLayer)
  }

  required init?(coder: NSCoder) {
     fatalError(“init(coder:) has not been implemented”)
  }

  override func layoutSubviews() {
    super.layoutSubviews()
    playerLayer.frame = bounds
  }
}

And then you use it like this:

var body: some View {
  PlayerView()
}
查看更多
登录 后发表回答