Skip to content

Commit

Permalink
Bump to HaishinKit.swift up 2.0.1 and refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
shogo4405 committed Dec 7, 2024
1 parent 2cd6ea6 commit 5f74b41
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 130 deletions.
1 change: 1 addition & 0 deletions .idea/HaishinKit.dart.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ PODS:
- Flutter (1.0.0)
- haishin_kit (0.13.0):
- Flutter
- HaishinKit (= 2.0.0)
- HaishinKit (2.0.0):
- HaishinKit (= 2.0.1)
- HaishinKit (2.0.1):
- Logboard (~> 2.5.0)
- Logboard (2.5.0)
- permission_handler_apple (9.3.0):
Expand Down Expand Up @@ -35,8 +35,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
audio_session: f08db0697111ac84ba46191b55488c0563bb29c6
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
haishin_kit: e7ecc567291eab9a6c0e9373a7602e239a880272
HaishinKit: 69f06380e1ffbed4b8dd03e3c76cdcc19d073a3b
haishin_kit: 2184189161cb8f2cada5a9cb57714e300bba605f
HaishinKit: 0f45d773a56f0a9b1054b02809cb8b5ed5ac0a83
Logboard: 4674a3d86681539a0ad1fca528d888b90871e268
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d

Expand Down
2 changes: 1 addition & 1 deletion ios/Classes/HKStreamFlutterTexture.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ final class HKStreamFlutterTexture: NSObject, FlutterTexture {
kCVPixelBufferIOSurfacePropertiesKey as String: NSDictionary()
]

var id: Int64 = 0
private(set) var id: Int64 = 0
var bounds: CGSize = .zero
var videoGravity: AVLayerVideoGravity = .resizeAspectFill
var videoOrientation: AVCaptureVideoOrientation = .portrait
Expand Down
143 changes: 143 additions & 0 deletions ios/Classes/MediaMixerHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import Foundation
import Flutter
import HaishinKit
import AVFoundation
import VideoToolbox

final class MediaMixerHandler: NSObject {
private lazy var instance = MediaMixer(multiCamSessionEnabled: false, multiTrackAudioMixingEnabled: false)

override init() {
super.init()
NotificationCenter.default.addObserver(self, selector: #selector(on(_:)), name: UIDevice.orientationDidChangeNotification, object: nil)
}

func addOutput(_ output: some MediaMixerOutput) {
Task { await instance.addOutput(output) }
}

func removeOutput(_ output: some MediaMixerOutput) {
Task { await instance.removeOutput(output) }
}

func stopRunning() {
Task {
await instance.stopCapturing()
await instance.stopRunning()
}
}

@objc
private func on(_ notification: Notification) {
guard let orientation = DeviceUtil.videoOrientation(by: UIApplication.shared.statusBarOrientation) else {
return
}
Task { await instance.setVideoOrientation(orientation) }
}
}

extension MediaMixerHandler: MethodCallHandler {
// MARK: MethodCallHandler
func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
Task {
guard
let arguments = call.arguments as? [String: Any?] else {
result(nil)
return
}
switch call.method {
case "RtmpStream#getHasAudio":
result(await !instance.audioMixerSettings.isMuted)
case "RtmpStream#setHasAudio":
guard let hasAudio = arguments["value"] as? Bool else {
result(nil)
return
}
var audioMixerSettings = await instance.audioMixerSettings
audioMixerSettings.isMuted = !hasAudio
await instance.setAudioMixerSettings(audioMixerSettings)
result(nil)
case "RtmpStream#getHasVudio":
result(await !instance.videoMixerSettings.isMuted)
case "RtmpStream#setHasVudio":
guard let hasVideo = arguments["value"] as? Bool else {
result(nil)
return
}
var videoMixerSettings = await instance.videoMixerSettings
videoMixerSettings.isMuted = !hasVideo
await instance.setVideoMixerSettings(videoMixerSettings)
result(nil)
case "RtmpStream#setFrameRate":
guard
let frameRate = arguments["value"] as? NSNumber else {
result(nil)
return
}
await instance.setFrameRate(frameRate.doubleValue)
result(nil)
case "RtmpStream#setSessionPreset":
guard let sessionPreset = arguments["value"] as? String else {
result(nil)
return
}
switch sessionPreset {
case "high":
await instance.setSessionPreset(.high)
case "medium":
await instance.setSessionPreset(.medium)
case "low":
await instance.setSessionPreset(.low)
case "hd1280x720":
await instance.setSessionPreset(.hd1280x720)
case "hd1920x1080":
await instance.setSessionPreset(.hd1920x1080)
case "hd4K3840x2160":
await instance.setSessionPreset(.hd4K3840x2160)
case "vga640x480":
await instance.setSessionPreset(.vga640x480)
case "iFrame960x540":
await instance.setSessionPreset(.iFrame960x540)
case "iFrame1280x720":
await instance.setSessionPreset(.iFrame1280x720)
case "cif352x288":
await instance.setSessionPreset(.cif352x288)
default:
await instance.setSessionPreset(AVCaptureSession.Preset.hd1280x720)
}
result(nil)
case "RtmpStream#attachAudio":
let source = arguments["source"] as? [String: Any?]
if source == nil {
try? await instance.attachAudio(nil)
} else {
try? await instance.attachAudio(AVCaptureDevice.default(for: .audio))
}
result(nil)
case "RtmpStream#attachVideo":
let source = arguments["source"] as? [String: Any?]
if source == nil {
try? await instance.attachVideo(nil, track: 0)
} else {
var devicePosition = AVCaptureDevice.Position.back
if let position = source?["position"] as? String {
switch position {
case "front":
devicePosition = .front
case "back":
devicePosition = .back
default:
break
}
}
if let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: devicePosition) {
try? await instance.attachVideo(device, track: 0)
}
}
result(nil)
default:
result(FlutterMethodNotImplemented)
}
}
}
}
124 changes: 14 additions & 110 deletions ios/Classes/RTMPStreamHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import VideoToolbox

final class RTMPStreamHandler: NSObject, MethodCallHandler {
private let plugin: SwiftHaishinKitPlugin
private var mixer: MediaMixer = .init()
private var texture: HKStreamFlutterTexture?
private var instance: RTMPStream?
private var eventSink: FlutterEventSink?
Expand All @@ -25,17 +24,9 @@ final class RTMPStreamHandler: NSObject, MethodCallHandler {
}
if let connection = handler.instance {
let instance = RTMPStream(connection: connection)
if let orientation = DeviceUtil.videoOrientation(by: UIApplication.shared.statusBarOrientation) {
Task { await mixer.setVideoOrientation(orientation) }
}
NotificationCenter.default.addObserver(self, selector: #selector(on(_:)), name: UIDevice.orientationDidChangeNotification, object: nil)
plugin.mixer?.addOutput(instance)
self.instance = instance
}
Task {
if let instance {
await mixer.addOutput(instance)
}
}
}

func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
Expand All @@ -46,66 +37,16 @@ final class RTMPStreamHandler: NSObject, MethodCallHandler {
return
}
switch call.method {
case "RtmpStream#getHasAudio":
result(await !mixer.audioMixerSettings.isMuted)
case "RtmpStream#setHasAudio":
guard let hasAudio = arguments["value"] as? Bool else {
result(nil)
return
}
var audioMixerSettings = await mixer.audioMixerSettings
audioMixerSettings.isMuted = !hasAudio
await mixer.setAudioMixerSettings(audioMixerSettings)
result(nil)
case "RtmpStream#getHasVudio":
result(await !mixer.videoMixerSettings.isMuted)
case "RtmpStream#setHasVudio":
guard let hasVideo = arguments["value"] as? Bool else {
result(nil)
return
}
var videoMixerSettings = await mixer.videoMixerSettings
videoMixerSettings.isMuted = !hasVideo
await mixer.setVideoMixerSettings(videoMixerSettings)
result(nil)
case "RtmpStream#setFrameRate":
guard
let frameRate = arguments["value"] as? NSNumber else {
result(nil)
return
}
await mixer.setFrameRate(frameRate.doubleValue)
result(nil)
case "RtmpStream#setSessionPreset":
guard let sessionPreset = arguments["value"] as? String else {
result(nil)
return
}
switch sessionPreset {
case "high":
await mixer.setSessionPreset(.high)
case "medium":
await mixer.setSessionPreset(.medium)
case "low":
await mixer.setSessionPreset(.low)
case "hd1280x720":
await mixer.setSessionPreset(.hd1280x720)
case "hd1920x1080":
await mixer.setSessionPreset(.hd1920x1080)
case "hd4K3840x2160":
await mixer.setSessionPreset(.hd4K3840x2160)
case "vga640x480":
await mixer.setSessionPreset(.vga640x480)
case "iFrame960x540":
await mixer.setSessionPreset(.iFrame960x540)
case "iFrame1280x720":
await mixer.setSessionPreset(.iFrame1280x720)
case "cif352x288":
await mixer.setSessionPreset(.cif352x288)
default:
await mixer.setSessionPreset(AVCaptureSession.Preset.hd1280x720)
}
result(nil)
case
"RtmpStream#getHasAudio",
"RtmpStream#setHasAudio",
"RtmpStream#getHasVudio",
"RtmpStream#setHasVudio",
"RtmpStream#setFrameRate",
"RtmpStream#setSessionPreset",
"RtmpStream#attachAudio",
"RtmpStream#attachVideo":
plugin.mixer?.handle(call, result: result)
case "RtmpStream#setAudioSettings":
guard
let settings = arguments["settings"] as? [String: Any?] else {
Expand Down Expand Up @@ -139,37 +80,6 @@ final class RTMPStreamHandler: NSObject, MethodCallHandler {
}
await instance?.setVideoSettings(videoSettings)
result(nil)
case "RtmpStream#setScreenSettings":
result(nil)
case "RtmpStream#attachAudio":
let source = arguments["source"] as? [String: Any?]
if source == nil {
try? await mixer.attachAudio(nil)
} else {
try? await mixer.attachAudio(AVCaptureDevice.default(for: .audio))
}
result(nil)
case "RtmpStream#attachVideo":
let source = arguments["source"] as? [String: Any?]
if source == nil {
try? await mixer.attachVideo(nil, track: 0)
} else {
var devicePosition = AVCaptureDevice.Position.back
if let position = source?["position"] as? String {
switch position {
case "front":
devicePosition = .front
case "back":
devicePosition = .back
default:
break
}
}
if let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: devicePosition) {
try? await mixer.attachVideo(device, track: 0)
}
}
result(nil)
case "RtmpStream#play":
_ = try? await instance?.play(arguments["name"] as? String)
result(nil)
Expand Down Expand Up @@ -219,7 +129,9 @@ final class RTMPStreamHandler: NSObject, MethodCallHandler {
_ = try? await instance?.close()
result(nil)
case "RtmpStream#dispose":
await mixer.stopRunning()
if let instance {
plugin.mixer?.removeOutput(instance)
}
_ = try? await instance?.close()
instance = nil
plugin.onDispose(id: Int(bitPattern: ObjectIdentifier(self)))
Expand All @@ -229,14 +141,6 @@ final class RTMPStreamHandler: NSObject, MethodCallHandler {
}
}
}

@objc
private func on(_ notification: Notification) {
guard let orientation = DeviceUtil.videoOrientation(by: UIApplication.shared.statusBarOrientation) else {
return
}
Task { await mixer.setVideoOrientation(orientation) }
}
}

extension RTMPStreamHandler: FlutterStreamHandler {
Expand Down
Loading

0 comments on commit 5f74b41

Please sign in to comment.