Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SwiftUI和AVPlayer_Swiftui - Fatal编程技术网

SwiftUI和AVPlayer

SwiftUI和AVPlayer,swiftui,Swiftui,我正在尝试在我的SwiftUI界面中使用AVPlayer层。 谷歌在这个问题上没有太多答案,事实上,有一个看起来很有希望的教程,请参见:。但是里面满是虫子。所以,我试着用我自己的方式去做 计划:创建一个UIView子类并向其中添加一个AVPlayerLayer,然后为SwiftUI包装UIView 结果是:什么都没有 以下是到目前为止我得到的信息: struct PlayerView : UIViewRepresentable { func makeUIView(context: Co

我正在尝试在我的SwiftUI界面中使用AVPlayer层。 谷歌在这个问题上没有太多答案,事实上,有一个看起来很有希望的教程,请参见:。但是里面满是虫子。所以,我试着用我自己的方式去做

计划:创建一个UIView子类并向其中添加一个AVPlayerLayer,然后为SwiftUI包装UIView

结果是:什么都没有

以下是到目前为止我得到的信息:

struct PlayerView : UIViewRepresentable {

    func makeUIView(context: Context) -> UIView {
        return PlayerViewSwift()
    }

    func updateUIView(_ uiView: UIView, context: Context) {

    }
}
然后是PlayerViewWift类:

class PlayerViewSwift : UIView {
   private let playerLayer = AVPlayerLayer()

    init() {
        super.init(frame: .infinite)


    }


    override init(frame: CGRect) {
      super.init(frame: frame)


    }



    // This attribute hides `init(coder:)` from subclasses
    @available(*, unavailable)
    required init?(coder aDecoder: NSCoder) {
        fatalError("NSCoding not supported")
    }

    override func layoutSubviews() {
         super.layoutSubviews()
      //  playerLayer.player =

        print("hmmm")

               let player = AVPlayer(url: URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u80")!)
               player.play()

               playerLayer.player = player
               layer.addSublayer(playerLayer)


     }


}
从URL路径扩展中删除尾随的“0”,使其为“m3u8”而不是“m3u80”

另外,将
playerLayer
的帧设置为
playervewswift
layoutSubviews()末尾的边界:

从URL路径扩展中删除尾随的“0”,使其为“m3u8”而不是“m3u80”

另外,将
playerLayer
的帧设置为
playervewswift
layoutSubviews()末尾的边界:

Swift 5.1,iOS 13

我也阅读了Chris Mash教程(其中有4篇)并将其组合在一起。我当然不记得它们充满了bug,也许是一些拼写错误

它在SwiftUI导航控制器管理的页面中播放嵌入式视频或流媒体视频

import Foundation
import SwiftUI
import AVFoundation
import Combine

let timePublisher = PassthroughSubject<TimeInterval, Never>()
let videoFinished = PassthroughSubject<Void, Never>()
let nextFrame = PassthroughSubject<Void, Never>()

 struct PlayerTimeView: View {
 @State private var currentTime: TimeInterval = 0

var body: some View {
Text("\(currentTime)")
.onReceive(timePublisher) { time in
  self.currentTime = time
}.statusBar(hidden: true)
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}

class PlayerUIView: UIView {
private var timeObservation: Any?
private let playerLayer = AVPlayerLayer()
override init(frame: CGRect) {
super.init(frame: .zero)
let url = Bundle.main.url(forResource: "AppDemo", withExtension: "mov")
//    let url = URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")!
//    let url = URL(string: "https://www.youtube.com/watch?v=XK8METRgK_U")!
let player = AVPlayer(url: url!)
player.play()

  timeObservation = player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 0.5, preferredTimescale: 600), queue: nil) { [weak self] time in
  guard let self = self else { return }
  // Publish the new player time
  print("time.seconds ", time.seconds)
  timePublisher.send(time.seconds)

  NotificationCenter.default.addObserver(self, selector: #selector(self.finishVideo), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
}

playerLayer.player = player
layer.addSublayer(playerLayer)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
  super.layoutSubviews()
  playerLayer.frame = CGRect(x: 0, y: -115, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
 }

 @objc func finishVideo() {
    print("Video Finished")
      NotificationCenter.default.removeObserver(NSNotification.Name.AVPlayerItemDidPlayToEndTime)
     videoFinished.send()
     nextFrame.send()
  }

}

struct PlayerView: UIViewRepresentable {
 func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PlayerView>) {
 }
 func makeUIView(context: Context) -> UIView {
     PlayerUIView(frame: .zero)
 }
}

struct PlayerPage: View {
 @EnvironmentObject var env: MyAppEnvironmentData
 @Environment(\.presentationMode) var presentation

 var body: some View {
   VStack {
     PlayerView().onReceive(videoFinished) { (_) in
       self.presentation.wrappedValue.dismiss()
     }
   HStack {
     Spacer()
     PlayerTimeView()
     Spacer()
   }
  }
}
}
<代码>导入基础 导入快捷键 进口AVF基金会 进口联合收割机 让timePublisher=PassthroughSubject() 让videoFinished=PassthroughSubject() 让nextFrame=PassthroughSubject() 结构PlayerTimeView:视图{ @状态专用变量currentTime:TimeInterval=0 var body:一些观点{ 文本(“\(当前时间)”) .onReceive(timePublisher){time in self.currentTime=时间 }.statusBar(隐藏:真) .navigationBarHidden(真) .navigationBarBackButtonHidden(真) } } 类playerUI视图:UIView{ 私人观察:有吗? private let playerLayer=AVPlayerLayer() 重写初始化(帧:CGRect){ super.init(帧:.0) 让url=Bundle.main.url(用于资源:“AppDemo”,扩展名为“mov”) //让url=url(字符串:https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")! //让url=url(字符串:https://www.youtube.com/watch?v=XK8METRgK_U")! let player=AVPlayer(url:url!) player.play() timeObservation=player.addPeriodicTimeObserver(用于间隔:CMTime(秒:0.5,首选时间刻度:600),队列:nil){[弱自我]时间 guard let self=self-else{return} //发布新的播放器时间 打印(“time.seconds”,time.seconds) timePublisher.send(time.seconds) NotificationCenter.default.addObserver(self,选择器:#选择器(self.finishVideo),名称:NSNotification.name.AVPlayerItemDidPlayToEndTime,对象:nil) } playerLayer.player=玩家 layer.addSublayer(playerLayer) } 必需初始化?(编码器:NSCoder){ fatalError(“初始化(编码者:)尚未实现”) } 覆盖func布局子视图(){ super.layoutSubviews() playerLayer.frame=CGRect(x:0,y:-115,宽度:UIScreen.main.bounds.width,高度:UIScreen.main.bounds.height) } @objc func finishVideo(){ 打印(“视频完成”) NotificationCenter.default.removeObserver(NSNotification.Name.AVPlayerItemDidPlayToEndTime) videoFinished.send() nextFrame.send() } } 结构PlayerView:UIViewRepresentable{ func updateUIView(uiView:uiView,context:UIViewRepresentableContext){ } func makeUIView(上下文:context)->UIView{ PlayerUI视图(帧:.0) } } 结构PlayerPage:视图{ @EnvironmentObject变量env:MyAppEnvironmentData @环境(\.presentationMode)变量表示 var body:一些观点{ VStack{ PlayerView().onReceive(videoFinished){(u3;)in self.presentation.wrappedValue.disclose()文件 } HStack{ 垫片() PlayerTimeView() 垫片() } } } }
Swift 5.1,iOS 13

我也阅读了Chris Mash教程(其中有4篇)并将其组合在一起。我当然不记得它们充满了bug,也许是一些拼写错误

它在SwiftUI导航控制器管理的页面中播放嵌入式视频或流媒体视频

import Foundation
import SwiftUI
import AVFoundation
import Combine

let timePublisher = PassthroughSubject<TimeInterval, Never>()
let videoFinished = PassthroughSubject<Void, Never>()
let nextFrame = PassthroughSubject<Void, Never>()

 struct PlayerTimeView: View {
 @State private var currentTime: TimeInterval = 0

var body: some View {
Text("\(currentTime)")
.onReceive(timePublisher) { time in
  self.currentTime = time
}.statusBar(hidden: true)
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}

class PlayerUIView: UIView {
private var timeObservation: Any?
private let playerLayer = AVPlayerLayer()
override init(frame: CGRect) {
super.init(frame: .zero)
let url = Bundle.main.url(forResource: "AppDemo", withExtension: "mov")
//    let url = URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")!
//    let url = URL(string: "https://www.youtube.com/watch?v=XK8METRgK_U")!
let player = AVPlayer(url: url!)
player.play()

  timeObservation = player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 0.5, preferredTimescale: 600), queue: nil) { [weak self] time in
  guard let self = self else { return }
  // Publish the new player time
  print("time.seconds ", time.seconds)
  timePublisher.send(time.seconds)

  NotificationCenter.default.addObserver(self, selector: #selector(self.finishVideo), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
}

playerLayer.player = player
layer.addSublayer(playerLayer)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
  super.layoutSubviews()
  playerLayer.frame = CGRect(x: 0, y: -115, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
 }

 @objc func finishVideo() {
    print("Video Finished")
      NotificationCenter.default.removeObserver(NSNotification.Name.AVPlayerItemDidPlayToEndTime)
     videoFinished.send()
     nextFrame.send()
  }

}

struct PlayerView: UIViewRepresentable {
 func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PlayerView>) {
 }
 func makeUIView(context: Context) -> UIView {
     PlayerUIView(frame: .zero)
 }
}

struct PlayerPage: View {
 @EnvironmentObject var env: MyAppEnvironmentData
 @Environment(\.presentationMode) var presentation

 var body: some View {
   VStack {
     PlayerView().onReceive(videoFinished) { (_) in
       self.presentation.wrappedValue.dismiss()
     }
   HStack {
     Spacer()
     PlayerTimeView()
     Spacer()
   }
  }
}
}
<代码>导入基础 导入快捷键 进口AVF基金会 进口联合收割机 让timePublisher=PassthroughSubject() 让videoFinished=PassthroughSubject() 让nextFrame=PassthroughSubject() 结构PlayerTimeView:视图{ @状态专用变量currentTime:TimeInterval=0 var body:一些观点{ 文本(“\(当前时间)”) .onReceive(timePublisher){time in self.currentTime=时间 }.statusBar(隐藏:真) .navigationBarHidden(真) .navigationBarBackButtonHidden(真) } } 类playerUI视图:UIView{ 私人观察:有吗? private let playerLayer=AVPlayerLayer() 重写初始化(帧:CGRect){ super.init(帧:.0) 让url=Bundle.main.url(用于资源:“AppDemo”,扩展名为“mov”) //让url=url(字符串:https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")! //让url=url(字符串:https://www.youtube.com/watch?v=XK8METRgK_U")! let player=AVPlayer(url:url!) player.play() timeObservation=player.addPeriodicTimeObserver(用于间隔:CMTime(秒:0.5,首选时间刻度:600),队列:nil){[弱自我]时间 guard let self=self-else{return} //发布新的播放器时间 打印(“time.seconds”,time.seconds) timePublisher.send(time.seconds) NotificationCenter.default.addObserver(self,选择器:#选择器(self.finishVideo),名称:NSNotification.name.AVPlayerItemDidPlayToEndTime,对象:nil) } playerLayer.player=玩家 layer.addSublayer(playerLayer) } 必需初始化?(编码器:NSCoder){ fatalError(“初始化(编码者:)尚未实现”) } 覆盖func布局子视图(){ super.layoutSubviews() playerLayer.frame=CGRect(x:0,y:-115,宽度:UIScreen.main.bounds.width,高度:UIScreen.main.bounds.height) } @objc func finishVideo(){ 打印(“视频完成”) NotificationCenter.default.removeObserver(NSNotification.Name.AVPlayerItemDidPlayToEndTime) videoFinished.send() nextFrame.send() } } 结构PlayerView:UIViewRepresentable{ func updateUIView(uiView:uiView,上下文: