Skip to content

Instantly share code, notes, and snippets.

@EndLess728
Last active August 11, 2021 11:36
Show Gist options
  • Save EndLess728/e2b9537850e3107e00e72956be1a1d8a to your computer and use it in GitHub Desktop.
Save EndLess728/e2b9537850e3107e00e72956be1a1d8a to your computer and use it in GitHub Desktop.
This code is used to send stickers and live comments using firebase in the live broadcast
//
// GAPlayBroadCastViewController.swift
// GaintzAds
//
// Created by MacMini on 3/8/19.
// Copyright © 2019 Amit. All rights reserved.
//
import UIKit
import WowzaGoCoderSDK
import Firebase
class GAPlayBroadCastViewController: UIViewController {
//IBOutLets
@IBOutlet weak var videoView: UIView!
@IBOutlet weak var liveCommentsTableView: UITableView!
@IBOutlet weak var stickersStackView: CustomStackView!
@IBOutlet weak var stickerContainerView : UIView!
@IBOutlet var sendComment : UIButton!
//Variables
var goCoderConfig: WowzaConfig!
var player = WOWZPlayer()
let SDKSampleSavedConfigKey = "SDKSampleSavedConfigKey"
let PlaybackPrerollKey = "PlaybackPrerollKey"
let SDKSampleAppLicenseKey = "GOSK-2A46-010C-DD1D-D901-5540"
var playerURL : String = ""
//var id = String()
var status: String!
var stickerCommentMessage = String()
var messageStickerURL :String!
//FireBase Variables
var messageArray = [GAFetchFireBaseData]()
var myRef :DatabaseReference?
var firHandle:DatabaseHandle?
//Variables
var DataDict = String()
var mainDict = NSDictionary()
//Variables for play stream Configs
var liveStreamUserProfilePic = String()
var liveStreamUserName = String()
var liveStreamID = String()
var hostAddress:String!
var hostPort:Int!
var applicationName : String!
var streamName = String()
// var userName:String!
var password:String!
var urlHLS:String!
weak var timer: Timer?
//IBOutlets
@IBOutlet weak var userProfilePic: RoundMyImageView!
@IBOutlet weak var userName: UILabel!
@IBOutlet weak var viewsCount: UILabel!
@IBOutlet weak var enterCommentTextField : UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// darkGradiantTableView()
//Reverse The TableView
liveCommentsTableView.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi));
// stickersStackView.isHidden = true
stickerContainerView.isHidden = true
// liveCommentsTableView.estimatedRowHeight = 80
// liveCommentsTableView.rowHeight = UITableViewAutomaticDimension
fetchFireBaseData()
// playerURL = "http://api.cloud.wowza.com/api/v1.3/live_streams/\(id)"
//print(playerURL)
licenceKey()
//playLiveStreamAPI()
setupConfig()
updateUserDetails()
playLiveStream()
//Update views count in every 1 minute
timer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(getStreamViewCount), userInfo: nil, repeats: true)
}
//MARK:- Gradiant Overlay
func darkGradiantTableView(){
let gradient = CAGradientLayer()
gradient.frame = liveCommentsTableView.bounds //liveCommentsTableView.superview?.bounds ?? CGRect.null
gradient.colors = [UIColor.clear.cgColor, UIColor.clear.cgColor, UIColor.black.cgColor, UIColor.black.cgColor, UIColor.clear.cgColor, UIColor.clear.cgColor]
gradient.locations = [0.0, 0.15, 0.25, 0.75, 0.85, 1.0]
gradient.startPoint = .init(x: 0 , y: 1) //(0.5, 0.0)
gradient.endPoint = .init(x: 0, y: 0) //and (0.5, 1)
liveCommentsTableView.superview?.layer.mask = gradient
liveCommentsTableView.backgroundColor = UIColor.clear
}
//MARK: Change StatusBar Color
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override func viewDidDisappear(_ animated: Bool) {
timer?.invalidate() //Invalidate timer when screen user lefts the screen
}
//MARK: Fetch Data From Firebase
func fetchFireBaseData(){
myRef = Database.database().reference()
print(streamName)
firHandle = myRef?.child("chats").child(streamName).observe(.childAdded, with: { (snapshot) in
print(snapshot.value)
let dict = snapshot.value as! NSDictionary
let obj = GAFetchFireBaseData.init(json: dict as! [String : Any] )
self.messageArray.append(obj)
print(obj)
self.liveCommentsTableView.reloadData()
})
}
//MARK: Update UserName and Profile Pic
func updateUserDetails(){
//User Profile Pic
let profileImageFinalURL = liveStreamUserProfilePic
print(profileImageFinalURL)
userProfilePic.sd_setImage(with: URL(string: profileImageFinalURL), placeholderImage: UIImage(named: "defaultUser"))
//userName
userName.text = liveStreamUserName
}
//MARK: Update Stickers Gift API
func updateStickerGiftAPI(giftAmount:String, giftPoints:String)
{
if GAReusableClass.sharedInstance.isNetworkAvailable() == true
{
GAReusableClass.sharedInstance.showActivityIndicator()
var deviceToken : String = ""
if(defaults.value(forKey:"deviceToken" ) != nil)
{
deviceToken = defaults.value(forKey: "deviceToken") as! String
print(deviceToken)
}
else
{
deviceToken = "12345"
}
let dictionary = [
"device_id": "\(deviceToken)",
"uuid": GAloginUserInfo.shared.loginUserUuid!,
"device_type": "ios",
"net_amount":giftAmount,
"stream_name":streamName,
"net_points":giftPoints
]
print(dictionary)
let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(dictionary)
{
if let jsonString = String(data: jsonData, encoding: .utf8)
{
print(jsonString)
let cipher:String = CryptoHelper.encrypt(input:jsonString)!;
let NewEncryption = "data=\(cipher)"
let hmac_md5 = cipher.hmac(algorithm: .sha512, key: kHMACKey)
print("hmac",hmac_md5)
defaults.set(hmac_md5, forKey: Headerkey)
print("new encyrption",NewEncryption)
Singleton.sharedInstance.getWebservices(params: NewEncryption, Methodname:"user/updateLiveStreamCoins" , data: Stringnil)
{ (result) in
print(result)
if result != nil
{
do {
let jsonData = try JSONSerialization.data(withJSONObject: result)
if let json = String(data: jsonData, encoding: .utf8)
{
print(json)
let Dict = function.convertToDictionary(text: json)! as NSDictionary
if Dict[KData] != nil
{
self.DataDict = Dict.value(forKey: KData) as! String
print(self.DataDict)
}
else
{
return
}
}
} catch {
// print(Errormsg)
}
let output:String = CryptoHelper.decrypt(input:self.DataDict)!;
print(output)
self.mainDict = function.convertToDictionary(text: output)! as NSDictionary
let status = self.mainDict[KStatus] as! NSInteger
if(status == 1)
{
DispatchQueue.main.async {
GAReusableClass.sharedInstance.hideActivityIndicator()
// self.sendLiveComments()
}
}
else
{
GAReusableClass.sharedInstance.hideActivityIndicator()
DispatchQueue.main.async
{
GAAlertClass.showAlertView(vc: self, titleString: "", messageString: self.mainDict[KMessage] as! String)
}
}
}
else
{
DispatchQueue.main.async
{
GAReusableClass.sharedInstance.hideActivityIndicator()
GAAlertClass.showAlertView(vc: self, titleString: "", messageString: NSLocalizedString("Server error", comment: ""))
}
}
}
}
}
}
else
{
GAReusableClass.sharedInstance.hideActivityIndicator()
GAAlertClass.showAlertView(vc: self, titleString: "", messageString: NSLocalizedString("noNEtwork", comment: ""))
}
}
//MARK: Update Stream API
func updateStreamViewAPI()
{
if GAReusableClass.sharedInstance.isNetworkAvailable() == true
{
//GAReusableClass.sharedInstance.showActivityIndicator()
var deviceToken : String = ""
if(defaults.value(forKey:"deviceToken" ) != nil)
{
deviceToken = defaults.value(forKey: "deviceToken") as! String
print(deviceToken)
}
else
{
deviceToken = "12345"
}
let dictionary = ["status": status!,
"device_id": "\(deviceToken)",
"uuid": GAloginUserInfo.shared.loginUserUuid!,
"stream_id": liveStreamID
]
print(dictionary)
let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(dictionary)
{
if let jsonString = String(data: jsonData, encoding: .utf8)
{
print(jsonString)
let cipher:String = CryptoHelper.encrypt(input:jsonString)!;
let NewEncryption = "data=\(cipher)"
let hmac_md5 = cipher.hmac(algorithm: .sha512, key: kHMACKey)
print("hmac",hmac_md5)
defaults.set(hmac_md5, forKey: Headerkey)
print("new encyrption",NewEncryption)
Singleton.sharedInstance.getWebservices(params: NewEncryption, Methodname:"user/updateStreamViewer" , data: Stringnil)
{ (result) in
print(result)
if result != nil
{
do {
let jsonData = try JSONSerialization.data(withJSONObject: result)
if let json = String(data: jsonData, encoding: .utf8)
{
print(json)
let Dict = function.convertToDictionary(text: json)! as NSDictionary
if Dict[KData] != nil
{
self.DataDict = Dict.value(forKey: KData) as! String
print(self.DataDict)
}
else
{
return
}
}
} catch {
// print(Errormsg)
}
let output:String = CryptoHelper.decrypt(input:self.DataDict)!;
print(output)
self.mainDict = function.convertToDictionary(text: output)! as NSDictionary
print(self.mainDict)
let status = self.mainDict[KStatus] as! NSInteger
if(status == 1)
{
DispatchQueue.main.async {
//GAReusableClass.sharedInstance.hideActivityIndicator()
}
}
else
{
//GAReusableClass.sharedInstance.hideActivityIndicator()
DispatchQueue.main.async
{
/* GAAlertClass.showAlertView(vc: self, titleString: "", messageString: self.mainDict[KMessage] as! String) */
}
}
}
else
{
DispatchQueue.main.async
{
//GAReusableClass.sharedInstance.hideActivityIndicator()
GAAlertClass.showAlertView(vc: self, titleString: "", messageString: NSLocalizedString("Server error", comment: ""))
}
}
}
}
}
}
else
{
GAReusableClass.sharedInstance.hideActivityIndicator()
GAAlertClass.showAlertView(vc: self, titleString: "", messageString: NSLocalizedString("noNEtwork", comment: ""))
}
}
//MARK:Get Stream View Count
@objc func getStreamViewCount()
{
if GAReusableClass.sharedInstance.isNetworkAvailable() == true
{
//GAReusableClass.sharedInstance.showActivityIndicator()
var deviceToken : String = ""
if(defaults.value(forKey:"deviceToken" ) != nil)
{
deviceToken = defaults.value(forKey: "deviceToken") as! String
print(deviceToken)
}
else
{
deviceToken = "12345"
}
let dictionary = ["device_id": "\(deviceToken)",
"uuid": GAloginUserInfo.shared.loginUserUuid!,
"stream_id": liveStreamID
]
print(dictionary)
let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(dictionary)
{
if let jsonString = String(data: jsonData, encoding: .utf8)
{
print(jsonString)
let cipher:String = CryptoHelper.encrypt(input:jsonString)!;
let NewEncryption = "data=\(cipher)"
let hmac_md5 = cipher.hmac(algorithm: .sha512, key: kHMACKey)
print("hmac",hmac_md5)
defaults.set(hmac_md5, forKey: Headerkey)
print("new encyrption",NewEncryption)
Singleton.sharedInstance.getWebservices(params: NewEncryption, Methodname:"user/getStreamsViewCount" , data: Stringnil)
{ (result) in
print(result)
if result != nil
{
do {
let jsonData = try JSONSerialization.data(withJSONObject: result)
if let json = String(data: jsonData, encoding: .utf8)
{
print(json)
let Dict = function.convertToDictionary(text: json)! as NSDictionary
if Dict[KData] != nil
{
self.DataDict = Dict.value(forKey: KData) as! String
print(self.DataDict)
}
else
{
return
}
}
} catch {
// print(Errormsg)
}
let output:String = CryptoHelper.decrypt(input:self.DataDict)!;
print(output)
self.mainDict = function.convertToDictionary(text: output)! as NSDictionary
print(self.mainDict)
let status = self.mainDict[KStatus] as! NSInteger
if(status == 1)
{
DispatchQueue.main.async {
//GAReusableClass.sharedInstance.hideActivityIndicator()
let data = self.mainDict[KData] as! NSDictionary
let viewsCount = data.value(forKey: "views_count") as! NSInteger
self.viewsCount.text = "\(viewsCount) Views"
}
}
else
{
//GAReusableClass.sharedInstance.hideActivityIndicator()
DispatchQueue.main.async
{
/* GAAlertClass.showAlertView(vc: self, titleString: "", messageString: self.mainDict[KMessage] as! String) */
}
}
}
else
{
DispatchQueue.main.async
{
//GAReusableClass.sharedInstance.hideActivityIndicator()
GAAlertClass.showAlertView(vc: self, titleString: "", messageString: NSLocalizedString("Server error", comment: ""))
}
}
}
}
}
}
else
{
GAReusableClass.sharedInstance.hideActivityIndicator()
GAAlertClass.showAlertView(vc: self, titleString: "", messageString: NSLocalizedString("noNEtwork", comment: ""))
}
}
//MARK: Play Live Stream Method
func playLiveStream(){
if GAReusableClass.sharedInstance.isNetworkAvailable() == true
{
if player.currentPlayState() == .idle {
self.player.playerView = self.view
player.play(goCoderConfig!, callback: self)
} else {
player.stop()
}
}
else
{
GAReusableClass.sharedInstance.hideActivityIndicator()
GAAlertClass.showAlertView(vc: self, titleString: "", messageString: NSLocalizedString("noNEtwork", comment: ""))
}
}
func licenceKey(){
// Register the GoCoder SDK license key
let goCoderLicensingError: Error? = WowzaGoCoder.registerLicenseKey(SDKSampleAppLicenseKey)
if goCoderLicensingError != nil {
// Handle license key registration failure
// Log license key registration failure
print("\(goCoderLicensingError?.localizedDescription ?? "")")
} else {
player = WOWZPlayer()
player.playerViewGravity = .resizeAspect
//Set default preroll buffer duration
// player.prerollDuration = 3 // Float64(UserDefaults.standard.float(forKey: PlaybackPrerollKey))
//Optionally set up data sink to handle in-stream events
// player.register(self, eventName: "onTextData")
}
}
//MARK: Play LiveStream API
/* func playLiveStreamAPI(){
Singleton.sharedInstance.playLiveStreamGET(Methodname: playerURL, data: Stringnil) { (result) in
print(result)
if result != nil {
do
{
let jsonData = try JSONSerialization.data(withJSONObject: result)
if let json = String(data: jsonData, encoding: .utf8)
{
print(json)
let Dict = function.convertToDictionary(text: json)! as NSDictionary
print(Dict)
let mainDict = Dict.value(forKey: "live_stream") as! NSDictionary
let id = mainDict.value(forKey: "id") as! String
//MARK: get HLS Configs
// let configHLS = mainDict.value(forKey: "delivery_protocols") as! NSDictionary
let urlHLS = mainDict.value(forKey: "player_hls_playback_url") as! String
//self.goCoderConfig?.allowHLSPlayback = true
//self.goCoderConfig?.hlsURL = urlHLS as NSString
print(urlHLS as NSString)
//self.urlHLS = urlHLS
//MARK:Get WOWZA Configs Dynamic Data
let wozwaConfig = mainDict.value(forKey: "source_connection_information") as! NSDictionary
let hostAddressURL = wozwaConfig.value(forKey: "primary_server") as! String
//Main URL
let fileName = hostAddressURL
//Split the String on behalf of "//"
let filearray2 = fileName.components(separatedBy: "//")
//Gets the String After "//"
let finalFileName = filearray2.last
//Split the String on behalf of "/"
let FinalString = finalFileName?.components(separatedBy: "/")
// Get String Value before "/" Charset
let hostAddress = FinalString?.first
self.hostAddress = hostAddress! //get hostAddress
//Get String Value After "/" Charset
let applicationName = FinalString?.last
self.applicationName = applicationName! //get applicationName
//get portnumber
let portNumber = wozwaConfig.value(forKey: "host_port") as! Int
self.hostPort = portNumber
//get streamname
let streamName = wozwaConfig.value(forKey: "stream_name") as! String
self.streamName = streamName
print(hostAddress,UInt(self.hostPort),streamName,applicationName)
self.setupConfig()
//get username
// let userName = wozwaConfig.value(forKey: "username") as! String
// self.userName = userName
//get password
// let password = wozwaConfig.value(forKey: "password") as! String
// self.password = password
}
} catch {
print("error")
}
}
}
}*/
func setupConfig() {
let config = WowzaConfig()
//print(hostAddress,UInt(hostPort),streamName,applicationName)
config.hostAddress = "3.0.155.108"//hostAddress
print(config.hostAddress)
config.portNumber = 1935 //UInt(hostPort)
print(config.portNumber)
config.streamName = streamName
print(config.streamName)
config.applicationName = "Viidoo"//applicationName
print(config.applicationName)
config.audioEnabled = true
config.videoEnabled = true
//If authentication is required
// config.username = userName
// config.password = password
goCoderConfig = config
}
@IBAction func backButtonAction(_ sender: Any) {
if player.currentPlayState() == .running {
player.stop()
}
self.navigationController?.popViewController(animated: true)
}
@IBAction func didTapPlaybackButton(_ sender: Any) {
if player.currentPlayState() == .idle {
player.play(goCoderConfig!, callback: self)
} else {
player.stop()
}
}
//MARK: Send Live Comments
@IBAction func sendCommentButton(_ sender: Any) {
sendLiveComments(from: enterCommentTextField.text!, with: "")
}
//Send Live Comments Method
func sendLiveComments(from comment : String, with image:String){
let databaseRoot = Database.database().reference()
let databaseChats = databaseRoot.child("chats")
let ref = databaseChats.child(streamName).childByAutoId()
let dateTimeStamp = GAloginUserInfo.shared.loginUserUuid! + "-" + String(Date().currentTimeStamp())
//userProfilePic
let profileImageFinalURL = BaseURLProfilePic + GAloginUserInfo.shared.loginUserProfilePic!
print(profileImageFinalURL)
//Ternary Operator (str1 != nil ? true : false)
// liveCommentMessage = messageStickerURL == nil || messageStickerURL == "" ? enterCommentTextField.text! : stickerCommentMessage
print(comment)
let message = ["messagePic": image, "messageUser": GAloginUserInfo.shared.loginUserName!, "messageText": comment,"messageTime":dateTimeStamp,"userPic":profileImageFinalURL,"recieverMessageText":""]
print(message)
ref.setValue(message)
enterCommentTextField.text! = ""
}
//MARK: Send Stricker Gifts
@IBAction func sendStickersButton(_ sender: Any) {
/* if stickersStackView.isHidden {
stickersStackView.isHidden = false
} else {
stickersStackView.isHidden = true
}*/
if stickerContainerView.isHidden {
stickerContainerView.isHidden = false
} else {
stickerContainerView.isHidden = true
}
}
@IBAction func selectStickersButton(_ sender: UIButton) {
switch sender.tag {
case 1:
print("pressed 1")
stickerCommentMessage = "gifted \(liveStreamUserName)"
messageStickerURL = "https://firebasestorage.googleapis.com/v0/b/viidoo.appspot.com/o/live_cartoon_one.png?alt=media&token=f6649d8d-70ed-4b20-beeb-30089a0453e5"
updateStickerGiftAPI(giftAmount:"10", giftPoints:"10")
self.sendLiveComments(from: stickerCommentMessage, with: messageStickerURL)
// stickersStackView.isHidden = true
stickerContainerView.isHidden = true
case 2:
print("pressed 2")
stickerCommentMessage = "gifted \(liveStreamUserName)"
messageStickerURL = "https://firebasestorage.googleapis.com/v0/b/viidoo.appspot.com/o/prefe_cartoon.png?alt=media&token=7ae0dfee-1efe-4e49-a834-fe9845f270f7"
updateStickerGiftAPI(giftAmount:"20", giftPoints:"20")
self.sendLiveComments(from: stickerCommentMessage, with: messageStickerURL)
// stickersStackView.isHidden = true
stickerContainerView.isHidden = true
case 3:
print("pressed 3")
stickerCommentMessage = "gifted \(liveStreamUserName)"
messageStickerURL = "https://firebasestorage.googleapis.com/v0/b/viidoo.appspot.com/o/provider.png?alt=media&token=8ed229c3-78f1-4004-abb9-2484b80d5f2d"
updateStickerGiftAPI(giftAmount:"30", giftPoints:"30")
self.sendLiveComments(from: stickerCommentMessage, with: messageStickerURL)
//stickersStackView.isHidden = true
stickerContainerView.isHidden = true
default:
print("nothing to do")
messageStickerURL = nil
self.sendLiveComments(from: enterCommentTextField.text!, with: "")
//stickersStackView.isHidden = true
stickerContainerView.isHidden = true
}
}
}
extension GAPlayBroadCastViewController : WOWZStatusCallback {
func onWOWZStatus(_ status: WOWZStatus!) {
let statusMessage: String? = nil
switch status.state {
case .idle:
break
case .starting:
self.status = "1"
self.updateStreamViewAPI()
self.getStreamViewCount()
break
// self.player.playerView = self.view
case .running:
break
case .stopping:
self.status = "0"
self.updateStreamViewAPI()
timer?.invalidate()
self.popupAlertWithAction(title: "Alert", message: "The stream has ended", actionTitles: ["Ok"], actions: [{action in
DispatchQueue.main.async {
self.navigationController?.popViewController(animated: true)
}
}
])
//self.navigationController?.popViewController(animated: true)
break
case .buffering:
break
default:
break
}
if statusMessage != nil {
print("Broadcast status: \(statusMessage ?? "")")
}
}
func onWOWZError(_ status: WOWZStatus!) {
print("status" ,status)
timer?.invalidate()
/* self.popupAlertWithAction(title: "Error", message: status.description, actionTitles: ["Ok"], actions: [{action in
self.navigationController?.popViewController(animated: true)
}
])*/
}
}
//MARK:Live Comments
extension GAPlayBroadCastViewController : UITableViewDataSource,UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messageArray.count
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "GALiveCommentsPlayStreamTableViewCell", for: indexPath) as! GALiveCommentsPlayStreamTableViewCell
//MARK :- Reverse the Reponse of BroadCastList
let reveresedBroadCastList = Array(messageArray.reversed())
let obj = reveresedBroadCastList[indexPath.row] // let obj = messageArray[indexPath.row]
//Reverse the Cell to load from bottom
cell.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi));
cell.messageLabel.text = obj.userCommentMessage!
cell.userName.text = obj.userName!
cell.userProfilePic.sd_setImage(with: URL(string: obj.userProfilePic!), placeholderImage: UIImage(named: "defaultUser"))
if obj.giftSticker == nil || obj.giftSticker == "" {
cell.stickerView.isHidden = true
}else {
cell.stickerView.isHidden = false
cell.giftSctickers.sd_setImage(with: URL(string: obj.giftSticker!), placeholderImage: UIImage(named: "ThumbnailImage"))
}
return cell
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment