// // ViewController.swift // Runner // // Created by Mohammad Aljammal & Elham Rababah on 23/6/20. // Copyright © 2020 The Chromium Authors. All rights reserved. // import UIKit import OpenTok import Alamofire class ViewController: UIViewController { var session: OTSession? var publisher: OTPublisher? var subscriber: OTSubscriber? var kApiKey:String = "" var kSessionId:String = "" var kToken:String = "" var VC_ID: Int = 0 var TokenID: String = "" var generalid : String = "" var DoctorId: Int = 0 var baseUrl:String = "" var callBack: ICallProtocol? var timer = Timer() var seconds = 30 var isUserConnect : Bool = false override func viewDidLoad() { super.viewDidLoad() setupButtons() askForMicrophonePermission() requestCameraPermissionsIfNeeded() hideVideoMuted() setupSession() // Do any additional setup after loading the view. } private func getSessionStatus() { let URL_USER_REGISTER = baseUrl+"LiveCareApi/DoctorApp/GetSessionStatus" let headers: HTTPHeaders = [ "Content-Type":"application/json", "Accept":"application/json", ] let parameters = [ "VC_ID": VC_ID, "TokenID": TokenID, "generalid": generalid, "DoctorId" : DoctorId , ] as [String : Any] Alamofire.request(URL_USER_REGISTER, method: .post,parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON{ response in if self.isUserConnect { } else { if let result = response.result.value { let jsonData = result as! NSObject if((jsonData.value(forKey: "SessionStatus")) as! Int == 2 || (jsonData.value(forKey: "SessionStatus")) as! Int == 3) { //jsonData let jsonObject: [String: Any] = [ "sessionStatus": result , "callResponse": "CallNotRespond", ] self.callBack?.sessionNotResponded(res: jsonObject) } } self.sessionDisconnect(); self.timer.invalidate() } //getting json value from the server } } func setupButtons() { perform(#selector(hideControlButtons), with: nil, afterDelay: 3) let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(remoteVideoTapped(_:))) view.addGestureRecognizer(tapGestureRecognizer) view.isUserInteractionEnabled = true } // MARK: -Microphone Camera and Permission Request func askForMicrophonePermission() { switch AVAudioSession.sharedInstance().recordPermission { case AVAudioSession.RecordPermission.granted: break case AVAudioSession.RecordPermission.denied: break case AVAudioSession.RecordPermission.undetermined: // This is the initial state before a user has made any choice // You can use this spot to request permission here if you want AVAudioSession.sharedInstance().requestRecordPermission({ granted in // Check for granted }) default: break } } func notifyUserOfCameraAccessDenial() { // display a useful message asking the user to grant permissions from within Settings > Privacy > Camera } @IBAction func didClickMuteButton(_ sender: UIButton) { sender.isSelected = !sender.isSelected publisher!.publishAudio = !sender.isSelected } @IBAction func didClickSpeakerButton(_ sender: UIButton) { sender.isSelected = !sender.isSelected subscriber?.subscribeToAudio = !sender.isSelected // resetHideButtonsTimer() } @IBAction func didClickVideoMuteButton(_ sender: UIButton) { sender.isSelected = !sender.isSelected if publisher!.publishVideo { publisher!.publishVideo = false } else { publisher!.publishVideo = true } localVideo.isHidden = sender.isSelected localVideoMutedBg.isHidden = !sender.isSelected localVideoMutedIndicator.isHidden = !sender.isSelected // resetHideButtonsTimer() } @IBAction func didClickSwitchCameraButton(_ sender: UIButton) { sender.isSelected = !sender.isSelected if sender.isSelected { publisher!.cameraPosition = AVCaptureDevice.Position.front } else { publisher!.cameraPosition = AVCaptureDevice.Position.back } /// resetHideButtonsTimer() } @IBAction func hangUp(_ sender: UIButton) { callBack?.sessionDone(res:["callResponse":"CallEnd"]) sessionDisconnect() } func sessionDisconnect() { if (session != nil) { print("disconnecting....") session!.disconnect(nil) dismiss(animated: true) return } dismiss(animated: true) } // Converted to Swift 5.2 by Swiftify v5.2.26743 - https://swiftify.com/ func requestCameraPermissionsIfNeeded() { // check camera authorization status let authStatus: AVAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video) switch authStatus { case .authorized: break // camera authorized // do camera intensive stuff case .notDetermined: // request authorization AVCaptureDevice.requestAccess(for: .video, completionHandler: { granted in DispatchQueue.main.async(execute: { if granted { // do camera intensive stuff } else { self.notifyUserOfCameraAccessDenial() } }) }) case .restricted, .denied: DispatchQueue.main.async(execute: { self.notifyUserOfCameraAccessDenial() }) default: break } } func hideVideoMuted() { remoteVideoMutedIndicator.isHidden = true localVideoMutedBg.isHidden = true localVideoMutedIndicator.isHidden = true } func setupSession() { //setup one time session if (session != nil) { session = nil } session = OTSession( apiKey: kApiKey, sessionId: kSessionId, delegate: self) var error: OTError? session!.connect(withToken: kToken,error: &error) } func connectToAnOpenTokSession() { session = OTSession(apiKey: kApiKey, sessionId: kSessionId, delegate: self) var error: OTError? session?.connect(withToken: kToken, error: &error) if error != nil { print(error!) } } func showAlert(_ string: String?) { // show alertview on main UI DispatchQueue.main.async(execute: { let alertVC = UIAlertController( title: "OTError", message: string, preferredStyle: .alert) self.present(alertVC, animated: true) }) } @IBOutlet weak var localVideo: UIView! @IBOutlet weak var remoteVideo: UIView! @IBOutlet weak var controlButtons: UIView! @IBOutlet weak var remoteVideoMutedIndicator: UIImageView! @IBOutlet weak var localVideoMutedBg: UIImageView! @IBOutlet weak var localVideoMutedIndicator: UIImageView! @objc func updateTimer(){ seconds -= 1 //This will decrement(count down)the seconds. print(seconds) if seconds == 0 { getSessionStatus() } } } extension ViewController: OTSessionDelegate { func sessionDidConnect(_ session: OTSession) { print("The client connected to the OpenTok session.") timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true) setupPublisher() } func setupPublisher() { let settings = OTPublisherSettings() settings.name = UIDevice.current.name publisher = OTPublisher(delegate: self, settings: settings) var error: OTError? = nil session!.publish(publisher!, error: &error) if error != nil { showAlert(error?.localizedDescription) } publisher?.view!.frame = CGRect(x: localVideo.bounds.origin.x, y: localVideo.bounds.origin.y, width: localVideo.bounds.size.width, height: localVideo.bounds.size.height) localVideo.addSubview((publisher?.view)!) } func sessionDidDisconnect(_ session: OTSession) { print("The client disconnected from the OpenTok session.") } func session(_ session: OTSession, didFailWithError error: OTError) { print("The client failed to connect to the OpenTok session: \(error).") } func session( _ session: OTSession, connectionDestroyed connection: OTConnection ) { if subscriber?.stream!.connection.connectionId == connection.connectionId { cleanupSubscriber() } sessionDisconnect() } func session(_ session: OTSession, streamCreated stream: OTStream) { subscriber = OTSubscriber(stream: stream, delegate: self) guard let subscriber = subscriber else { return } var error: OTError? session.subscribe(subscriber, error: &error) guard error == nil else { print(error!) return } guard let subscriberView = subscriber.view else { return } subscriberView.frame = UIScreen.main.bounds view.insertSubview(subscriberView, at: 0) // if nil == subscriber { // setupSubscribe(stream) // } } func setupSubscribe(_ stream: OTStream?) { subscriber = OTSubscriber(stream: stream!, delegate: self) var error: OTError? = nil session!.subscribe(subscriber!, error: &error) if error != nil { showAlert(error!.localizedDescription) } } func session(_ session: OTSession, streamDestroyed stream: OTStream) { if subscriber?.stream?.streamId == stream.streamId { cleanupSubscriber() } print("A stream was destroyed in the session.") } func cleanupSubscriber() { subscriber?.view!.removeFromSuperview() subscriber = nil } func session( _ session: OTSession?, connectionCreated connection: OTConnection? ) { // startTimer(callDuration, warningDuration) if let connectionId = connection?.connectionId { print("session connectionCreated (\(connectionId))") } isUserConnect = true timer.invalidate() } } extension ViewController: OTPublisherDelegate { func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) { print("The publisher failed: \(error)") } @objc func remoteVideoTapped(_ recognizer: UITapGestureRecognizer?) { if controlButtons.isHidden { controlButtons.isHidden = false perform(#selector(hideControlButtons), with: nil, afterDelay: 3) } } } extension ViewController: OTSubscriberDelegate { public func subscriberDidConnect(toStream subscriber: OTSubscriberKit) { print("The subscriber did connect to the stream.") } public func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) { print("The subscriber failed to connect to the stream.") } @objc func hideControlButtons() { controlButtons.isHidden = true } }