Skip to content

Instantly share code, notes, and snippets.

@Faiyyaz
Created May 20, 2020 22:30
Show Gist options
  • Save Faiyyaz/4c4dfea2b588676a3c975c819946d6f3 to your computer and use it in GitHub Desktop.
Save Faiyyaz/4c4dfea2b588676a3c975c819946d6f3 to your computer and use it in GitHub Desktop.
Youtube LFLiveKit example
//
// BroadCastViewController.swift
// trainer
//
// Created by Faiyyaz Khatri on 26/03/20.
// Copyright © 2020 Intro. All rights reserved.
//
import Foundation
import UIKit
import LFLiveKit
import Alamofire
import SwiftDate
class ViewController : UIViewController, LFLiveSessionDelegate {
var url : String = ""
var token : String = ""
var isException : Bool = false
var status : String = ""
var broadCastID : String = ""
var date : String = ""
var minute : CGFloat = 0
var yourTimer : Timer!
var refreshUserTimer : Timer!
@IBOutlet weak var tvLabel: UILabel!
@IBOutlet weak var btnShowBottomSheet: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
session.delegate = self
session.preView = self.view
startTimer()
refreshUserTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(refreshUser), userInfo: nil, repeats: true)
self.requestAccessForVideo()
self.requestAccessForAudio()
self.view.backgroundColor = UIColor.clear
self.view.addSubview(containerView)
containerView.addSubview(startLiveButton)
startLiveButton.addTarget(self, action: #selector(didTappedStartLiveButton(_:)), for: .touchUpInside)
self.view.bringSubviewToFront(btnShowBottomSheet)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: AccessAuth
func requestAccessForVideo() -> Void {
let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video);
switch status {
case AVAuthorizationStatus.notDetermined:
AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (granted) in
if(granted){
DispatchQueue.main.async {
self.session.running = true
}
}
})
break;
case AVAuthorizationStatus.authorized:
session.running = true;
break;
case AVAuthorizationStatus.denied: break
case AVAuthorizationStatus.restricted:break;
default:
break;
}
}
func requestAccessForAudio() -> Void {
let status = AVCaptureDevice.authorizationStatus(for:AVMediaType.audio)
switch status {
case AVAuthorizationStatus.notDetermined:
AVCaptureDevice.requestAccess(for: AVMediaType.audio, completionHandler: { (granted) in
})
break;
case AVAuthorizationStatus.authorized:
break;
case AVAuthorizationStatus.denied: break
case AVAuthorizationStatus.restricted:break;
default:
break;
}
}
//MARK: - Callbacks
// 回调
func liveSession(_ session: LFLiveSession?, debugInfo: LFLiveDebug?) {
print("debugInfo: \(String(describing: debugInfo?.currentBandwidth))")
}
func liveSession(_ session: LFLiveSession?, errorCode: LFLiveSocketErrorCode) {
print("errorCode: \(errorCode.rawValue)")
}
func liveSession(_ session: LFLiveSession?, liveStateDidChange state: LFLiveState) {
print("liveStateDidChange: \(state.rawValue)")
if(state == LFLiveState.start) {
status = Constants.LIVE
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: {
self.changeStatus(broadCastID: self.broadCastID, status: self.status)
})
}
else if(state == LFLiveState.stop) {
status = Constants.COMPLETED
changeStatus(broadCastID: broadCastID, status: status)
}
else if(state == LFLiveState.error) {
isException = true
self.dismiss(animated: true, completion: nil)
}
}
//MARK: - Events
@objc func didTappedStartLiveButton(_ button: UIButton) -> Void {
startLiveButton.isSelected = !startLiveButton.isSelected;
if (startLiveButton.isSelected) {
startLiveButton.setTitle("Stop", for: UIControl.State())
let stream = LFLiveStreamInfo()
stream.url = url
session.startLive(stream)
self.startLiveButton.isEnabled = false
} else {
startLiveButton.setTitle("Start", for: UIControl.State())
session.stopLive()
}
}
//MARK: - Getters and Setters
var session: LFLiveSession = {
let audioConfiguration = LFLiveAudioConfiguration.defaultConfiguration(for: LFLiveAudioQuality.high)
let videoConfiguration = LFLiveVideoConfiguration.defaultConfiguration(for: LFLiveVideoQuality.low3)
let session = LFLiveSession(audioConfiguration: audioConfiguration, videoConfiguration: videoConfiguration)
return session!
}()
var containerView: UIView = {
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
containerView.backgroundColor = UIColor.clear
containerView.autoresizingMask = [UIView.AutoresizingMask.flexibleHeight, UIView.AutoresizingMask.flexibleHeight]
return containerView
}()
var startLiveButton: UIButton = {
let startLiveButton = UIButton(frame: CGRect(x: 30, y: UIScreen.main.bounds.height - 50, width: UIScreen.main.bounds.width - 10 - 44, height: 44))
startLiveButton.layer.cornerRadius = 22
startLiveButton.setTitleColor(UIColor.black, for:UIControl.State())
startLiveButton.setTitle("Start", for: UIControl.State())
startLiveButton.titleLabel!.font = UIFont.systemFont(ofSize: 14)
startLiveButton.backgroundColor = UIColor.blue
return startLiveButton
}()
func changeStatus(broadCastID : String, status : String){
let headers : HTTPHeaders = [
"authtoken": token,
"Content-Type": "application/json"
]
let request = AF.request(Constants.URL + "?" + Constants.BROADCAST_STATUS + "=" + status + "&" + Constants.BROADCAST_ID + "=" + broadCastID, method: .get, encoding: JSONEncoding.default, headers: headers)
request.responseJSON {
response in
switch response.result {
case .success(let responseJSON):
//success
let jsonData = try! JSONSerialization.data(withJSONObject: responseJSON)
self.startLiveButton.isEnabled = true
print(jsonData)
if(status == Constants.COMPLETED) {
self.dismiss(animated: true, completion: nil)
}
break
case .failure(let error):
if (!JSONSerialization.isValidJSONObject(error)) {
print(error)
return
}
//failure
let jsonData = try! JSONSerialization.data(withJSONObject: error)
print(jsonData)
self.dismiss(animated: true, completion: nil)
break
}
}
}
func startTimer() {
yourTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateCountDown), userInfo: nil, repeats: true)
yourTimer.fire()
}
@objc func updateCountDown(){
///ISO date from flutter
let dateString = date
///Date formatter
let formatter = DateFormatter()
formatter.timeZone = TimeZone.current
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
///Current Date creation
let currentDateTime = Date()
let nowString = formatter.string(from: currentDateTime)
let nowDate = formatter.date(from: nowString)
///Formatting Start Date
let region = Region(calendar: Calendars.gregorian, zone: Zones.current, locale: Locales.english)
let date = DateInRegion(dateString, region: region)!
let startDateString = formatter.string(from: date.date)
let startDate = formatter.date(from: startDateString)
///Calculating difference
let difference = Calendar.current.dateComponents([.minute, .second], from: startDate!, to: nowDate!)
let formattedString = String(format: "%02ld: %02ld", difference.minute!, difference.second!)
tvLabel.text = formattedString
}
@IBAction func showBottomSheet(_ sender: UIButton) {
let bounds = UIScreen.main.bounds
let height = bounds.size.height
let storyboard = UIStoryboard(name: "Main", bundle: Bundle(for:type(of: self)))
let userBottomSheetController = storyboard.instantiateViewController(withIdentifier: "UserBottomSheetController") as! UserBottomSheetController
userBottomSheetController.height = height * 0.65
self.present(userBottomSheetController, animated: true, completion: nil)
}
@objc func refreshUser(refreshUserTimer: Timer) {
print("refreshUserTimer")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment