Commit 8f50fa3e authored by pete谢兆麟's avatar pete谢兆麟

翻译文件

parent 1ea5bb9e
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
0411CF182D1D502D00644D35 /* YHlifeCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0411CF172D1D502D00644D35 /* YHlifeCollectionReusableView.swift */; }; 0411CF182D1D502D00644D35 /* YHlifeCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0411CF172D1D502D00644D35 /* YHlifeCollectionReusableView.swift */; };
0411CF1A2D22960900644D35 /* YHGCWorkExperienceListReasonTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0411CF192D22960900644D35 /* YHGCWorkExperienceListReasonTableViewCell.swift */; }; 0411CF1A2D22960900644D35 /* YHGCWorkExperienceListReasonTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0411CF192D22960900644D35 /* YHGCWorkExperienceListReasonTableViewCell.swift */; };
0411CF1C2D2BA99500644D35 /* YHGCWorkExperienceListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0411CF1B2D2BA99500644D35 /* YHGCWorkExperienceListTableViewCell.swift */; }; 0411CF1C2D2BA99500644D35 /* YHGCWorkExperienceListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0411CF1B2D2BA99500644D35 /* YHGCWorkExperienceListTableViewCell.swift */; };
0411DD582DEFE92700D8FF1C /* SpeechRecognitionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0411DD572DEFE90600D8FF1C /* SpeechRecognitionManager.swift */; }; 0411DD582DEFE92700D8FF1C /* NuiSdkUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0411DD572DEFE90600D8FF1C /* NuiSdkUtils.swift */; };
041938712D2B722D00C7A52A /* YHGCCollegeSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041938702D2B722D00C7A52A /* YHGCCollegeSearchViewController.swift */; }; 041938712D2B722D00C7A52A /* YHGCCollegeSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041938702D2B722D00C7A52A /* YHGCCollegeSearchViewController.swift */; };
041CCDF72D7ED9030015E7BC /* YHHKVisaRenewalPaymentInfoList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041CCDF62D7ED9030015E7BC /* YHHKVisaRenewalPaymentInfoList.swift */; }; 041CCDF72D7ED9030015E7BC /* YHHKVisaRenewalPaymentInfoList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041CCDF62D7ED9030015E7BC /* YHHKVisaRenewalPaymentInfoList.swift */; };
041CCDF92D7EE8B90015E7BC /* YHVisaRenewalPayMemberCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041CCDF82D7EE8B90015E7BC /* YHVisaRenewalPayMemberCell.swift */; }; 041CCDF92D7EE8B90015E7BC /* YHVisaRenewalPayMemberCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041CCDF82D7EE8B90015E7BC /* YHVisaRenewalPayMemberCell.swift */; };
...@@ -1347,7 +1347,7 @@ ...@@ -1347,7 +1347,7 @@
0411CF172D1D502D00644D35 /* YHlifeCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHlifeCollectionReusableView.swift; sourceTree = "<group>"; }; 0411CF172D1D502D00644D35 /* YHlifeCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHlifeCollectionReusableView.swift; sourceTree = "<group>"; };
0411CF192D22960900644D35 /* YHGCWorkExperienceListReasonTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCWorkExperienceListReasonTableViewCell.swift; sourceTree = "<group>"; }; 0411CF192D22960900644D35 /* YHGCWorkExperienceListReasonTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCWorkExperienceListReasonTableViewCell.swift; sourceTree = "<group>"; };
0411CF1B2D2BA99500644D35 /* YHGCWorkExperienceListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCWorkExperienceListTableViewCell.swift; sourceTree = "<group>"; }; 0411CF1B2D2BA99500644D35 /* YHGCWorkExperienceListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCWorkExperienceListTableViewCell.swift; sourceTree = "<group>"; };
0411DD572DEFE90600D8FF1C /* SpeechRecognitionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpeechRecognitionManager.swift; sourceTree = "<group>"; }; 0411DD572DEFE90600D8FF1C /* NuiSdkUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NuiSdkUtils.swift; sourceTree = "<group>"; };
0411DD5B2DEFF03300D8FF1C /* nuisdk.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = nuisdk.framework; sourceTree = "<group>"; }; 0411DD5B2DEFF03300D8FF1C /* nuisdk.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = nuisdk.framework; sourceTree = "<group>"; };
041938702D2B722D00C7A52A /* YHGCCollegeSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCCollegeSearchViewController.swift; sourceTree = "<group>"; }; 041938702D2B722D00C7A52A /* YHGCCollegeSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCCollegeSearchViewController.swift; sourceTree = "<group>"; };
041CCDF62D7ED9030015E7BC /* YHHKVisaRenewalPaymentInfoList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHHKVisaRenewalPaymentInfoList.swift; sourceTree = "<group>"; }; 041CCDF62D7ED9030015E7BC /* YHHKVisaRenewalPaymentInfoList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHHKVisaRenewalPaymentInfoList.swift; sourceTree = "<group>"; };
...@@ -2783,7 +2783,7 @@ ...@@ -2783,7 +2783,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0411DD5B2DEFF03300D8FF1C /* nuisdk.framework */, 0411DD5B2DEFF03300D8FF1C /* nuisdk.framework */,
0411DD572DEFE90600D8FF1C /* SpeechRecognitionManager.swift */, 0411DD572DEFE90600D8FF1C /* NuiSdkUtils.swift */,
04B18BC02DF01DC200A287A5 /* YHVoiceDemo.swift */, 04B18BC02DF01DC200A287A5 /* YHVoiceDemo.swift */,
); );
path = Voice; path = Voice;
...@@ -8399,7 +8399,7 @@ ...@@ -8399,7 +8399,7 @@
045C13A62D12CA5F00BD2DC0 /* YHTravelDocsPreparationViewModel.swift in Sources */, 045C13A62D12CA5F00BD2DC0 /* YHTravelDocsPreparationViewModel.swift in Sources */,
045C13A72D12CA5F00BD2DC0 /* YHWorkExampleMessageTableViewCell.swift in Sources */, 045C13A72D12CA5F00BD2DC0 /* YHWorkExampleMessageTableViewCell.swift in Sources */,
045C13A82D12CA5F00BD2DC0 /* YHBasicInfoCellModel.swift in Sources */, 045C13A82D12CA5F00BD2DC0 /* YHBasicInfoCellModel.swift in Sources */,
0411DD582DEFE92700D8FF1C /* SpeechRecognitionManager.swift in Sources */, 0411DD582DEFE92700D8FF1C /* NuiSdkUtils.swift in Sources */,
04AE20292D13B20900891D24 /* YHGCSpouseInfoContainerVC.swift in Sources */, 04AE20292D13B20900891D24 /* YHGCSpouseInfoContainerVC.swift in Sources */,
045C13A92D12CA5F00BD2DC0 /* YHAllowUseMyInfoViewController.swift in Sources */, 045C13A92D12CA5F00BD2DC0 /* YHAllowUseMyInfoViewController.swift in Sources */,
045C13AA2D12CA5F00BD2DC0 /* YHServiceCenterProgressModel.swift in Sources */, 045C13AA2D12CA5F00BD2DC0 /* YHServiceCenterProgressModel.swift in Sources */,
......
//
// SpeechRecognitionManager.swift
// galaxy
//
// Created by EDY on 2025/6/4.
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
import Foundation
import AdSupport
import CommonCrypto
enum TokenTicketType: Int {
case getStsAccessFromServerForOnlineFeatures = 0
case getStsAccessFromServerForOfflineFeatures = 1
case getStsAccessFromServerForMixedFeatures = 2
case getTokenFromServerForOnlineFeatures = 3
case getAccessFromServerForOfflineFeatures = 4
case getAccessFromServerForMixedFeatures = 5
case getTokenInClientForOnlineFeatures = 6
case getAccessInClientForOfflineFeatures = 7
case getAccessInClientForMixedFeatures = 8
case getAccessInClientForOnlineFeatures = 9
case getStsAccessInClientForOnlineFeatures = 10
case getStsAccessInClientForOfflineFeatures = 11
case getStsAccessInClientForMixedFeatures = 12
}
class NuiSdkUtils {
static let shared = NuiSdkUtils()
var curTokenExpiredTime: UInt = 0
var curTokenTicketType: TokenTicketType = .getStsAccessFromServerForOnlineFeatures
var curAppkey: String = ""
var curToken: String = ""
// MARK: - 文件目录操作
/// 获取文档目录
func dirDoc() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
debugPrint("app_home_doc: \(documentsDirectory)")
return documentsDirectory
}
/// 创建语音文件保存目录
func createDir() -> String {
let documentsPath = dirDoc()
let fileManager = FileManager.default
let testDirectory = documentsPath.appending("/voices")
do {
try fileManager.createDirectory(atPath: testDirectory, withIntermediateDirectories: true, attributes: nil)
debugPrint("文件夹创建成功")
} catch {
debugPrint("文件夹创建失败: \(error.localizedDescription)")
}
return testDirectory
}
// MARK: - 鉴权相关
/// 获取凭证
func getTicket(_ dict: inout [String: Any], type: TokenTicketType) {
// 项目创建appkey
let APPKEY = "<您申请创建的app_key>"
dict["app_key"] = APPKEY
self.curTokenTicketType = type
self.curAppkey = APPKEY
switch type {
case .getStsAccessFromServerForOnlineFeatures:
let STS_AK_ID = "STS.<服务器生成的具有时效性的临时凭证>"
let STS_AK_SECRET = "<服务器生成的具有时效性的临时凭证>"
let STS_TOKEN = "<服务器生成的具有时效性的临时凭证>"
let TOKEN = generateToken(accessKey: STS_AK_ID, secret: STS_AK_SECRET, stsToken: STS_TOKEN)
if TOKEN.isEmpty {
print("generate token failed")
return
}
dict["token"] = TOKEN
self.curToken = TOKEN
case .getStsAccessFromServerForOfflineFeatures:
let STS_AK_ID = "STS.<服务器生成的具有时效性的临时凭证>"
let STS_AK_SECRET = "<服务器生成的具有时效性的临时凭证>"
let STS_TOKEN = "<服务器生成的具有时效性的临时凭证>"
dict["ak_id"] = STS_AK_ID
dict["ak_secret"] = STS_AK_SECRET
dict["sts_token"] = STS_TOKEN
let sdk_code = "software_nls_tts_offline_standard"
dict["sdk_code"] = sdk_code
// 其他case实现类似...
// 这里省略了其他类型的实现,实际使用时需要补充完整
default:
break
}
}
/// 生成Token
func generateToken(accessKey: String, secret: String, stsToken: String) -> String {
// 这里需要实现实际的Token生成逻辑
// 示例代码,实际应该使用阿里云提供的Token生成方法
let combined = "\(accessKey):\(secret):\(stsToken)"
let token = combined.data(using: .utf8)?.base64EncodedString() ?? ""
self.curTokenExpiredTime = UInt(Date().timeIntervalSince1970) + 3600 // 假设1小时过期
print("Token expire time is \(self.curTokenExpiredTime)")
return token
}
/// 刷新Token(如果需要)
func refreshTokenIfNeed(_ json: inout [String: Any], distanceExpireTime: Int64) {
guard !self.curAppkey.isEmpty, !self.curToken.isEmpty, self.curTokenExpiredTime > 0 else {
return
}
let millis = Int64(Date().timeIntervalSince1970 * 1000)
let unixTimestampInSeconds = millis / 1000
if Int64(self.curTokenExpiredTime) - distanceExpireTime < unixTimestampInSeconds {
let oldToken = self.curToken
let oldExpireTime = self.curTokenExpiredTime
var ticketJsonDict = [String: Any]()
getTicket(&ticketJsonDict, type: self.curTokenTicketType)
if let newToken = ticketJsonDict["token"] as? String {
self.curToken = newToken
if self.curToken.isEmpty {
debugPrint("The 'token' key exists but the value is empty.")
}
json["token"] = self.curToken
} else {
debugPrint("The 'token' key does not exist.")
}
if let newAppkey = ticketJsonDict["app_key"] as? String {
self.curAppkey = newAppkey
if self.curAppkey.isEmpty {
debugPrint("The 'app_key' key exists but the value is empty.")
}
json["app_key"] = self.curAppkey
} else {
debugPrint("The 'app_key' key does not exist.")
}
let newToken = self.curToken
let newExpireTime = self.curTokenExpiredTime
print("Refresh old token(\(oldToken) : \(oldExpireTime)) to (\(newToken) : \(newExpireTime)).")
}
}
// MARK: - 其他工具方法
/// 获取直接IP
func getDirectIp() -> String {
let MAX_HOST_IP_LENGTH = 16
guard let remoteHostEnt = gethostbyname("nls-gateway-inner.aliyuncs.com") else {
print("demo get host failed!")
return ""
}
let remoteInAddr = remoteHostEnt.pointee.h_addr_list[0]?.withMemoryRebound(to: in_addr.self, capacity: 1) { $0 }
var ip = [CChar](repeating: 0, count: MAX_HOST_IP_LENGTH)
inet_ntop(AF_INET, remoteInAddr, &ip, socklen_t(MAX_HOST_IP_LENGTH))
return String(cString: ip)
}
/// 获取错误引导信息
func getGuideWithError(_ errorCode: Int, error errMesg: String, status: String) -> String {
var str = errMesg
switch errorCode {
case 140001:
str = "错误信息: 引擎未创建, 请检查是否成功初始化, 详情可查看运行日志."
case 140008:
str = "错误信息: 鉴权失败, 请关注日志中详细失败原因."
case 140011:
str = "错误信息: 当前方法调用不符合当前状态, 比如在未初始化情况下调用pause接口."
case 140013:
str = "错误信息: 当前方法调用不符合当前状态, 比如在未初始化情况下调用pause/release等接口."
case 140900:
str = "错误信息: tts引擎初始化失败, 请检查资源路径和资源文件是否正确."
case 140901:
str = "错误信息: tts引擎初始化失败, 请检查使用的SDK是否支持离线语音合成功能."
// 其他错误码处理...
default:
if status.contains("403 Forbidden") {
str = "错误信息: 流式语音合成未成功连接服务, 请检查设置的账号临时凭证."
} else if status.contains("404 Forbidden") {
str = "错误信息: 流式语音合成未成功连接服务, 请检查设置的服务地址URL."
} else if errMesg.contains("FREE_TRIAL_EXPIRED") {
str = "错误信息: 此账号试用期已过, 请开通商用版或检查账号权限."
}
}
return str
}
}
//
// SpeechRecognitionManager.swift
// galaxy
//
// Created by EDY on 2025/6/4.
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
// class SpeechRecognitionManager {
// static let shared = SpeechRecognitionManager()
//
// private var recognizer: NlsSpeechRecognizer?
// private var fileTrans: NlsFileTrans?
//
// // 配置你的阿里云信息
// private let accessKeyId = "your_access_key_id"
// private let accessKeySecret = "your_access_key_secret"
// private let appKey = "your_app_key"
//
// private init() {
// setupCredentials()
// }
//
// private func setupCredentials() {
// let config = AlibabaCloudCredentialConfig()
// config.accessKeyId = accessKeyId
// config.accessKeySecret = accessKeySecret
//
// let provider = AlibabaCloudStaticCredentialProvider(config: config)
// AlibabaCloudCredential.default = provider
// }
// }
//
// extension SpeechRecognitionManager {
// func startRealTimeRecognition(resultHandler: @escaping (String?, Error?) -> Void) {
// recognizer = NlsSpeechRecognizer()
//
// // 配置识别参数
// let request = NlsSpeechRecognizerRequest()
// request.appkey = appKey
// request.format = "pcm" // 音频格式
// request.sampleRate = 16000 // 采样率
//
// // 设置回调
// recognizer?.onRecognizationStarted = {
// print("识别开始")
// }
//
// recognizer?.onTaskFailed = { error in
// print("识别失败: \(error.localizedDescription)")
// resultHandler(nil, error)
// }
//
// recognizer?.onRecognizationCompleted = { result in
// if let text = result.result {
// print("识别结果: \(text)")
// resultHandler(text, nil)
// }
// }
//
// recognizer?.onChannelClosed = {
// print("通道关闭")
// }
//
// // 开始识别
// do {
// try recognizer?.start(request: request)
// } catch {
// print("启动识别失败: \(error.localizedDescription)")
// resultHandler(nil, error)
// }
// }
//
// func stopRealTimeRecognition() {
// recognizer?.stop()
// recognizer = nil
// }
//
// func pushAudioData(_ data: Data) {
// recognizer?.sendAudio(data: data)
// }
// }
//
// extension SpeechRecognitionManager {
// func transcribeAudioFile(fileURL: URL, completion: @escaping (String?, Error?) -> Void) {
// fileTrans = NlsFileTrans()
//
// let request = NlsFileTransRequest()
// request.appkey = appKey
// request.fileLink = fileURL.absoluteString
// request.format = "pcm" // 根据实际文件格式设置
// request.sampleRate = 16000
//
// fileTrans?.onTaskFailed = { error in
// print("文件转写失败: \(error.localizedDescription)")
// completion(nil, error)
// }
//
// fileTrans?.onTranscriptionCompleted = { result in
// if let text = result.result {
// print("转写结果: \(text)")
// completion(text, nil)
// }
// }
//
// do {
// try fileTrans?.start(request: request)
// } catch {
// print("启动文件转写失败: \(error.localizedDescription)")
// completion(nil, error)
// }
// }
// }
...@@ -7,23 +7,23 @@ ...@@ -7,23 +7,23 @@
// //
import UIKit import UIKit
//import nuisdk
class YHVoiceDemo: YHBaseViewController { class YHVoiceDemo: YHBaseViewController {
var start: UIButton! var start: UIButton!
var end: UIButton! var end: UIButton!
var result: UILabel! var result: UILabel!
var nui: NeoNui!
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setupUI() setupUI()
} }
} }
extension YHVoiceDemo { extension YHVoiceDemo {
func setupUI() { func setupUI() {
// let recognizer = NuanceManager()
start = { start = {
let view = UIButton() let view = UIButton()
view.setTitle("start", for: .normal) view.setTitle("start", for: .normal)
......
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