Skip to content

Instantly share code, notes, and snippets.

@satishVekariya
Last active November 24, 2023 18:59
Show Gist options
  • Save satishVekariya/e0175c453623ad10e06195cc217e5447 to your computer and use it in GitHub Desktop.
Save satishVekariya/e0175c453623ad10e06195cc217e5447 to your computer and use it in GitHub Desktop.
AvPlayer wrapper for SwiftUI
import SwiftUI
import AVKit
public struct VideoPlayerView<Overlay: View>: View {
let overlay: Overlay
let player: AVPlayer
@State private var isShowOverlay = true
public init(_ player: AVPlayer, overlay: () -> (Overlay)) {
self.player = player
self.overlay = overlay()
}
public var body: some View {
AVPlayerViewRepresentable(player) {
// on touches began
isShowOverlay.toggle()
}
.ignoresSafeArea()
.overlay {
overlay
.onTapGesture {
isShowOverlay.toggle()
}
.opacity(isShowOverlay ? 1 : 0)
.animation(.default, value: isShowOverlay)
}
.task {
await hideOverlay()
}
.task(id: isShowOverlay) {
await hideOverlay()
}
.task(id: player.isPlaying) {
await hideOverlay()
}
}
private func hideOverlay() async {
guard isShowOverlay else { return }
try? await Task.sleep(for: .seconds(3))
await MainActor.run {
if player.isPlaying {
isShowOverlay = false
}
}
}
}
public struct AVPlayerViewRepresentable: UIViewRepresentable {
let touchesBegan: (() -> ())?
let player: AVPlayer
public init(_ player: AVPlayer, touchesBegan: (() -> ())?) {
self.player = player
self.touchesBegan = touchesBegan
}
public func makeUIView(context: Context) -> AVPlayerLayerUIView {
let view = AVPlayerLayerUIView(touchesBegan: touchesBegan)
view.playerLayer.player = player
return view
}
public func updateUIView(_ uiView: AVPlayerLayerUIView, context: Context) {
uiView.playerLayer.player = player
}
}
public class AVPlayerLayerUIView: UIView {
let touchesBegan: (() -> ())?
public override class var layerClass: AnyClass { AVPlayerLayer.self }
public var playerLayer: AVPlayerLayer { layer as? AVPlayerLayer ?? .init(layer: layer) }
public init(touchesBegan: (() -> ())?) {
self.touchesBegan = touchesBegan
super.init(frame: .zero)
backgroundColor = .black
}
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
touchesBegan?()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment