You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.1 KiB

import Flutter
import AVKit
import UIKit
@objc(FloatingUiPlugin)
public class FloatingUiPlugin: NSObject, FlutterPlugin {
private var pipContentViewArray: [PlayerView] = []
private static func updateAudioSession() {
let audioSession = AVAudioSession.sharedInstance()
do {
if #available(iOS 14.5, *) {
try audioSession.setCategory(.playback, mode: .moviePlayback, options: [.overrideMutedMicrophoneInterruption])
}
try audioSession.setActive(true)
} catch {
NSLog("Set audio session error: \(error.localizedDescription)")
}
}
public static func register(with registrar: FlutterPluginRegistrar) {
// 保证 PiP 能正常工作
Self.updateAudioSession()
let channel = FlutterMethodChannel(name: "native_plugin", binaryMessenger: registrar.messenger())
let instance = FloatingUiPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
let factory = FLNativeViewFactory(messenger: registrar.messenger())
registrar.register(factory, withId: "native_view")
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getPlatformVersion":
result("iOS " + UIDevice.current.systemVersion)
case "createPipContentView":
let playerView = PlayerView()
// 这里未来可以根据 PiP 的事件来控制播放状态
playerView.play()
pipContentViewArray.append(playerView)
let ptr = Unmanaged.passUnretained(playerView).toOpaque()
let viewId = UInt64(UInt(bitPattern: ptr))
result(NSNumber(value: viewId))
case "disposePipContentView":
guard let viewIdNum = call.arguments as? NSNumber else {
result(nil)
return
}
let targetId = viewIdNum.uint64Value
for (idx, playerView) in pipContentViewArray.enumerated() {
let currentId = UInt64(UInt(bitPattern: Unmanaged.passUnretained(playerView).toOpaque()))
if currentId == targetId {
playerView.pause()
pipContentViewArray.remove(at: idx)
break
}
}
result(nil)
case "updatePipContentView":
guard let data = call.arguments as? [String: Any] else {
result(nil)
return
}
let lang = data["lang"] as? String
let cn = data["cn"] as? String
let en = data["en"] as? String
let viewIdNum = data["viewId"] as? NSNumber
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
if let viewIdNum = viewIdNum {
let targetId = viewIdNum.uint64Value
for playerView in self.pipContentViewArray {
let currentId = UInt64(UInt(bitPattern: Unmanaged.passUnretained(playerView).toOpaque()))
if currentId == targetId {
playerView.update(withLang: lang, cn: cn, en: en)
break
}
}
} else {
if let playerView = self.pipContentViewArray.last {
playerView.update(withLang: lang, cn: cn, en: en)
}
}
}
result(nil)
default:
result(FlutterMethodNotImplemented)
}
}
}