How to show my AVPlayer in a VStack with SwiftUI

被刻印的时光 ゝ 提交于 2019-12-10 18:50:00

问题


I have created a simple AVPlayer. (If I didn't create it correctly, please help me fixing it... 😀 ) I want to display it in my VStack with swift ui, but I'm kind of stuck...

If at least there was the AVPlayer View component in the library, it would have been easier, but I didn't found it in the library... 😔

Here is my code in the ContentView.swift:

//
//  ContentView.swift
//  test
//
//  Created by Francis Dolbec on 2019-06-26.
//  Copyright © 2019 Francis Dolbec. All rights reserved.
//

import SwiftUI
import AVKit
import AVFoundation

// MARK: variables
var hauteurMenuBar = NSApplication.shared.mainMenu?.menuBarHeight
var urlVideo = URL(string: "/Users/francisdolbec/Movies/Séries Télé/Rick et Morty/Rick.and.Morty.S01E01.VFQ.HDTV.1080p.x264-Kamek.mp4")
let player = AVPlayer(url: urlVideo!)


struct ContentView : View {
    var body: some View {

        VStack {
            Text("Hello World")
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            Text("PATATE!")
            //player.play()
            }

        .frame(minWidth: 1024, idealWidth: 1440, maxWidth: .infinity, minHeight: (640-hauteurMenuBar!), idealHeight: (900-hauteurMenuBar!), maxHeight: .infinity)

    }
}


#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

By the way, if there's a tutorial that show how to make a video player with swift ui, I would really appreciate it!

EDIT I forgot to say that I am developing a macOS app.


回答1:


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()
}



回答2:


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.



来源:https://stackoverflow.com/questions/56822943/how-to-show-my-avplayer-in-a-vstack-with-swiftui

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!