feat: implement Linphone SDK integration with video call support

Complete rewrite from stub plugin to (probably) functional liblinphone integration featuring:
- Core SDK bridge with registration, calls, and media controls
- Platform views for remote and local video rendering
- Event channels for registration and call state updates
This commit is contained in:
Andrew 2026-01-22 16:15:28 +07:00
parent 7bbaf1b827
commit 0375fe4d1a
18 changed files with 901 additions and 52 deletions

View file

@ -0,0 +1,27 @@
import Flutter
import linphonesw
class LocalView: NSObject, FlutterPlatformView {
private var _lvvh: LinphoneVideoViewHolder? = nil
private var _view: UIView? = nil
init(
frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?,
binaryMessenger messenger: FlutterBinaryMessenger?,
cacher: (UIView) -> Void
) {
super.init()
_lvvh = LinphoneVideoViewHolder { view in
self._view = view
}
cacher(_view!)
}
func view() -> UIView {
return _view!
}
}

View file

@ -0,0 +1,32 @@
import Flutter
import UIKit
class LocalViewFactory: NSObject, FlutterPlatformViewFactory {
private var messenger: FlutterBinaryMessenger
private var cacher: (UIView) -> Void
init(messenger: FlutterBinaryMessenger, cacher: @escaping (UIView) -> Void) {
self.messenger = messenger
self.cacher = cacher
super.init()
}
func create(
withFrame frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?
) -> FlutterPlatformView {
return LocalView(
frame: frame,
viewIdentifier: viewId,
arguments: args,
binaryMessenger: messenger,
cacher: cacher
)
}
/// Implementing this method is only necessary when the `arguments` in `createWithFrame` is not `nil`.
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}

View file

@ -0,0 +1,27 @@
import Flutter
import linphonesw
class RemoteView: NSObject, FlutterPlatformView {
private var _lvvh: LinphoneVideoViewHolder? = nil
private var _view: UIView? = nil
init(
frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?,
binaryMessenger messenger: FlutterBinaryMessenger?,
cacher: (UIView) -> Void
) {
super.init()
_lvvh = LinphoneVideoViewHolder { view in
self._view = view
}
cacher(_view!)
}
func view() -> UIView {
return _view!
}
}

View file

@ -0,0 +1,32 @@
import Flutter
import UIKit
class RemoteViewFactory: NSObject, FlutterPlatformViewFactory {
private var messenger: FlutterBinaryMessenger
private var cacher: (UIView) -> Void
init(messenger: FlutterBinaryMessenger, cacher: @escaping (UIView) -> Void) {
self.messenger = messenger
self.cacher = cacher
super.init()
}
func create(
withFrame frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?
) -> FlutterPlatformView {
return RemoteView(
frame: frame,
viewIdentifier: viewId,
arguments: args,
binaryMessenger: messenger,
cacher: cacher
)
}
/// Implementing this method is only necessary when the `arguments` in `createWithFrame` is not `nil`.
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}