Files
react-native-video/ios/hybrids/VideoViewViewManager/HybridVideoViewViewManager.swift
2025-10-13 22:23:17 +02:00

196 lines
3.9 KiB
Swift

//
// HybridVideoViewViewManager.swift
// ReactNativeVideo
//
// Created by Krzysztof Moch on 23/09/2024.
//
import Foundation
import AVKit
import NitroModules
class HybridVideoViewViewManager: HybridVideoViewViewManagerSpec {
weak var view: VideoComponentView?
let DEALOCATED_WARNING = "ReactNativeVideo: VideoComponentView is no longer available. It is likely that the view was deallocated."
init(nitroId: Double) throws {
guard let view = VideoComponentView.globalViewsMap.object(forKey: NSNumber(value: nitroId)) else {
throw VideoViewError.viewNotFound(nitroId: nitroId).error()
}
self.view = view
super.init()
view.delegate = VideoViewDelegate(viewManager: self)
}
// MARK: - Properties
weak var player: (any HybridVideoPlayerSpec)? {
get {
guard let view = view else {
print(DEALOCATED_WARNING)
return nil
}
return view.player
}
set {
guard let view = view else {
print(DEALOCATED_WARNING)
return
}
view.player = newValue
}
}
var controls: Bool {
get {
guard let view else {
print(DEALOCATED_WARNING)
return false
}
return view.controls
}
set {
guard let view else {
print(DEALOCATED_WARNING)
return
}
view.controls = newValue
}
}
var pictureInPicture: Bool {
get {
guard let view else {
print(DEALOCATED_WARNING)
return false
}
return view.allowsPictureInPicturePlayback
}
set {
guard let view else {
print(DEALOCATED_WARNING)
return
}
view.allowsPictureInPicturePlayback = newValue
}
}
var autoEnterPictureInPicture: Bool {
get {
guard let view else {
print(DEALOCATED_WARNING)
return false
}
return view.autoEnterPictureInPicture
}
set {
guard let view else {
print(DEALOCATED_WARNING)
return
}
view.autoEnterPictureInPicture = newValue
}
}
var resizeMode: ResizeMode {
get {
guard let view else {
print(DEALOCATED_WARNING)
return .none
}
return view.resizeMode
}
set {
guard let view else {
print(DEALOCATED_WARNING)
return
}
view.resizeMode = newValue
}
}
var keepScreenAwake: Bool {
get {
guard let view else {
print(DEALOCATED_WARNING)
return false
}
return view.keepScreenAwake
}
set {
guard let view else {
print(DEALOCATED_WARNING)
return
}
view.keepScreenAwake = newValue
}
}
// Android only - no-op on iOS
var surfaceType: SurfaceType = .surface
func enterFullscreen() throws {
guard let view else {
throw VideoViewError.viewIsDeallocated.error()
}
try view.enterFullscreen()
}
func exitFullscreen() throws {
guard let view else {
throw VideoViewError.viewIsDeallocated.error()
}
try view.exitFullscreen()
}
func enterPictureInPicture() throws {
guard let view else {
throw VideoViewError.viewIsDeallocated.error()
}
try view.startPictureInPicture()
}
func exitPictureInPicture() throws {
guard let view else {
throw VideoViewError.viewIsDeallocated.error()
}
try view.stopPictureInPicture()
}
func canEnterPictureInPicture() -> Bool {
return AVPictureInPictureController.isPictureInPictureSupported()
}
// MARK: - Callbacks
var onPictureInPictureChange: ((Bool) -> Void)?
var onFullscreenChange: ((Bool) -> Void)?
var willEnterFullscreen: (() -> Void)?
var willExitFullscreen: (() -> Void)?
var willEnterPictureInPicture: (() -> Void)?
var willExitPictureInPicture: (() -> Void)?
var onReadyToDisplay: (() -> Void)?
}