You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
7.9 KiB
Swift
274 lines
7.9 KiB
Swift
//
|
|
// OpenTok.swift
|
|
// Runner
|
|
//
|
|
// Created by Zohaib Iqbal Kambrani on 18/10/2021.
|
|
//
|
|
|
|
import Foundation
|
|
import OpenTok
|
|
|
|
enum SdkState: String {
|
|
case loggedOut = "LOGGED_OUT"
|
|
case loggedIn = "LOGGED_IN"
|
|
case wait = "WAIT"
|
|
case error = "ERROR"
|
|
}
|
|
|
|
class OpenTok : NSObject{
|
|
private var mainViewController:MainFlutterVC!
|
|
private var registrar:FlutterPluginRegistrar?
|
|
init(mainViewController:MainFlutterVC, registrar:FlutterPluginRegistrar?){
|
|
self.mainViewController = mainViewController
|
|
self.registrar = registrar
|
|
|
|
let factory = OpentokVideoFactory(messenger: registrar!.messenger())
|
|
registrar?.register(factory, withId: "opentok-video-container")
|
|
}
|
|
|
|
var otSession: OTSession?
|
|
var vonageChannel: FlutterMethodChannel?
|
|
|
|
var subscriber: OTSubscriber?
|
|
lazy var publisher: OTPublisher = {
|
|
let settings = OTPublisherSettings()
|
|
settings.name = UIDevice.current.name
|
|
return OTPublisher(delegate: self, settings: settings)!
|
|
}()
|
|
|
|
func initSession(call:FlutterMethodCall, result: @escaping FlutterResult){
|
|
if let arguments = call.arguments as? [String: String],
|
|
let apiKey = arguments["apiKey"],
|
|
let sessionId = arguments["sessionId"],
|
|
let token = arguments["token"]{
|
|
|
|
var error: OTError?
|
|
defer {
|
|
// todo
|
|
}
|
|
|
|
notifyFlutter(state: SdkState.wait)
|
|
otSession = OTSession(apiKey: apiKey, sessionId: sessionId, delegate: self)!
|
|
otSession?.connect(withToken: token, error: &error)
|
|
|
|
result("")
|
|
}else{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
func swapCamera(call:FlutterMethodCall, result: @escaping FlutterResult) {
|
|
if publisher.cameraPosition == .front {
|
|
publisher.cameraPosition = .back
|
|
} else {
|
|
publisher.cameraPosition = .front
|
|
}
|
|
result("")
|
|
}
|
|
|
|
func toggleAudio(call:FlutterMethodCall, result: @escaping FlutterResult) {
|
|
if let arguments = call.arguments as? [String: Bool],
|
|
let publishAudio = arguments["publishAudio"] {
|
|
publisher.publishAudio = !publisher.publishAudio
|
|
}
|
|
result("")
|
|
}
|
|
|
|
func toggleVideo(call:FlutterMethodCall, result: @escaping FlutterResult) {
|
|
if let arguments = call.arguments as? [String: Bool],
|
|
let publishVideo = arguments["publishVideo"] {
|
|
publisher.publishVideo = !publisher.publishVideo
|
|
}
|
|
result("")
|
|
}
|
|
|
|
|
|
func notifyFlutter(state: SdkState) {
|
|
vonageChannel?.invokeMethod("updateState", arguments: state.rawValue)
|
|
}
|
|
|
|
}
|
|
|
|
extension OpenTok: OTSessionDelegate {
|
|
func sessionDidConnect(_ sessionDelegate: OTSession) {
|
|
print("The client connected to the session.")
|
|
notifyFlutter(state: SdkState.loggedIn)
|
|
|
|
var error: OTError?
|
|
defer {
|
|
// todo
|
|
}
|
|
|
|
self.otSession?.publish(self.publisher, error: &error)
|
|
|
|
if let pubView = self.publisher.view {
|
|
pubView.frame = CGRect(x: 0, y: 0, width: 200, height: 300)
|
|
|
|
if OpentokVideoFactory.view == nil {
|
|
OpentokVideoFactory.viewToAddPub = pubView
|
|
} else {
|
|
OpentokVideoFactory.view?.addPublisherView(pubView)
|
|
}
|
|
}
|
|
}
|
|
|
|
func sessionDidDisconnect(_ session: OTSession) {
|
|
print("The client disconnected from the session.")
|
|
notifyFlutter(state: SdkState.loggedOut)
|
|
}
|
|
|
|
func session(_ session: OTSession, didFailWithError error: OTError) {
|
|
print("The client failed to connect to the session: \(error).")
|
|
}
|
|
|
|
func session(_ session: OTSession, streamCreated stream: OTStream) {
|
|
print("A stream was created in the session.")
|
|
var error: OTError?
|
|
defer {
|
|
// todo
|
|
}
|
|
subscriber = OTSubscriber(stream: stream, delegate: self)
|
|
|
|
session.subscribe(subscriber!, error: &error)
|
|
}
|
|
|
|
func session(_ session: OTSession, streamDestroyed stream: OTStream) {
|
|
print("A stream was destroyed in the session.")
|
|
}
|
|
}
|
|
|
|
extension OpenTok: OTPublisherDelegate {
|
|
func publisher(_ publisher: OTPublisherKit, streamCreated stream: OTStream) {
|
|
}
|
|
|
|
func publisher(_ publisher: OTPublisherKit, streamDestroyed stream: OTStream) {
|
|
}
|
|
|
|
func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) {
|
|
print("Publisher failed: \(error.localizedDescription)")
|
|
}
|
|
}
|
|
|
|
extension OpenTok: OTSubscriberDelegate {
|
|
func subscriberDidConnect(toStream subscriberKit: OTSubscriberKit) {
|
|
print("Subscriber connected")
|
|
|
|
if let subView = self.subscriber?.view {
|
|
subView.frame = CGRect(x: 0, y: 0, width: 200, height: 300)
|
|
|
|
if OpentokVideoFactory.view == nil {
|
|
OpentokVideoFactory.viewToAddSub = subView
|
|
} else {
|
|
OpentokVideoFactory.view?.addSubscriberView(subView)
|
|
}
|
|
}
|
|
}
|
|
|
|
func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) {
|
|
print("Subscriber failed: \(error.localizedDescription)")
|
|
}
|
|
|
|
}
|
|
|
|
class OpentokVideoFactory: NSObject, FlutterPlatformViewFactory {
|
|
static var view: OpentokVideoPlatformView?
|
|
|
|
static var viewToAddSub: UIView?
|
|
static var viewToAddPub: UIView?
|
|
|
|
static func getViewInstance(
|
|
frame: CGRect,
|
|
viewId: Int64,
|
|
args: Any?,
|
|
messenger: FlutterBinaryMessenger?
|
|
) -> OpentokVideoPlatformView{
|
|
if(view == nil) {
|
|
view = OpentokVideoPlatformView()
|
|
if viewToAddSub != nil {
|
|
view?.addSubscriberView(viewToAddSub!)
|
|
}
|
|
if viewToAddPub != nil {
|
|
view?.addPublisherView(viewToAddPub!)
|
|
}
|
|
}
|
|
|
|
return view!
|
|
}
|
|
|
|
private var messenger: FlutterBinaryMessenger
|
|
|
|
init(messenger: FlutterBinaryMessenger) {
|
|
self.messenger = messenger
|
|
super.init()
|
|
}
|
|
|
|
func create(
|
|
withFrame frame: CGRect,
|
|
viewIdentifier viewId: Int64,
|
|
arguments args: Any?
|
|
) -> FlutterPlatformView {
|
|
return OpentokVideoFactory.getViewInstance(
|
|
frame: frame,
|
|
viewId: viewId,
|
|
args: args,
|
|
messenger: messenger)
|
|
}
|
|
}
|
|
|
|
class OpentokVideoPlatformView: NSObject, FlutterPlatformView {
|
|
private let videoContainer: OpenTokVideoContainer
|
|
|
|
override init() {
|
|
videoContainer = OpenTokVideoContainer()
|
|
super.init()
|
|
}
|
|
|
|
public func addSubscriberView(_ view: UIView) {
|
|
videoContainer.addSubscriberView(view)
|
|
}
|
|
|
|
public func addPublisherView(_ view: UIView) {
|
|
videoContainer.addPublisherView(view)
|
|
}
|
|
|
|
func view() -> UIView {
|
|
return videoContainer
|
|
}
|
|
}
|
|
|
|
final class OpenTokVideoContainer: UIView {
|
|
private let subscriberContainer = UIView()
|
|
private let publisherContainer = UIView()
|
|
|
|
init() {
|
|
super.init(frame: .zero)
|
|
addSubview(subscriberContainer)
|
|
addSubview(publisherContainer)
|
|
}
|
|
|
|
|
|
public func addSubscriberView(_ view: UIView) {
|
|
subscriberContainer.addSubview(view)
|
|
}
|
|
|
|
public func addPublisherView(_ view: UIView) {
|
|
publisherContainer.addSubview(view)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
let width = frame.width
|
|
let height = frame.height
|
|
|
|
let videoWidth = width / 2
|
|
subscriberContainer.frame = CGRect(x: 0, y: 0, width: videoWidth, height: height)
|
|
publisherContainer.frame = CGRect(x: videoWidth, y: 0, width: videoWidth, height: height)
|
|
}
|
|
}
|