Skip to content

Commit b71d159

Browse files
chenparkenough0
andauthored
merge ktvapi (#33)
* merge ktvapi * update ktvapi --------- Co-authored-by: CP <[email protected]>
1 parent 122496f commit b71d159

20 files changed

+4128
-1451
lines changed

KTVAPI/iOS/Example/KTVApiDemo/KTVApiDemo.xcodeproj/project.pbxproj

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10-
E3CB4D602A935EBD00322389 /* 成都.xml in Resources */ = {isa = PBXBuildFile; fileRef = E3CB4D5F2A935EBD00322389 /* 成都.xml */; };
10+
E38BDE782B6F7A78007A2834 /* KTVGiantChorusApiImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38BDE772B6F7A77007A2834 /* KTVGiantChorusApiImpl.swift */; };
11+
E38BDE7A2B6F7ABD007A2834 /* ApiManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38BDE792B6F7ABD007A2834 /* ApiManager.swift */; };
12+
E39BAF762B6CC695002C692F /* LrcTime.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = E39BAF742B6CC695002C692F /* LrcTime.pb.swift */; };
13+
E39BAF772B6CC695002C692F /* LrcTime.proto in Sources */ = {isa = PBXBuildFile; fileRef = E39BAF752B6CC695002C692F /* LrcTime.proto */; };
14+
E39BAF792B6CCC65002C692F /* 不如跳舞.xml in Resources */ = {isa = PBXBuildFile; fileRef = E39BAF782B6CCC65002C692F /* 不如跳舞.xml */; };
15+
E39BAF7B2B6CCC74002C692F /* 不如跳舞.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = E39BAF7A2B6CCC74002C692F /* 不如跳舞.mp4 */; };
1116
E3ED270B2A822E9D0087B7AA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3ED270A2A822E9D0087B7AA /* AppDelegate.swift */; };
1217
E3ED270D2A822E9D0087B7AA /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3ED270C2A822E9D0087B7AA /* SceneDelegate.swift */; };
1318
E3ED270F2A822E9D0087B7AA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3ED270E2A822E9D0087B7AA /* ViewController.swift */; };
@@ -28,15 +33,19 @@
2833
E3ED27392A8312120087B7AA /* AgoraStringExtention.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3ED27312A8312120087B7AA /* AgoraStringExtention.swift */; };
2934
E3ED273A2A8312120087B7AA /* AgoraURLExtention.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3ED27322A8312120087B7AA /* AgoraURLExtention.swift */; };
3035
E3ED273B2A8312120087B7AA /* AgoraDownLoadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3ED27332A8312120087B7AA /* AgoraDownLoadManager.swift */; };
31-
E3FE65332B20638D001D6BF9 /* 成都.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = E3FE65322B20638D001D6BF9 /* 成都.mp3 */; };
3236
F33427D772BC45C43FBC8F23 /* Pods_KTVApiDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AFBE8E6CA2314F17EF33468 /* Pods_KTVApiDemo.framework */; };
3337
/* End PBXBuildFile section */
3438

3539
/* Begin PBXFileReference section */
3640
0AFBE8E6CA2314F17EF33468 /* Pods_KTVApiDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KTVApiDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3741
91649F2302F7D5A73F303630 /* Pods-KTVApiDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KTVApiDemo.release.xcconfig"; path = "Target Support Files/Pods-KTVApiDemo/Pods-KTVApiDemo.release.xcconfig"; sourceTree = "<group>"; };
3842
AFA8596CCA93FAF74AD1D2D5 /* Pods-KTVApiDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KTVApiDemo.debug.xcconfig"; path = "Target Support Files/Pods-KTVApiDemo/Pods-KTVApiDemo.debug.xcconfig"; sourceTree = "<group>"; };
39-
E3CB4D5F2A935EBD00322389 /* 成都.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "成都.xml"; sourceTree = "<group>"; };
43+
E38BDE772B6F7A77007A2834 /* KTVGiantChorusApiImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KTVGiantChorusApiImpl.swift; sourceTree = "<group>"; };
44+
E38BDE792B6F7ABD007A2834 /* ApiManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiManager.swift; sourceTree = "<group>"; };
45+
E39BAF742B6CC695002C692F /* LrcTime.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LrcTime.pb.swift; sourceTree = "<group>"; };
46+
E39BAF752B6CC695002C692F /* LrcTime.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = LrcTime.proto; sourceTree = "<group>"; };
47+
E39BAF782B6CCC65002C692F /* 不如跳舞.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "不如跳舞.xml"; sourceTree = "<group>"; };
48+
E39BAF7A2B6CCC74002C692F /* 不如跳舞.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "不如跳舞.mp4"; sourceTree = "<group>"; };
4049
E3ED27072A822E9D0087B7AA /* KTVApiDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KTVApiDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
4150
E3ED270A2A822E9D0087B7AA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
4251
E3ED270C2A822E9D0087B7AA /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@@ -59,7 +68,6 @@
5968
E3ED27312A8312120087B7AA /* AgoraStringExtention.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AgoraStringExtention.swift; sourceTree = "<group>"; };
6069
E3ED27322A8312120087B7AA /* AgoraURLExtention.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AgoraURLExtention.swift; sourceTree = "<group>"; };
6170
E3ED27332A8312120087B7AA /* AgoraDownLoadManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AgoraDownLoadManager.swift; sourceTree = "<group>"; };
62-
E3FE65322B20638D001D6BF9 /* 成都.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "成都.mp3"; sourceTree = "<group>"; };
6371
/* End PBXFileReference section */
6472

6573
/* Begin PBXFrameworksBuildPhase section */
@@ -115,13 +123,14 @@
115123
E3ED27232A8230A00087B7AA /* KeyCenter.swift */,
116124
E3ED270A2A822E9D0087B7AA /* AppDelegate.swift */,
117125
E3ED270C2A822E9D0087B7AA /* SceneDelegate.swift */,
118-
E3CB4D5F2A935EBD00322389 /* 成都.xml */,
119-
E3FE65322B20638D001D6BF9 /* 成都.mp3 */,
120126
E3ED270E2A822E9D0087B7AA /* ViewController.swift */,
127+
E39BAF782B6CCC65002C692F /* 不如跳舞.xml */,
128+
E39BAF7A2B6CCC74002C692F /* 不如跳舞.mp4 */,
121129
E3ED27252A8236750087B7AA /* KTVViewController.swift */,
122130
E3ED27292A826B0D0087B7AA /* KTVLyricView.swift */,
123131
E3ED272B2A8312120087B7AA /* FileDownloadCache */,
124132
E3ED27272A8243480087B7AA /* NetworkManager.swift */,
133+
E38BDE792B6F7ABD007A2834 /* ApiManager.swift */,
125134
E3ED271E2A822ED30087B7AA /* KTVAPI */,
126135
E3ED27102A822E9D0087B7AA /* Main.storyboard */,
127136
E3ED27132A822E9E0087B7AA /* Assets.xcassets */,
@@ -136,6 +145,9 @@
136145
children = (
137146
E3ED271F2A822ED30087B7AA /* KTVApiImpl.swift */,
138147
E3ED27202A822ED30087B7AA /* KTVApi.swift */,
148+
E38BDE772B6F7A77007A2834 /* KTVGiantChorusApiImpl.swift */,
149+
E39BAF742B6CC695002C692F /* LrcTime.pb.swift */,
150+
E39BAF752B6CC695002C692F /* LrcTime.proto */,
139151
);
140152
path = KTVAPI;
141153
sourceTree = "<group>";
@@ -217,9 +229,9 @@
217229
files = (
218230
E3ED27172A822E9E0087B7AA /* LaunchScreen.storyboard in Resources */,
219231
E3ED27142A822E9E0087B7AA /* Assets.xcassets in Resources */,
220-
E3FE65332B20638D001D6BF9 /* 成都.mp3 in Resources */,
221-
E3CB4D602A935EBD00322389 /* 成都.xml in Resources */,
222232
E3ED27122A822E9D0087B7AA /* Main.storyboard in Resources */,
233+
E39BAF7B2B6CCC74002C692F /* 不如跳舞.mp4 in Resources */,
234+
E39BAF792B6CCC65002C692F /* 不如跳舞.xml in Resources */,
223235
);
224236
runOnlyForDeploymentPostprocessing = 0;
225237
};
@@ -275,11 +287,14 @@
275287
E3ED27392A8312120087B7AA /* AgoraStringExtention.swift in Sources */,
276288
E3ED273B2A8312120087B7AA /* AgoraDownLoadManager.swift in Sources */,
277289
E3ED27212A822ED30087B7AA /* KTVApiImpl.swift in Sources */,
290+
E39BAF772B6CC695002C692F /* LrcTime.proto in Sources */,
278291
E3ED27222A822ED30087B7AA /* KTVApi.swift in Sources */,
279292
E3ED270F2A822E9D0087B7AA /* ViewController.swift in Sources */,
280293
E3ED270B2A822E9D0087B7AA /* AppDelegate.swift in Sources */,
281294
E3ED27342A8312120087B7AA /* AgoraMiguXmlLrcParse.swift in Sources */,
295+
E39BAF762B6CC695002C692F /* LrcTime.pb.swift in Sources */,
282296
E3ED27282A8243480087B7AA /* NetworkManager.swift in Sources */,
297+
E38BDE7A2B6F7ABD007A2834 /* ApiManager.swift in Sources */,
283298
E3ED27242A8230A00087B7AA /* KeyCenter.swift in Sources */,
284299
E3ED27382A8312120087B7AA /* AgoraCacheFileHandle.swift in Sources */,
285300
E3ED272A2A826B0D0087B7AA /* KTVLyricView.swift in Sources */,
@@ -288,6 +303,7 @@
288303
E3ED27352A8312120087B7AA /* AgoraLrcParse.swift in Sources */,
289304
E3ED273A2A8312120087B7AA /* AgoraURLExtention.swift in Sources */,
290305
E3ED27372A8312120087B7AA /* AgoraLrcModel.swift in Sources */,
306+
E38BDE782B6F7A78007A2834 /* KTVGiantChorusApiImpl.swift in Sources */,
291307
E3ED27362A8312120087B7AA /* AgoraRequestTask.swift in Sources */,
292308
);
293309
runOnlyForDeploymentPostprocessing = 0;

KTVAPI/iOS/Example/KTVApiDemo/KTVApiDemo.xcodeproj/xcuserdata/cp.xcuserdatad/xcschemes/xcschememanagement.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<key>KTVApiDemo.xcscheme_^#shared#^_</key>
88
<dict>
99
<key>orderHint</key>
10-
<integer>6</integer>
10+
<integer>8</integer>
1111
</dict>
1212
</dict>
1313
</dict>
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
import Foundation
2+
class ApiManager {
3+
static let shared = ApiManager()
4+
5+
// private let domain = "https://api.sd-rtn.com"
6+
private let domain: String = "http://218.205.37.50:16000"
7+
private let testIp: String = "218.205.37.50"
8+
9+
private let TAG = "ApiManager"
10+
11+
private var tokenName = ""
12+
private var taskId = ""
13+
14+
private lazy var session: URLSession = {
15+
let configuration = URLSessionConfiguration.default
16+
configuration.timeoutIntervalForRequest = 30
17+
configuration.timeoutIntervalForResource = 30
18+
19+
return URLSession(configuration: configuration)
20+
}()
21+
22+
func fetchCloudToken() -> String? {
23+
var token: String? = nil
24+
25+
do {
26+
let timeInterval: TimeInterval = Date().timeIntervalSince1970
27+
let millisecond = CLongLong(round(timeInterval*1000))
28+
let acquireOjb = try JSONSerialization.data(withJSONObject: [
29+
"instanceId": "\(Int(millisecond))",
30+
"testIp": testIp,
31+
])
32+
33+
let url = getTokenUrl(domain: domain, appId: KeyCenter.AppId)
34+
guard let requestUrl = URL(string: url) else {return ""}
35+
var request = URLRequest(url: requestUrl)
36+
request.httpMethod = "POST"
37+
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
38+
request.setValue(getBasicAuth(), forHTTPHeaderField: "Authorization")
39+
request.httpBody = acquireOjb
40+
41+
let semaphore = DispatchSemaphore(value: 0)
42+
43+
let task = session.dataTask(with: request) { (data, response, error) in
44+
if let error = error {
45+
print("getToken error: \(error.localizedDescription)")
46+
token = nil
47+
// VLToast.toast("ktv_merge_failed_and create".toSceneLocalization() as String)
48+
} else if let data = data {
49+
do {
50+
guard let responseDict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let tokenName = responseDict["tokenName"] as? String else {
51+
return
52+
}
53+
54+
token = tokenName
55+
} catch {
56+
print("getToken error: \(error.localizedDescription)")
57+
// VLToast.toast("ktv_merge_failed_and create".toSceneLocalization() as String)
58+
token = nil
59+
}
60+
}
61+
62+
semaphore.signal()
63+
}
64+
65+
task.resume()
66+
semaphore.wait()
67+
68+
} catch {
69+
print("getToken error: \(error.localizedDescription)")
70+
//VLToast.toast("ktv_merge_failed_and create")
71+
token = nil
72+
}
73+
74+
return token
75+
}
76+
77+
func fetchStartCloud(mainChannel: String, cloudRtcUid: Int, completion: @escaping ((Bool)->Void)) {
78+
let token = fetchCloudToken()
79+
80+
if token == nil {
81+
print("云端合流uid 请求报错 token is null")
82+
completion(false)
83+
return
84+
} else {
85+
tokenName = token!
86+
}
87+
88+
do {
89+
let inputRetObj: [String: Any] = [
90+
"rtcUid": 0,
91+
"rtcToken": KeyCenter.AppId,
92+
"rtcChannel": mainChannel
93+
]
94+
95+
let intObj: [String: Any] = ["rtc": inputRetObj]
96+
97+
let audioOptionObj: [String: Any] = [
98+
"profileType": "AUDIO_PROFILE_MUSIC_HIGH_QUALITY_STEREO",
99+
"fullChannelMixer": "native-mixer-weighted"
100+
]
101+
102+
let outputRetObj: [String: Any] = [
103+
"rtcUid": cloudRtcUid,
104+
"rtcToken": KeyCenter.AppId,
105+
"rtcChannel": "\(mainChannel)_ad"
106+
]
107+
108+
let dataStreamObj: [String: Any] = [
109+
"source": ["audioMetaData": true],
110+
"sink": [:]
111+
]
112+
113+
let outputsObj: [String: Any] = [
114+
"audioOption": audioOptionObj,
115+
"rtc": outputRetObj,
116+
"metaDataOption": dataStreamObj
117+
]
118+
119+
let transcoderObj: [String: Any] = [
120+
"audioInputs": [intObj],
121+
"idleTimeout": 300,
122+
"outputs": [outputsObj]
123+
]
124+
125+
let postBody: [String: Any] = [
126+
"services": [
127+
"cloudTranscoder": [
128+
"serviceType": "cloudTranscoderV2",
129+
"config": [
130+
"transcoder": transcoderObj
131+
]
132+
]
133+
]
134+
]
135+
136+
let url = startTaskUrl(domain: domain, appId: KeyCenter.AppId, tokenName: tokenName)
137+
guard let requestUrl = URL(string: url) else {return}
138+
var request = URLRequest(url: requestUrl)
139+
request.httpMethod = "POST"
140+
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
141+
request.setValue(getBasicAuth(), forHTTPHeaderField: "Authorization")
142+
request.httpBody = try JSONSerialization.data(withJSONObject: postBody, options: [])
143+
144+
// let semaphore = DispatchSemaphore(value: 0)
145+
146+
let task = session.dataTask(with: request) { (data, response, error) in
147+
if let error = error {
148+
print("云端合流uid 请求报错: \(error.localizedDescription)")
149+
completion(false)
150+
// VLToast.toast("ktv_merge_failed_and create".toSceneLocalization() as String)
151+
} else if let data = data {
152+
do {
153+
guard let responseDict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let taskId = responseDict["taskId"] as? String else {
154+
completion(false)
155+
return
156+
}
157+
158+
self.taskId = taskId
159+
completion(true)
160+
// VLToast.toast("ktv_merge_success".toSceneLocalization() as String)
161+
print("合流成功")
162+
} catch {
163+
print("云端合流uid 请求报错: \(error.localizedDescription)")
164+
completion(false)
165+
// VLToast.toast("ktv_merge_failed_and create".toSceneLocalization() as String)
166+
}
167+
}
168+
169+
// semaphore.signal()
170+
}
171+
172+
task.resume()
173+
// semaphore.wait()
174+
175+
} catch {
176+
print("云端合流uid 请求报错: \(error.localizedDescription)")
177+
completion(false)
178+
// VLToast.toast("ktv_merge_failed_and create".toSceneLocalization() as String)
179+
}
180+
}
181+
182+
func fetchStopCloud() {
183+
if taskId.isEmpty || tokenName.isEmpty {
184+
print("云端合流任务停止失败 taskId || tokenName is null")
185+
return
186+
}
187+
188+
do {
189+
let url = deleteTaskUrl(domain: domain, appid: KeyCenter.AppId, taskid: taskId, tokenName: tokenName)
190+
guard let requestUrl = URL(string: url) else {return}
191+
var request = URLRequest(url: requestUrl)
192+
request.httpMethod = "DELETE"
193+
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
194+
request.setValue(getBasicAuth(), forHTTPHeaderField: "Authorization")
195+
196+
// let semaphore = DispatchSemaphore(value: 0)
197+
198+
let task = session.dataTask(with: request) { (data, response, error) in
199+
// Handle response
200+
201+
// semaphore.signal()
202+
}
203+
204+
task.resume()
205+
// semaphore.wait()
206+
207+
} catch {
208+
print("云端合流任务停止失败: \(error.localizedDescription)")
209+
}
210+
}
211+
212+
private func getTokenUrl(domain: String, appId: String) -> String {
213+
return String(format: "%@/v1/projects/%@/rtsc/cloud-transcoder/builderTokens", domain, appId)
214+
}
215+
216+
private func startTaskUrl(domain: String, appId: String, tokenName: String) -> String {
217+
return String(format: "%@/v1/projects/%@/rtsc/cloud-transcoder/tasks?builderToken=%@", domain, appId, tokenName)
218+
}
219+
220+
private func deleteTaskUrl(domain: String, appid: String, taskid: String, tokenName: String) -> String {
221+
return String(format: "%@/v1/projects/%@/rtsc/cloud-transcoder/tasks/%@?builderToken=%@", domain, appid, taskid, tokenName)
222+
}
223+
224+
private func getBasicAuth() -> String {
225+
// 拼接客户 ID 和客户密钥并使用 base64 编码
226+
let plainCredentials = "\(KeyCenter.CloudPlayerKey!):\(KeyCenter.CloudPlayerSecret!)"
227+
guard let base64Credentials = plainCredentials.data(using: .utf8)?.base64EncodedString() else {
228+
return ""
229+
}
230+
// 创建 authorization header
231+
return "Basic \(base64Credentials)"
232+
}
233+
234+
}

0 commit comments

Comments
 (0)