如何使用 SwiftUI 在 VStack 中显示我的 AVPlayer

Posted

技术标签:

【中文标题】如何使用 SwiftUI 在 VStack 中显示我的 AVPlayer【英文标题】:How to show my AVPlayer in a VStack with SwiftUI 【发布时间】:2019-06-30 06:44:08 【问题描述】:

我创建了一个简单的 AVPlayer。 (如果我没有正确创建它,请帮我修复它...... ????)我想用 swift ui 在我的 VStack 中显示它,但我有点卡住了......

如果库中至少有AVPlayer View 组件,那会更容易,但是我在库中没有找到它... ????

这是我在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

顺便说一句,如果有教程展示如何使用 swift ui 制作视频播放器,我将不胜感激!

编辑 我忘了说我正在开发一个 ma​​cOS 应用程序。

【问题讨论】:

如何使用 PlayerView("video1.mp4") PlayerView("video2.mp4") 【参考方案1】:

当然,这是Chris Mash on Medium 的教程。

基本上,您将AVPlayerLayer 嵌入到符合UIViewRepresentable 的结构中,您可以为任何想要与SwiftUI 一起使用的UIView 组件执行此操作。

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

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

实现的“肉”在PlayerUIView类中完成:

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
  

然后你像这样使用它:

var body: some View 
  PlayerView()

【讨论】:

嗯...本教程和示例适用于 ios...我正在为 macOS 开发。 对不起,我忘了在我最初的帖子中提到它...... :) @FrancisDolbec : UIViewRepresentableAVPlayerLayer 都可以在 MacO 上工作。 哦,真的吗?也许我输入了错误的内容,因为当我尝试您的答案时,它说它无法导入 UIKit ......我读到它适用于 iOS,等效的是 AppKit...... @FrancisDolbec:对不起,我的意思是 NSViewRepresentable,见developer.apple.com/documentation/swiftui/nsviewrepresentable【参考方案2】:

感谢 Bogdan 的快速回答以及对本教程的喜欢!

这是代码,已转换为 NSView,因此它可以用于 macOS 应用程序...

这是结构体PlayerView

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

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

这是类,像博格丹所说的“肉”:

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
    

最后你可以使用PlayerView()struct ContentView中添加AVPlayer。

【讨论】:

PlayerUIView 实现在 macOS Catalina 上对我来说工作得很好,开箱即用。使用开启 macOS 的 iOS 应用程序。 如何使用 PlayerView("video1.mp4") PlayerView("video2.mp4")

以上是关于如何使用 SwiftUI 在 VStack 中显示我的 AVPlayer的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中动态调整可垂直滚动的 VStack 中的一行中的项目数?

Swiftui 将 VStack 子项高度调整为内容高度

SwiftUI - 在 VStack 中对齐文本

SwiftUI中ScrollView底部对齐内的VStack

SwiftUI,删除VStack中视图之间的空间?

如何在 SwiftUI 中根据其子级高度设置 GeometryReader 高度?