Commit 253855c2 authored by Alex朱枝文's avatar Alex朱枝文

添加rtc播放的示例

parent 8079abe0
......@@ -34,6 +34,7 @@
040AE9992CF5CB1D00310241 /* YHSelectLookHeadView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 040AE9982CF5CB1D00310241 /* YHSelectLookHeadView.swift */; };
04129E862CD0C8490072F87B /* YHAliYunLogManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04129E852CD0C8490072F87B /* YHAliYunLogManager.swift */; };
041390692C1081FA0098CB8A /* YHFileListEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041390682C1081FA0098CB8A /* YHFileListEmptyView.swift */; };
0413A9AD2CFB086A00304BC6 /* YHSimpleAudienceVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0413A9AC2CFB086A00304BC6 /* YHSimpleAudienceVC.swift */; };
0414708B2C88627B00B7B688 /* YHButlerServiceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0414708A2C88627B00B7B688 /* YHButlerServiceManager.swift */; };
0414708E2C895A9300B7B688 /* YHButlerServiceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0414708D2C895A9300B7B688 /* YHButlerServiceViewModel.swift */; };
041470922C898EB700B7B688 /* YHGalaxyManagerTipsItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041470912C898EB700B7B688 /* YHGalaxyManagerTipsItemView.swift */; };
......@@ -1104,6 +1105,7 @@
040AE9982CF5CB1D00310241 /* YHSelectLookHeadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSelectLookHeadView.swift; sourceTree = "<group>"; };
04129E852CD0C8490072F87B /* YHAliYunLogManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHAliYunLogManager.swift; sourceTree = "<group>"; };
041390682C1081FA0098CB8A /* YHFileListEmptyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHFileListEmptyView.swift; sourceTree = "<group>"; };
0413A9AC2CFB086A00304BC6 /* YHSimpleAudienceVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSimpleAudienceVC.swift; sourceTree = "<group>"; };
0414708A2C88627B00B7B688 /* YHButlerServiceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHButlerServiceManager.swift; sourceTree = "<group>"; };
0414708D2C895A9300B7B688 /* YHButlerServiceViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHButlerServiceViewModel.swift; sourceTree = "<group>"; };
041470912C898EB700B7B688 /* YHGalaxyManagerTipsItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGalaxyManagerTipsItemView.swift; sourceTree = "<group>"; };
......@@ -2978,6 +2980,7 @@
04564D7F2CF8E16C004456E4 /* YHPlayerTransitionAnimator.swift */,
04564D7B2CF8CF6D004456E4 /* YHPlayer.swift */,
04564D602CF59835004456E4 /* YHMessageInputViewController.swift */,
0413A9AC2CFB086A00304BC6 /* YHSimpleAudienceVC.swift */,
);
path = C;
sourceTree = "<group>";
......@@ -6522,6 +6525,7 @@
045792152CBD041F00EBD99B /* YHResignUploadTravelHKTableViewCell.swift in Sources */,
04C8F4832B7216D800ADF59B /* YHUserInfoHeaderView.swift in Sources */,
045EEEAF2B9F171A0022A143 /* YHWorkExperienceTextItemView.swift in Sources */,
0413A9AD2CFB086A00304BC6 /* YHSimpleAudienceVC.swift in Sources */,
A5ACE9492B4564F7002C94D2 /* YHHUDSuccessView.swift in Sources */,
04B360EF2C620975001EB053 /* YHPrincipleUploadStatusCell.swift in Sources */,
044EE2252C90138000A2FE3A /* YHServerCenterHoldViewController.swift in Sources */,
......
//
// YHSimpleAudienceVC.swift
// galaxy
//
// Created by alexzzw on 2024/11/30.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import AgoraRtcKit
import UIKit
class YHSimpleAudienceVC: UIViewController {
// MARK: - Properties
private var agoraKit: AgoraRtcEngineKit!
private var isJoined: Bool = false
private var remoteView: UIView!
private var channelName: String = "1732950381844975000"
private let viewModel = YHLiveSalesViewModel()
private let liveId: Int = 34
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
setupAgoraKit()
joinChannel()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
leaveChannel()
}
// MARK: - Setup
private func setupUI() {
// Setup remote video view
remoteView = UIView()
view.addSubview(remoteView)
remoteView.frame = view.bounds
remoteView.backgroundColor = .black
}
private func setupAgoraKit() {
// Initialize AgoraRtcEngineKit
let config = AgoraRtcEngineConfig()
config.appId = YhConstant.AgoraRtcKit.appId
config.channelProfile = .liveBroadcasting
agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self)
// Enable video
agoraKit.enableVideo()
// Set client role as audience
let options = AgoraClientRoleOptions()
options.audienceLatencyLevel = .lowLatency
agoraKit.setClientRole(.audience, options: options)
// Set audio route to speaker
agoraKit.setDefaultAudioRouteToSpeakerphone(true)
}
// MARK: - Channel
private func joinChannel() {
// Create media options
let option = AgoraRtcChannelMediaOptions()
option.publishCameraTrack = false
option.publishMicrophoneTrack = false
option.clientRoleType = .audience
viewModel.getLiveDetail(id: liveId) { [weak self] liveDetail, error in
guard let self = self else {
return
}
guard let liveDetail = liveDetail else {
return
}
self.agoraKit.preloadChannel(byToken: liveDetail.token,
channelId: channelName,
uid: UInt(self.liveId))
let result = self.agoraKit.joinChannel(byToken: liveDetail.token,
channelId: channelName,
uid: UInt(self.liveId),
mediaOptions: option)
if result != 0 {
print("Join channel failed: \(result)")
}
}
// viewModel.generateToken(channelName: channelName, uid: 0) { [weak self] token in
// guard let self = self else {
// return
// }
// self.agoraKit.preloadChannel(byToken: token,
// channelId: channelName,
// uid: 0)
// let result = self.agoraKit.joinChannel(byToken: token,
// channelId: channelName,
// uid: 0,
// mediaOptions: option)
//
// if result != 0 {
// print("Join channel failed: \(result)")
// }
// }
}
private func leaveChannel() {
if isJoined {
agoraKit.disableVideo()
agoraKit.disableAudio()
agoraKit.leaveChannel(nil)
AgoraRtcEngineKit.destroy()
}
}
}
// MARK: - AgoraRtcEngineDelegate
extension YHSimpleAudienceVC: AgoraRtcEngineDelegate {
// Called when successfully joined the channel
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) {
isJoined = true
print("Local user joined with uid \(uid)")
}
// Called when a remote user joins
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.view = remoteView
videoCanvas.renderMode = .hidden
agoraKit.setupRemoteVideo(videoCanvas)
}
// Called when a remote user leaves
func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) {
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.view = nil
agoraKit.setupRemoteVideo(videoCanvas)
}
// Called when warning occurs
func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurWarning warningCode: AgoraWarningCode) {
print("Warning: \(warningCode.rawValue)")
}
// Called when error occurs
func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurError errorCode: AgoraErrorCode) {
print("Error: \(errorCode.rawValue)")
}
}
......@@ -21,6 +21,7 @@ class YHLiveDetailModel: SmartCodable {
var roomId: String = ""
var pullUrl: String = ""
var goods: [YHLiveGoodsItem] = []
var token: String = ""
// 直播封面
var live_image: String = ""
......
......@@ -175,4 +175,39 @@ extension YHLiveSalesViewModel {
callback(false, err)
}
}
func generateToken(channelName: String, uid: UInt = 0, success: @escaping (String?) -> Void) {
guard let certificate = YhConstant.AgoraRtcKit.certificate, !certificate.isEmpty else {
success(nil)
return
}
let params = ["appCertificate": certificate,
"appId": YhConstant.AgoraRtcKit.appId,
"channelName": channelName,
"expire": 900,
"src": "iOS",
"ts": "".timeStamp,
"type": 1,
"uid": "\(uid)"] as [String: Any]
let strUrl = "https://toolbox.bj2.agoralab.co/v1/token/generate"
_ = YHNetRequest.postRequest(url: strUrl, params: params) { response, code in
// 1. json字符串 转 对象
if let dict = response.data?.peel as? [String: String] {
let token = dict["token"]
success(token)
}
success(nil)
} failBlock: { err in
success(nil)
}
}
}
private extension String {
var timeStamp: String {
let date = Date()
let timeInterval = date.timeIntervalSince1970
let millisecond = CLongLong(timeInterval * 1000)
return "\(millisecond)"
}
}
......@@ -98,8 +98,13 @@ class YHMyViewController: YHBaseViewController, ConstraintRelatableTarget {
[weak self] in
guard let self = self else { return }
if !checkLogin() { return }
let vc = YHMySettingViewController()//let vc = YHLivePlayerViewController(id: 2)
let vc = YHMySettingViewController()
self.navigationController?.pushViewController(vc)
// let url = "https://pull-flv-l11.douyincdn.com/thirdgame/stream-116296425803875148.flv?expire=1733558990&sign=cc69d0ac884efe3613385140611c1702&major_anchor_level=common&abr_pts=-800&_session_id=037-2024113016095034A5715FA5656D873A69.1732954190959.73911&rsi=1"
// YHPlayerManager.shared.enterLive(from: nil, id: 23, url: url)
// for test
// let vc = YHSimpleAudienceVC()
// self.navigationController?.pushViewController(vc)
}
view.evaluateBlock = {
......@@ -342,90 +347,90 @@ extension YHMyViewController : UITableViewDelegate, UITableViewDataSource {
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = YHIMTestViewController()
// let vc = YHIMTestViewController()
// self.navigationController?.pushViewController(vc)
// return //for test hjl
if (indexPath.row >= items.count) { return }
if !checkLogin() {
return
}
let item: PersonalModuleItem = items[indexPath.row]
switch item.type {
case .myCard://我的名片
if let userId = YHLoginManager.shared.userModel?.id, !userId.isEmpty {
let vc = YHNameCardViewController()
vc.userId = userId
self.navigationController?.pushViewController(vc)
return //for test hjl
} else {
YHHUD.show(.progress(message: "加载中..."))
self.loginViewModel.getUserId {
[weak self] uid in
YHHUD.hide()
guard let self = self else { return }
if !uid.isEmpty {
YHLoginManager.shared.userModel?.id = uid
let vc = YHNameCardViewController()
vc.userId = uid
self.navigationController?.pushViewController(vc)
}
}
}
case .myMessage://我的消息
printLog("我的消息")
goToMessagePage()
// if (indexPath.row >= items.count) { return }
//
// if !checkLogin() {
// return
// }
//
// let item: PersonalModuleItem = items[indexPath.row]
// switch item.type {
// case .myCard://我的名片
// if let userId = YHLoginManager.shared.userModel?.id, !userId.isEmpty {
// let vc = YHNameCardViewController()
// vc.userId = userId
// self.navigationController?.pushViewController(vc)
// } else {
// YHHUD.show(.progress(message: "加载中..."))
// self.loginViewModel.getUserId {
// [weak self] uid in
// YHHUD.hide()
// guard let self = self else { return }
// if !uid.isEmpty {
// YHLoginManager.shared.userModel?.id = uid
// let vc = YHNameCardViewController()
// vc.userId = uid
// self.navigationController?.pushViewController(vc)
// }
// }
// }
// case .myMessage://我的消息
// printLog("我的消息")
// goToMessagePage()
//
// case .scoreCenter:////积分中心
// printLog("积分中心")
// if let param = YHLoginManager.shared.userModel?.token,param.count>5 {
// printLog(param)
// var url = YHBaseUrlManager.shared.curH5URL() + "superApp/integral"
// url = url + "?param=" + YHLoginManager.shared.h5Token
//
// let vc = YHH5WebViewVC()
// vc.navTitle = "积分中心"
// vc.url = url
// vc.isFullScreenFlag = false
// vc.isSupportWebviewInterBackFlag = true
// self.navigationController?.pushViewController(vc)
// }
// case .myTestCode://我的测评码
// printLog("我的测评码")
// let vc = YHHomeWebViewController()
// vc.vcTitle = "香港身份测评码"
// vc.showSavePicBottomFlag = true
// vc.url = "https://cdn-public.galaxy-immi.com/app/cepingma.png"
// self.navigationController?.pushViewController(vc)
// case .appointGalaxyBay://预约银河湾
// printLog("预约银河湾")
// let vc = YHListViewController()
// self.navigationController?.pushViewController(vc)
// case .myActivity:
// printLog("我的活动")
// let vc = YHActivityListViewController()
// vc.type = 1
// self.navigationController?.pushViewController(vc)
// case .aboutUs:
// let vc = YHAboutGalaxyViewController()
// self.navigationController?.pushViewController(vc)
// case .myOrder:
//// 我的订单
// if let token = YHLoginManager.shared.userModel?.token,token.count > 5 {
// var url = YHBaseUrlManager.shared.curH5URL() + "superAppBridge.html#/order/my"
// url = url + "?param=" + YHLoginManager.shared.h5Token
// printLog("URL: \(url)")
// let vc = YHH5WebViewVC()
// vc.url = url
// vc.isFullScreenFlag = false
// vc.navTitle = "我的订单"
// vc.isSupportWebviewInterBackFlag = true
// UIViewController.current?.navigationController?.pushViewController(vc)
// }
// default:
// printLog("不需要响应")
// }
case .scoreCenter:////积分中心
printLog("积分中心")
if let param = YHLoginManager.shared.userModel?.token,param.count>5 {
printLog(param)
var url = YHBaseUrlManager.shared.curH5URL() + "superApp/integral"
url = url + "?param=" + YHLoginManager.shared.h5Token
let vc = YHH5WebViewVC()
vc.navTitle = "积分中心"
vc.url = url
vc.isFullScreenFlag = false
vc.isSupportWebviewInterBackFlag = true
self.navigationController?.pushViewController(vc)
}
case .myTestCode://我的测评码
printLog("我的测评码")
let vc = YHHomeWebViewController()
vc.vcTitle = "香港身份测评码"
vc.showSavePicBottomFlag = true
vc.url = "https://cdn-public.galaxy-immi.com/app/cepingma.png"
self.navigationController?.pushViewController(vc)
case .appointGalaxyBay://预约银河湾
printLog("预约银河湾")
let vc = YHListViewController()
self.navigationController?.pushViewController(vc)
case .myActivity:
printLog("我的活动")
let vc = YHActivityListViewController()
vc.type = 1
self.navigationController?.pushViewController(vc)
case .aboutUs:
let vc = YHAboutGalaxyViewController()
self.navigationController?.pushViewController(vc)
case .myOrder:
// 我的订单
if let token = YHLoginManager.shared.userModel?.token,token.count > 5 {
var url = YHBaseUrlManager.shared.curH5URL() + "superAppBridge.html#/order/my"
url = url + "?param=" + YHLoginManager.shared.h5Token
printLog("URL: \(url)")
let vc = YHH5WebViewVC()
vc.url = url
vc.isFullScreenFlag = false
vc.navTitle = "我的订单"
vc.isSupportWebviewInterBackFlag = true
UIViewController.current?.navigationController?.pushViewController(vc)
}
default:
printLog("不需要响应")
}
}
private func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> CGFloat {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment