add TencentTTS
This commit is contained in:
@ -25,6 +25,8 @@
|
||||
5509CEF12BB54DD10056C5C2 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5509CEF02BB54DD10056C5C2 /* Config.swift */; };
|
||||
550B85A22C2BC624008834E5 /* InitAPP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 550B85A12C2BC623008834E5 /* InitAPP.swift */; };
|
||||
551C8C342C79946700B1A88C /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 551C8C332C79946700B1A88C /* GoogleService-Info.plist */; };
|
||||
555027392C81C0ED00A05441 /* QCloudTTS.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555027382C81C0ED00A05441 /* QCloudTTS.xcframework */; };
|
||||
5586E0882C80AD2D00026733 /* TTSManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5586E0872C80AD2D00026733 /* TTSManager.swift */; };
|
||||
559E6D7C2C34EAE700C971B9 /* IapManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 559E6D7B2C34EAE700C971B9 /* IapManager.swift */; };
|
||||
559E6D7E2C35355200C971B9 /* LogManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 559E6D7D2C35355200C971B9 /* LogManager.swift */; };
|
||||
55A954A22BBBFD0C00BF181E /* GrammarData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A954A12BBBFD0C00BF181E /* GrammarData.swift */; };
|
||||
@ -88,6 +90,9 @@
|
||||
5509CEF02BB54DD10056C5C2 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = "<group>"; };
|
||||
550B85A12C2BC623008834E5 /* InitAPP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitAPP.swift; sourceTree = "<group>"; };
|
||||
551C8C332C79946700B1A88C /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
555027382C81C0ED00A05441 /* QCloudTTS.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = QCloudTTS.xcframework; sourceTree = "<group>"; };
|
||||
5586E0832C8092C400026733 /* AIGrammar-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AIGrammar-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
5586E0872C80AD2D00026733 /* TTSManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TTSManager.swift; sourceTree = "<group>"; };
|
||||
559E6D7B2C34EAE700C971B9 /* IapManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IapManager.swift; sourceTree = "<group>"; };
|
||||
559E6D7D2C35355200C971B9 /* LogManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogManager.swift; sourceTree = "<group>"; };
|
||||
55A954A12BBBFD0C00BF181E /* GrammarData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GrammarData.swift; sourceTree = "<group>"; };
|
||||
@ -118,6 +123,7 @@
|
||||
55BC474F2C3A4E5E00120A7D /* ToastUI in Frameworks */,
|
||||
67F268687FCD2E4F2F4462C0 /* Pods_AIGrammar.framework in Frameworks */,
|
||||
55EF5C3E2C2263460060CE47 /* StoreKit.framework in Frameworks */,
|
||||
555027392C81C0ED00A05441 /* QCloudTTS.xcframework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -177,6 +183,8 @@
|
||||
5500A38E2BB3C7E80065A1D3 /* AIGrammar */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5586E0842C8093DF00026733 /* third-party */,
|
||||
5586E0832C8092C400026733 /* AIGrammar-Bridging-Header.h */,
|
||||
55BC47472C3A380C00120A7D /* CommView */,
|
||||
55C73D7E2C157C2200041C66 /* AIGrammar.entitlements */,
|
||||
55DAC6532BBA956100BDD4C8 /* GrammarSubView */,
|
||||
@ -240,6 +248,7 @@
|
||||
559E6D7B2C34EAE700C971B9 /* IapManager.swift */,
|
||||
559E6D7D2C35355200C971B9 /* LogManager.swift */,
|
||||
55E4E8F42C60CFFC00988503 /* CommFunc.swift */,
|
||||
5586E0872C80AD2D00026733 /* TTSManager.swift */,
|
||||
);
|
||||
path = lib;
|
||||
sourceTree = "<group>";
|
||||
@ -253,6 +262,14 @@
|
||||
path = ViewModel;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5586E0842C8093DF00026733 /* third-party */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
555027382C81C0ED00A05441 /* QCloudTTS.xcframework */,
|
||||
);
|
||||
path = "third-party";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
55BC47472C3A380C00120A7D /* CommView */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -551,6 +568,7 @@
|
||||
5500A3922BB3C7E80065A1D3 /* ContentView.swift in Sources */,
|
||||
55BB127D2BBD6D0600D2BEA4 /* CameraView.swift in Sources */,
|
||||
559E6D7C2C34EAE700C971B9 /* IapManager.swift in Sources */,
|
||||
5586E0882C80AD2D00026733 /* TTSManager.swift in Sources */,
|
||||
55EF5C3C2C2250900060CE47 /* IAPTestView.swift in Sources */,
|
||||
5500A3902BB3C7E80065A1D3 /* AIGrammarApp.swift in Sources */,
|
||||
5500A39C2BB3C7EB0065A1D3 /* AIGrammar.xcdatamodeld in Sources */,
|
||||
@ -724,6 +742,13 @@
|
||||
DEVELOPMENT_ASSET_PATHS = "\"AIGrammar/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = G8UMWM9TLL;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
EXCLUDED_ARCHS = x86_64;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/AIGrammar/third-party",
|
||||
"$(PROJECT_DIR)/AIGrammar/third-party/ios-arm64_armv7",
|
||||
"$(PROJECT_DIR)/AIGrammar/third-party/ios-arm64_i386_x86_64-simulator",
|
||||
);
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = EasyGrammar;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
|
||||
@ -738,11 +763,91 @@
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
"-l\"c++\"",
|
||||
"-l\"sqlite3\"",
|
||||
"-l\"z\"",
|
||||
"-framework",
|
||||
"\"Alamofire\"",
|
||||
"-framework",
|
||||
"\"CFNetwork\"",
|
||||
"-framework",
|
||||
"\"CoreTelephony\"",
|
||||
"-framework",
|
||||
"\"Cryptor\"",
|
||||
"-framework",
|
||||
"\"CryptorECC\"",
|
||||
"-framework",
|
||||
"\"CryptorRSA\"",
|
||||
"-framework",
|
||||
"\"FBLPromises\"",
|
||||
"-framework",
|
||||
"\"FirebaseABTesting\"",
|
||||
"-framework",
|
||||
"\"FirebaseAnalytics\"",
|
||||
"-framework",
|
||||
"\"FirebaseCore\"",
|
||||
"-framework",
|
||||
"\"FirebaseCoreExtension\"",
|
||||
"-framework",
|
||||
"\"FirebaseCoreInternal\"",
|
||||
"-framework",
|
||||
"\"FirebaseCrashlytics\"",
|
||||
"-framework",
|
||||
"\"FirebaseInstallations\"",
|
||||
"-framework",
|
||||
"\"FirebasePerformance\"",
|
||||
"-framework",
|
||||
"\"FirebaseRemoteConfig\"",
|
||||
"-framework",
|
||||
"\"FirebaseRemoteConfigInterop\"",
|
||||
"-framework",
|
||||
"\"FirebaseSessions\"",
|
||||
"-framework",
|
||||
"\"FirebaseSharedSwift\"",
|
||||
"-framework",
|
||||
"\"Foundation\"",
|
||||
"-framework",
|
||||
"\"GoogleAppMeasurement\"",
|
||||
"-framework",
|
||||
"\"GoogleAppMeasurementIdentitySupport\"",
|
||||
"-framework",
|
||||
"\"GoogleDataTransport\"",
|
||||
"-framework",
|
||||
"\"GoogleUtilities\"",
|
||||
"-framework",
|
||||
"\"KituraContracts\"",
|
||||
"-framework",
|
||||
"\"LoggerAPI\"",
|
||||
"-framework",
|
||||
"\"Logging\"",
|
||||
"-framework",
|
||||
"\"Promises\"",
|
||||
"-framework",
|
||||
"\"Security\"",
|
||||
"-framework",
|
||||
"\"StoreKit\"",
|
||||
"-framework",
|
||||
"\"SwiftJWT\"",
|
||||
"-framework",
|
||||
"\"SwiftyBeaver\"",
|
||||
"-framework",
|
||||
"\"SystemConfiguration\"",
|
||||
"-framework",
|
||||
"\"TrustDecision\"",
|
||||
"-framework",
|
||||
"\"UIKit\"",
|
||||
"-framework",
|
||||
"\"nanopb\"",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.easyprompts.aigrammar;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/AIGrammar/AIGrammar-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
};
|
||||
@ -760,6 +865,13 @@
|
||||
DEVELOPMENT_ASSET_PATHS = "\"AIGrammar/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = G8UMWM9TLL;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
EXCLUDED_ARCHS = x86_64;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/AIGrammar/third-party",
|
||||
"$(PROJECT_DIR)/AIGrammar/third-party/ios-arm64_armv7",
|
||||
"$(PROJECT_DIR)/AIGrammar/third-party/ios-arm64_i386_x86_64-simulator",
|
||||
);
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = EasyGrammar;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
|
||||
@ -774,11 +886,92 @@
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
"-l\"c++\"",
|
||||
"-l\"sqlite3\"",
|
||||
"-l\"z\"",
|
||||
"-framework",
|
||||
"\"Alamofire\"",
|
||||
"-framework",
|
||||
"\"CFNetwork\"",
|
||||
"-framework",
|
||||
"\"CoreTelephony\"",
|
||||
"-framework",
|
||||
"\"Cryptor\"",
|
||||
"-framework",
|
||||
"\"CryptorECC\"",
|
||||
"-framework",
|
||||
"\"CryptorRSA\"",
|
||||
"-framework",
|
||||
"\"FBLPromises\"",
|
||||
"-framework",
|
||||
"\"FirebaseABTesting\"",
|
||||
"-framework",
|
||||
"\"FirebaseAnalytics\"",
|
||||
"-framework",
|
||||
"\"FirebaseCore\"",
|
||||
"-framework",
|
||||
"\"FirebaseCoreExtension\"",
|
||||
"-framework",
|
||||
"\"FirebaseCoreInternal\"",
|
||||
"-framework",
|
||||
"\"FirebaseCrashlytics\"",
|
||||
"-framework",
|
||||
"\"FirebaseInstallations\"",
|
||||
"-framework",
|
||||
"\"FirebasePerformance\"",
|
||||
"-framework",
|
||||
"\"FirebaseRemoteConfig\"",
|
||||
"-framework",
|
||||
"\"FirebaseRemoteConfigInterop\"",
|
||||
"-framework",
|
||||
"\"FirebaseSessions\"",
|
||||
"-framework",
|
||||
"\"FirebaseSharedSwift\"",
|
||||
"-framework",
|
||||
"\"Foundation\"",
|
||||
"-framework",
|
||||
"\"GoogleAppMeasurement\"",
|
||||
"-framework",
|
||||
"\"GoogleAppMeasurementIdentitySupport\"",
|
||||
"-framework",
|
||||
"\"GoogleDataTransport\"",
|
||||
"-framework",
|
||||
"\"GoogleUtilities\"",
|
||||
"-framework",
|
||||
"\"KituraContracts\"",
|
||||
"-framework",
|
||||
"\"LoggerAPI\"",
|
||||
"-framework",
|
||||
"\"Logging\"",
|
||||
"-framework",
|
||||
"\"Promises\"",
|
||||
"-framework",
|
||||
"\"Security\"",
|
||||
"-framework",
|
||||
"\"StoreKit\"",
|
||||
"-framework",
|
||||
"\"SwiftJWT\"",
|
||||
"-framework",
|
||||
"\"SwiftyBeaver\"",
|
||||
"-framework",
|
||||
"\"SystemConfiguration\"",
|
||||
"-framework",
|
||||
"\"TrustDecision\"",
|
||||
"-framework",
|
||||
"\"UIKit\"",
|
||||
"-framework",
|
||||
"\"nanopb\"",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.easyprompts.aigrammar;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/AIGrammar/AIGrammar-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
};
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
@ -62,7 +63,9 @@
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
allowLocationSimulation = "YES"
|
||||
consoleMode = "0"
|
||||
structuredConsoleMode = "1">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
|
||||
14
AIGrammar/AIGrammar-Bridging-Header.h
Normal file
14
AIGrammar/AIGrammar-Bridging-Header.h
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// AIGrammar-Bridging-Header.h
|
||||
// AIGrammar
|
||||
//
|
||||
// Created by oscar on 2024/8/29.
|
||||
//
|
||||
|
||||
#ifndef AIGrammar_Bridging_Header_h
|
||||
#define AIGrammar_Bridging_Header_h
|
||||
|
||||
#import "QCloudTTS/QCloudTTSEngine.h"
|
||||
#import "QCloudTTS/QCloudMediaPlayer2.h"
|
||||
|
||||
#endif /* AIGrammar_Bridging_Header_h */
|
||||
@ -8,6 +8,7 @@
|
||||
import SwiftUI
|
||||
import AVFoundation
|
||||
import ToastUI
|
||||
import FirebaseAnalytics
|
||||
|
||||
struct SubmitTextEditor: UIViewRepresentable {
|
||||
@Binding var text: String
|
||||
@ -271,7 +272,9 @@ struct TranslateCardView: View {
|
||||
var onEdit: (String) -> Void
|
||||
var onCopy: (String) -> Void
|
||||
var onFeedback: (TranslateFeedback) -> Void
|
||||
let synthesizer = AVSpeechSynthesizer()
|
||||
|
||||
// 创建委托类的实例
|
||||
@State private var isSynthesizing = false
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
@ -285,15 +288,15 @@ struct TranslateCardView: View {
|
||||
Text(translation.input)
|
||||
.padding(.bottom, 3)
|
||||
HStack {
|
||||
/*
|
||||
|
||||
Button(action: {
|
||||
speakText(translation.input)
|
||||
synthesizeAndPlay(text: translation.input, lang: "Original")
|
||||
}) {
|
||||
Image(systemName: "speaker.wave.2")
|
||||
.foregroundColor(.blue)
|
||||
.padding(.trailing)
|
||||
}
|
||||
*/
|
||||
|
||||
Spacer()
|
||||
Button(action: {
|
||||
onEdit(translation.input)
|
||||
@ -315,14 +318,14 @@ struct TranslateCardView: View {
|
||||
.padding(.vertical, 1) // 减少与分割线的间距
|
||||
.padding(.bottom, 3) // 减少与原文之间的间距
|
||||
HStack {
|
||||
/*
|
||||
|
||||
Button(action: {
|
||||
speakText(translation.translation)
|
||||
synthesizeAndPlay(text: translation.translation, lang: "Translated")
|
||||
}) {
|
||||
Image(systemName: "speaker.wave.2")
|
||||
.foregroundColor(.blue)
|
||||
}
|
||||
*/
|
||||
|
||||
Spacer()
|
||||
HStack(spacing: 15) {// 减小图标之间的间距
|
||||
Button(action: {
|
||||
@ -362,14 +365,27 @@ struct TranslateCardView: View {
|
||||
.background(Color.gray.opacity(0.2)) // 设置整个卡片的背景色为LightGray
|
||||
.overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.gray, lineWidth: 1))
|
||||
}
|
||||
|
||||
func speakText(_ text: String) {
|
||||
let utterance = AVSpeechUtterance(string: text)
|
||||
utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
|
||||
synthesizer.speak(utterance)
|
||||
|
||||
func synthesizeAndPlay(text: String, lang: String) {
|
||||
// 记录事件
|
||||
Analytics.logEvent("TTSClick", parameters: [
|
||||
"vendor": "TencentTTS",
|
||||
"lang" : lang
|
||||
])
|
||||
|
||||
isSynthesizing = true
|
||||
TTSManager.shared.synthesizeAndPlay(text: text, isVIP: globalEnvironment.isVip, onSuccess: {
|
||||
isSynthesizing = false
|
||||
logger.info("Synthesis succ.")
|
||||
}, onFailure: { error in
|
||||
isSynthesizing = false
|
||||
logger.info("Synthesis error: \(error)")
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extension View {
|
||||
func dashed() -> some View {
|
||||
self.overlay(
|
||||
|
||||
@ -100,6 +100,7 @@ class GlobalAnalyticsEvents: ObservableObject {
|
||||
|
||||
let valEntryBuyProBtn = "buy_pro_btn"
|
||||
let valEntrySettingsBtn = "settings_buy_btn"
|
||||
|
||||
}
|
||||
|
||||
let globalAnalyticsEvents = GlobalAnalyticsEvents()
|
||||
|
||||
100
AIGrammar/lib/TTSManager.swift
Normal file
100
AIGrammar/lib/TTSManager.swift
Normal file
@ -0,0 +1,100 @@
|
||||
//
|
||||
// TTSManager.swift
|
||||
// AIGrammar
|
||||
//
|
||||
// Created by oscar on 2024/8/29.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import AVFAudio
|
||||
|
||||
class TTSManager: NSObject, QCloudTTSEngineDelegate {
|
||||
static let shared = TTSManager() // 单例模式
|
||||
|
||||
private var synthesizer: QCloudTTSEngine?
|
||||
private var audioPlayer: AVAudioPlayer?
|
||||
private var onSuccess: (() -> Void)?
|
||||
private var onFailure: ((String) -> Void)?
|
||||
|
||||
// 设定个非会员每天的使用上限
|
||||
private let dailyLimit = 100
|
||||
private let userDefaults = UserDefaults.standard
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
setupSynthesizer()
|
||||
}
|
||||
|
||||
private func setupSynthesizer() {
|
||||
synthesizer = QCloudTTSEngine.getShareInstance() as? QCloudTTSEngine
|
||||
synthesizer?.engineInit(.TTS_MODE_ONLINE, delegate: self)
|
||||
synthesizer?.setOnlineAuthParam(1300230265, secretId: "AKIDmcetGuREGiDOBeIJVm4Kd1ZOUqFdD1CQ", secretKey: "UwhP3XrJfrx8IQUfpMvRznYTK5lM4rhR", token: nil)
|
||||
}
|
||||
|
||||
func synthesizeAndPlay(text: String, isVIP: Bool, onSuccess: @escaping () -> Void, onFailure: @escaping (String) -> Void) {
|
||||
if !isVIP {
|
||||
let currentDate = Date()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd"
|
||||
let currentDateString = dateFormatter.string(from: currentDate)
|
||||
|
||||
let lastDateString = userDefaults.string(forKey: "LastCallDate") ?? ""
|
||||
var callCount = userDefaults.integer(forKey: "CallCount")
|
||||
|
||||
if currentDateString != lastDateString {
|
||||
// 如果日期变化,重置计数器
|
||||
callCount = 0
|
||||
userDefaults.set(currentDateString, forKey: "LastCallDate")
|
||||
}
|
||||
logger.info("nonVIP check limit, cnt: \(callCount), limit: \(dailyLimit)")
|
||||
if callCount >= dailyLimit {
|
||||
onFailure("Daily limit reached. Please try again tomorrow.")
|
||||
return
|
||||
} else {
|
||||
// 增加调用计数
|
||||
callCount += 1
|
||||
userDefaults.set(callCount, forKey: "CallCount")
|
||||
}
|
||||
}
|
||||
|
||||
guard let synthesizer = synthesizer else {
|
||||
onFailure("Synthesizer is not initialized.")
|
||||
return
|
||||
}
|
||||
|
||||
self.onSuccess = onSuccess
|
||||
self.onFailure = onFailure
|
||||
|
||||
let error = synthesizer.synthesize(text, utteranceId: "test")
|
||||
if let error = error {
|
||||
onFailure("Synthesis error: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - QCloudTTSEngineDelegate
|
||||
func onSynthesizeData(_ data: Data?, utteranceId: String?, text: String?, engineType: Int, requestId: String?, respJson: String?) {
|
||||
guard let data = data else {
|
||||
onFailure?("Synthesis failed with no data.")
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
audioPlayer = try AVAudioPlayer(data: data)
|
||||
audioPlayer?.prepareToPlay()
|
||||
audioPlayer?.play()
|
||||
onSuccess?()
|
||||
} catch {
|
||||
onFailure?("Failed to play synthesized audio: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func onError(_ error: TtsError?, utteranceId: String?, text: String?) {
|
||||
if let error = error {
|
||||
onFailure?("Synthesis error: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func onOfflineAuthInfo(_ OfflineAuthInfo: QCloudOfflineAuthInfo) {
|
||||
// 处理离线授权信息,如果需要
|
||||
}
|
||||
}
|
||||
42
AIGrammar/third-party/QCloudTTS.xcframework/Info.plist
vendored
Normal file
42
AIGrammar/third-party/QCloudTTS.xcframework/Info.plist
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64_i386_x86_64-simulator</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>QCloudTTS.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>i386</string>
|
||||
<string>x86_64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64_armv7</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>QCloudTTS.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
<key>XCFrameworkFormatVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -0,0 +1,25 @@
|
||||
//
|
||||
// QPlayerError.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by renqiu on 2022/1/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM (NSInteger,QCPlayerErrorCode){
|
||||
|
||||
QPLAYER_ERROR_CODE_EXCEPTION = -201,
|
||||
QPLAYER_ERROR_CODE_PLAY_QUEUE_IS_FULL = -202,
|
||||
QPLAYER_ERROR_CODE_AUDIO_READ_FAILEDL = -203,
|
||||
QPLAYER_ERROR_CODE_UNKNOW = -204,
|
||||
|
||||
};
|
||||
@interface QCPlayerError : NSObject
|
||||
@property (nonatomic, assign) NSInteger mCode;
|
||||
@property (nonatomic,copy)NSString *message;
|
||||
@property (nonatomic,strong)NSError *errorMessage;
|
||||
+(instancetype)getQCPlayerErrorWithMcode:(NSInteger)mCode ErrorMessage:(NSError*)errorMessage;
|
||||
@end
|
||||
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
//
|
||||
// QCloudMediaPlayer.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by renqiu on 2022/1/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QCloudTTS/QCPlayerError.h>
|
||||
#import <QCloudTTS/QCloudPlayerDelegate.h>
|
||||
|
||||
/// <#Description#>
|
||||
@interface QCloudMediaPlayer : NSObject
|
||||
@property (assign,nonnull)id <QCloudPlayerDelegate>playerDelegate;
|
||||
//
|
||||
/// 数据入队列
|
||||
/// @param data 加入队列的音频
|
||||
/// @param text 音频对应的文本
|
||||
/// @param utteranceId 音频对应的ID
|
||||
-(void)enqueueWithData:(NSData* _Nonnull )data Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
|
||||
//
|
||||
/// 数据入队列
|
||||
/// @param data 加入队列的音频
|
||||
/// @param text 音频对应的文本
|
||||
/// @param utteranceId 音频对应的ID
|
||||
/// @param server 服务端返回的信息,包含Subtitles时会使用Subtitle来进行时间戳判断
|
||||
-(void)enqueueWithData:(NSData* _Nonnull )data Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId RespJson:(NSString* _Nullable)respjson;
|
||||
|
||||
/// 数据入队列
|
||||
/// @param file 加入队列的音频文件
|
||||
/// @param text 音频文件对应的文本
|
||||
/// @param utteranceId 音频文件对应的ID
|
||||
-(void)enqueueWithFile:(NSURL* _Nullable)file Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
|
||||
//
|
||||
/// 停止播放
|
||||
-(QCPlayerError* _Nullable)StopPlay;
|
||||
/// 暂停播放
|
||||
-(QCPlayerError* _Nullable)PausePlay;
|
||||
/// 恢复播放
|
||||
-(QCPlayerError* _Nullable)ResumePlay;
|
||||
-(NSInteger)getAudioQueueSize;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
//
|
||||
// QCloudMediaPlayer.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by renqiu on 2022/1/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QCloudTTS/QCPlayerError.h>
|
||||
#import <QCloudTTS/QCloudMediaPlayer.h>
|
||||
|
||||
/// <#Description#>
|
||||
@interface QCloudMediaPlayer2 : NSObject
|
||||
@property (weak)id <QCloudPlayerDelegate> _Nullable playerDelegate;
|
||||
//
|
||||
/// 数据入队列
|
||||
/// @param data 加入队列的音频
|
||||
/// @param text 音频对应的文本
|
||||
/// @param utteranceId 音频对应的ID
|
||||
-(void)enqueueWithData:(NSData* _Nonnull )data Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
/// 数据入队列
|
||||
/// @param file 加入队列的音频文件
|
||||
/// @param text 音频文件对应的文本
|
||||
/// @param utteranceId 音频文件对应的ID
|
||||
-(void)enqueueWithFile:(NSURL* _Nullable)file Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
//
|
||||
/// 停止播放
|
||||
-(QCPlayerError* _Nullable)StopPlay;
|
||||
/// 暂停播放
|
||||
-(QCPlayerError* _Nullable)PausePlay;
|
||||
/// 恢复播放
|
||||
-(QCPlayerError* _Nullable)ResumePlay;
|
||||
-(NSInteger)getAudioQueueSize;
|
||||
|
||||
@end
|
||||
@ -0,0 +1,48 @@
|
||||
//
|
||||
// QCloudOfflineAuthInfo.h
|
||||
// QCloudTTS
|
||||
//
|
||||
// Created by dgw on 2022/6/15.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
/*如果您下载的是在线版TTS SDK ,请忽略此接口文件*/
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// 离线授权错误吗
|
||||
typedef NS_ENUM(NSInteger, AuthErrorCode) {
|
||||
OFFLINE_AUTH_SUCCESS = 0,//"Auth Success"
|
||||
|
||||
OFFLINE_AUTH_NETWORK_CONNECT_FAILED = -10,//"Network connect failed."
|
||||
OFFLINE_AUTH_NETWORK_SERVER_AUTH_FAILED = -11,//"Server Authorization Error !See Response Message."
|
||||
|
||||
OFFLINE_AUTH_PARAMETERS_ERROR = -12,//"Parameter cannot be empty."
|
||||
OFFLINE_AUTH_PACKAGENAME_ERROR = -13,//"Authorization package name error."
|
||||
OFFLINE_AUTH_DEVICE_ID_ERROR = -14,//"Authorization device ID error."
|
||||
OFFLINE_AUTH_GET_DEVICE_ID_FAILED = -15,//"The device is abnormal and the device ID cannot be obtained."
|
||||
OFFLINE_AUTH_PLATFORM_ERROR = -16,//"The platform is not authorized."
|
||||
OFFLINE_AUTH_BIZCODE_ERROR = -17,//"License business does not match."
|
||||
OFFLINE_AUTH_EXPIRED = -18,//"Authorization has expired.")
|
||||
OFFLINE_AUTH_JSON_PARSE_FAILED = -19,//"JSON Parsing Error."
|
||||
OFFLINE_AUTH_DECODE_ERROR = -20,//"Could not decode license, please check input parameters."
|
||||
OFFLINE_AUTH_UNKNOWN_ERROR = -21,//"Unknown authorization error."
|
||||
|
||||
};
|
||||
// 离线授权信息类
|
||||
@interface QCloudOfflineAuthInfo : NSObject
|
||||
|
||||
@property (nonatomic, copy, nullable) NSString* respose; //使用在线拉取授权时,服务器返回到json数据
|
||||
|
||||
@property (nonatomic, assign) AuthErrorCode err_code; //错误码
|
||||
@property (nonatomic, copy, nullable) NSString* err_msg; //错误信息
|
||||
|
||||
@property (nonatomic, copy, nullable) NSString* deviceId; //设备id
|
||||
@property (nonatomic, copy, nullable) NSString* expireTime; //到期时间
|
||||
@property (nonatomic, copy, nullable) NSString* voiceAuthList; //已授权的音色名列表,用分号隔开
|
||||
|
||||
+(instancetype _Nonnull )getQCloudOfflineAuthInfo:(AuthErrorCode)err_code Respose:(NSString*_Nullable)respose;
|
||||
|
||||
+(NSString* _Nonnull )getErrorMsg:(AuthErrorCode)code;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -0,0 +1,37 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QCloudTTS/QCPlayerError.h>
|
||||
|
||||
@protocol QCloudPlayerDelegate <NSObject>
|
||||
//播放开始
|
||||
-(void) onTTSPlayStart;
|
||||
|
||||
//队列所有音频播放完成,音频等待中
|
||||
-(void) onTTSPlayWait;
|
||||
|
||||
//恢复播放
|
||||
-(void) onTTSPlayResume;
|
||||
|
||||
//暂停播放
|
||||
-(void) onTTSPlayPause;
|
||||
|
||||
//播放中止
|
||||
-(void)onTTSPlayStop;
|
||||
|
||||
//即将播放播放下一句,即将播放音频对应的句子,以及这句话utteranceId
|
||||
/// 即将播放播放下一句,即将播放音频对应的句子,以及这句话utteranceId
|
||||
/// @param text 当前播放句子的文本
|
||||
/// @param utteranceId 当前播放音频对应的ID
|
||||
-(void) onTTSPlayNextWithText:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
|
||||
|
||||
|
||||
//播放器异常
|
||||
-(void)onTTSPlayError:(QCPlayerError* _Nullable)playError;
|
||||
|
||||
/// 当前播放的字符,当前播放的字符在所在的句子中的下标.
|
||||
/// @param currentWord 当前读到的单个字,是一个估算值不一定准确
|
||||
/// @param currentIdex 当前播放句子中读到文字的下标
|
||||
-(void)onTTSPlayProgressWithCurrentWord:(NSString*_Nullable)currentWord CurrentIndex:(NSInteger)currentIdex;
|
||||
|
||||
|
||||
@end
|
||||
@ -0,0 +1,222 @@
|
||||
//
|
||||
// QCloudTTSEngine.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by dgw on 2022/1/10.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QCloudTTS/TtsError.h>
|
||||
#import <QCloudTTS/QCloudOfflineAuthInfo.h>
|
||||
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TtsMode) {
|
||||
TTS_MODE_ONLINE = 0, //在线模式
|
||||
TTS_MODE_OFFLINE = 1, //离线模式
|
||||
TTS_MODE_MIX = 2 //离在线混合模式
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// 回调接口
|
||||
@protocol QCloudTTSEngineDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
/// 合成结果回调
|
||||
/// @param data 音频数据
|
||||
/// @param utteranceId utteranceId
|
||||
/// @param text text
|
||||
/// @param type 该句话是以何种引擎生成的:0:在线 1:离线
|
||||
/// @deprecated
|
||||
-(void) onSynthesizeData:(NSData *_Nullable)data UtteranceId:(NSString *_Nullable)utteranceId Text:(NSString *_Nullable)text EngineType:(NSInteger)type;
|
||||
|
||||
/// 合成结果回调
|
||||
/// @param data 音频数据
|
||||
/// @param utteranceId utteranceId
|
||||
/// @param text text
|
||||
/// @param type 该句话是以何种引擎生成的:0:在线 1:离线
|
||||
/// @param requestId 请求ID,仅engineType为0时不为nil,用于排查问题
|
||||
-(void) onSynthesizeData:(NSData *_Nullable)data UtteranceId:(NSString *_Nullable)utteranceId Text:(NSString *_Nullable)text EngineType:(NSInteger)type RequestId:(NSString* _Nullable)requestId;
|
||||
|
||||
/// 合成结果回调
|
||||
/// @param data 音频数据
|
||||
/// @param utteranceId utteranceId
|
||||
/// @param text text
|
||||
/// @param type 该句话是以何种引擎生成的:0:在线 1:离线
|
||||
/// @param respJson 请求结果
|
||||
-(void) onSynthesizeData:(NSData *_Nullable)data UtteranceId:(NSString *_Nullable)utteranceId Text:(NSString *_Nullable)text EngineType:(NSInteger)type RequestId:(NSString* _Nullable)requestId RespJson:(NSString* _Nullable)respJson;
|
||||
|
||||
@required
|
||||
/// 错误回调
|
||||
/// @param error 错误信息
|
||||
/// @param utteranceId utteranceId
|
||||
/// @param text text
|
||||
-(void) onError:(TtsError *_Nullable)error UtteranceId:(NSString *_Nullable)utteranceId Text:(NSString *_Nullable)text;
|
||||
|
||||
|
||||
/// 返回离线合成模块授权信息,使用混合或者离线模式时,收到此方法成功回调后才可以调用合成接口
|
||||
/// 如果您下载的是在线版TTS SDK ,或者只使用在线合成模式,请忽略此方法
|
||||
/// @param OfflineAuthInfo 授权信息,当OfflineAuthInfo.err_msg为0时授权成功,详见QCloudOfflineAuthInfo.h
|
||||
-(void) onOfflineAuthInfo:(QCloudOfflineAuthInfo* _Nonnull )OfflineAuthInfo;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// 语音合成引擎接口
|
||||
@interface QCloudTTSEngine : NSObject
|
||||
|
||||
|
||||
/// 获得QCloudTTSEngine实例
|
||||
+(id _Nullable )getShareInstance;
|
||||
|
||||
/// 销毁QCloudTTSEngine实例
|
||||
+(void) instanceRelease;
|
||||
|
||||
|
||||
/// 初始化引擎
|
||||
/// @param mode 引擎模式,在线、离线、混合,如切换引擎,需要先执行instanceRelease
|
||||
/// @param delegate 用于接收结果的代理
|
||||
-(void) engineInit:(TtsMode)mode Delegate:(id<QCloudTTSEngineDelegate> _Nonnull) delegate;
|
||||
|
||||
|
||||
/// 取消合成,清空内部合成队列
|
||||
-(TtsError *_Nullable) cancel;
|
||||
|
||||
/// 合成接口,支持持续调用添加文本
|
||||
/// @param text 需要合成的文本
|
||||
/// @param utteranceId 用于标记文本的id,合成完成后随音频文件或者错误接口返回,可为空
|
||||
-(TtsError *_Nullable) synthesize:(NSString *_Nonnull)text UtteranceId:(NSString *_Nullable)utteranceId;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// 配置在线引擎鉴权参数
|
||||
/// @param appId appId
|
||||
/// @param secretId secretId
|
||||
/// @param secretKey secretKey
|
||||
/// @param token token,可为空,如果使用sts临时证书鉴权,secretId和secretKey均入参临时的,同时需要入参对应的token,
|
||||
/// sts临时证书具体详见https://cloud.tencent.com/document/product/598/33416 (开发调试时建议先用普通方式鉴权,token填nil)
|
||||
-(void) setOnlineAuthParam:(NSInteger)appId SecretId:(NSString* _Nonnull)secretId SecretKey:(NSString* _Nonnull)secretKey Token:(NSString* _Nullable)token;
|
||||
|
||||
|
||||
|
||||
///online语音相关设置
|
||||
|
||||
/// 设置在线语速,对setOnlineParam的封装
|
||||
/// @param voiceSpeed 默认0,代表正常速度
|
||||
-(void)setOnlineVoiceSpeed:(float)voiceSpeed;
|
||||
|
||||
/// 设置在线音色ID,对setOnlineParam的封装
|
||||
/// @param voiceType 默认1001,音色id可查看官网文档https://cloud.tencent.com/document/product/1073/37995
|
||||
-(void)setOnlineVoiceType:(int)voiceType;
|
||||
|
||||
/// 设置在线引擎音量,对setOnlineParam的封装
|
||||
/// @param voiceVolume 默认0,代表正常音量,没有静音选项
|
||||
-(void)setOnlineVoiceVolume:(float)voiceVolume;
|
||||
|
||||
/// 设置主语言类型,对setOnlineParam的封装
|
||||
/// @param primaryLanguage 1:中文 2:英文 默认1
|
||||
-(void)setOnlineVoiceLanguage:(int)primaryLanguage;
|
||||
|
||||
///在线编码格式,如无业务特殊需求不建议更改(默认"mp3",目前支持"mp3","wav","pcm",若更改为pcm不支持直接播放,对setOnlineParam的封装
|
||||
-(void)setOnlineCodec:(NSString* _Nonnull) code;
|
||||
|
||||
/// 项目ID
|
||||
/// @param projectId 默认0, 对setOnlineParam的封装
|
||||
-(void)setOnlineProjectId:(int)projectId;
|
||||
|
||||
/// 是否开启时间戳功能,默认为false,对setOnlineParam的封装
|
||||
- (void)setOnlineEnableSubtitle:(Boolean)val;
|
||||
|
||||
/// 断句敏感阈值,默认值为:0,对setOnlineParam的封装
|
||||
- (void)setOnlineSegmentRate:(int)val;
|
||||
|
||||
/// 控制合成音频的情感,仅支持多情感音色使用,对setOnlineParam的封装
|
||||
- (void)setOnlineEmotionCategory:(NSString* _Nullable)val;
|
||||
|
||||
/// 控制合成音频情感程度,对setOnlineParam的封装
|
||||
- (void)setOnlineEmotionIntensity:(int)val;
|
||||
|
||||
/// 设置自定义参数,可使用该方法控制请求时的参数
|
||||
/// @param value为nil时将删除参数,否则会在请求中添加参数
|
||||
- (void)setOnlineParam:(NSString* _Nonnull)key value:(NSObject* _Nullable)value;
|
||||
|
||||
/// 设置区域
|
||||
/// @param region 默认为ap-shanghai,无特殊需求请勿更改
|
||||
- (void)setOnlineRegion:(NSString *)region;
|
||||
|
||||
//设置是否输出日志
|
||||
-(void)setEnableDebugLog:(BOOL)enableDebugLog;
|
||||
|
||||
|
||||
|
||||
|
||||
/// timeoutIntervalForRequest ,0.5s - 30s 默认15000ms(15s)
|
||||
/// @param timeout [2200,60000] 单位ms
|
||||
- (void)setTimeoutIntervalForRequest:(int)timeout;
|
||||
|
||||
|
||||
/// timeoutIntervalForResource 2.2s - 60s 默认30000ms(30s)
|
||||
/// @param timeout [500,30000] 单位ms
|
||||
-(void)setTimeoutIntervalForResource:(int) timeout;
|
||||
|
||||
|
||||
/// Mix模式下,出现网络错误后的检测间隔时间, 默认值5分钟
|
||||
///注意:每次检测时将使用所入参的一句文本请求服务器,如果后端合成成功将会额外消耗该句字数的合成额度
|
||||
/// @param checkNetworkIntervalTime 大于等于0 单位s, 等于0时持续检测,直到成功
|
||||
-(void)setCheckNetworkIntervalTime:(int) checkNetworkIntervalTime;
|
||||
|
||||
|
||||
//以下为离线语音相关参数配置
|
||||
|
||||
//resourceDir 离线资源路径
|
||||
-(void)setOfflineResourceDir:(NSString * _Nonnull) resourceDir;
|
||||
|
||||
//voiceSpeed [0.5,2.0]
|
||||
-(void)setOfflineVoiceSpeed:(float) voiceSpeed;
|
||||
|
||||
//voiceType 离线音色名称,名称配置位于音色资源目录\voices\config.json 中,可自行指定更多的音色,demo中仅提供"pb"、"femalen"两种
|
||||
-(void)setOfflineVoiceType:(NSString *_Nonnull) voiceType;
|
||||
|
||||
//voiceVolume >0
|
||||
-(void)setOfflineVoiceVolume:(float) voiceVolume;
|
||||
|
||||
/// 配置离线TTS授权参数: 在线下载密钥(第一次激活设备需要联网)
|
||||
/// @param licPk 密钥对应的licPk,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param licKey 密钥对应的licKey,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param secretId 腾讯云secretId (可能与在线模式不是同一个账号,需要输入购买离线SDK对应的账号的secretId)
|
||||
/// @param secretKey 腾讯云 secretKey(可能与在线模式不是同一个账号,需要输入购买离线SDK对应的账号的secretKey)
|
||||
/// @param token token,可为空,如果使用sts临时证书鉴权,secretId和secretKey均入参临时的,同时需要入参对应的token,
|
||||
-(void)setOfflineAuthParamDoOnline:(NSString* _Nonnull)licPk
|
||||
LicKey:(NSString* _Nonnull)licKey
|
||||
SecretId:(NSString* _Nonnull)secretId
|
||||
SecretKey:(NSString* _Nonnull)secretKey
|
||||
Token:(NSString* _Nullable)token;
|
||||
|
||||
/// 配置离线TTS授权参数: 在线下载密钥(第一次激活设备需要联网)
|
||||
/// @param licPk 密钥对应的licPk,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param licKey 密钥对应的licKey,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param secretId 腾讯云secretId (可能与在线模式不是同一个账号,需要输入购买离线SDK对应的账号的secretId)
|
||||
/// @param secretKey 腾讯云 secretKey(可能与在线模式不是同一个账号,需要输入购买离线SDK对应的账号的secretKey)
|
||||
/// @param token token,可为空,如果使用sts临时证书鉴权,secretId和secretKey均入参临时的,同时需要入参对应的token,
|
||||
/// @param refreshAuth 是否强制联网刷新授权(NO:仅第一次联网激活下载授权文件; YES:联网刷新授权文件,无网络下将激活失败)
|
||||
-(void)setOfflineAuthParamDoOnline:(NSString* _Nonnull)licPk
|
||||
LicKey:(NSString* _Nonnull)licKey
|
||||
SecretId:(NSString* _Nonnull)secretId
|
||||
SecretKey:(NSString* _Nonnull)secretKey
|
||||
Token:(NSString* _Nullable)token
|
||||
RefreshAuth:(BOOL)refreshAuth;
|
||||
|
||||
|
||||
/// 配置离线TTS授权参数: 直接传入密钥(第一次激活也不需要联网)
|
||||
/// @param lic 授权密钥 ,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param licPk 该密钥对应的licPk,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param licSign 该密钥对应的licSign,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
-(void)setOfflineAuthParamDoOffline:(NSString* _Nonnull)lic
|
||||
LicPk:(NSString* _Nonnull)licPk
|
||||
LicSign:(NSString* _Nonnull)licSign;
|
||||
@end
|
||||
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
//
|
||||
// TtsError.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by dgw on 2022/1/10.
|
||||
//
|
||||
|
||||
#ifndef TtsError_h
|
||||
#define TtsError_h
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, TtsErrorCode) {
|
||||
|
||||
TTS_ERROR_CODE_UNINITIALIZED = -100, //Engine uninitialized
|
||||
TTS_ERROR_CODE_GENERATE_SIGN_FAIL = -101, //generate sign failed
|
||||
TTS_ERROR_CODE_NETWORK_CONNECT_FAILED = 102, //network connect failed
|
||||
TTS_ERROR_CODE_DECODE_FAIL = -103, //JSON Response Parsing Error
|
||||
TTS_ERROR_CODE_SERVER_RESPONSE_ERROR = -104, //Server response error
|
||||
TTS_ERROR_CODE_CANCEL_FAILURE = -106, //Cancel failure,please try again later
|
||||
|
||||
TTS_ERROR_CODE_OFFLINE_FAILURE = -107,//Offline synthesize failed, please check your text and VoiceType
|
||||
TTS_ERROR_CODE_OFFLINE_INIT_FAILURE = -108,//Offline engine initialization failed, please check resource files
|
||||
TTS_ERROR_CODE_OFFLINE_AUTH_FAILURE = -109,//Offline engine auth failure
|
||||
TTS_ERROR_CODE_OFFLINE_TEXT_TOO_LONG = -110, //Offline synthesize failed,text too long,MAX <= 1024 byte
|
||||
TTS_ERROR_CODE_OFFLINE_VOICE_AUTH_FAILURE = -111, //This voice not authorized, please change it
|
||||
|
||||
TTS_ERROR_CODE_OFFLINE_NOSUPPORT = -900 //This SDK only supports online mode
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// 后端返回的错误信息
|
||||
@interface TtsServiceError : NSObject
|
||||
|
||||
@property (nonatomic, copy) NSString* _Nullable err_code;
|
||||
@property (nonatomic, copy) NSString* _Nullable msg;
|
||||
@property (nonatomic, copy) NSString* _Nullable respose;
|
||||
|
||||
+(instancetype _Nonnull)getTtsServiceError:(NSString *_Nullable)err_code ErrorMsg:(NSString* _Nullable)msg Respose:(NSString* _Nullable)respose;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/// 错误信息类
|
||||
@interface TtsError : NSObject
|
||||
|
||||
@property (nonatomic, assign) TtsErrorCode err_code; //错误码
|
||||
|
||||
@property (nonatomic, copy, nullable) NSString* msg; //错误信息
|
||||
|
||||
@property (nonatomic, copy, nullable) NSError * error; //系统抛出的错误信息(不一定有,可能为空)
|
||||
|
||||
@property (nonatomic, strong ,nullable) TtsServiceError * serviceError;//服务器返回的错误信息(不一定有,可能为空)
|
||||
|
||||
+(instancetype _Nonnull)getTtsError:(TtsErrorCode)err_code
|
||||
TtsServiceError:(TtsServiceError* _Nullable)serviceError
|
||||
NSErrorMsg:(NSError *_Nullable)error;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* TtsError_h */
|
||||
BIN
AIGrammar/third-party/QCloudTTS.xcframework/ios-arm64_armv7/QCloudTTS.framework/Info.plist
vendored
Normal file
BIN
AIGrammar/third-party/QCloudTTS.xcframework/ios-arm64_armv7/QCloudTTS.framework/Info.plist
vendored
Normal file
Binary file not shown.
BIN
AIGrammar/third-party/QCloudTTS.xcframework/ios-arm64_armv7/QCloudTTS.framework/QCloudTTS
vendored
Normal file
BIN
AIGrammar/third-party/QCloudTTS.xcframework/ios-arm64_armv7/QCloudTTS.framework/QCloudTTS
vendored
Normal file
Binary file not shown.
@ -0,0 +1,25 @@
|
||||
//
|
||||
// QPlayerError.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by renqiu on 2022/1/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM (NSInteger,QCPlayerErrorCode){
|
||||
|
||||
QPLAYER_ERROR_CODE_EXCEPTION = -201,
|
||||
QPLAYER_ERROR_CODE_PLAY_QUEUE_IS_FULL = -202,
|
||||
QPLAYER_ERROR_CODE_AUDIO_READ_FAILEDL = -203,
|
||||
QPLAYER_ERROR_CODE_UNKNOW = -204,
|
||||
|
||||
};
|
||||
@interface QCPlayerError : NSObject
|
||||
@property (nonatomic, assign) NSInteger mCode;
|
||||
@property (nonatomic,copy)NSString *message;
|
||||
@property (nonatomic,strong)NSError *errorMessage;
|
||||
+(instancetype)getQCPlayerErrorWithMcode:(NSInteger)mCode ErrorMessage:(NSError*)errorMessage;
|
||||
@end
|
||||
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
//
|
||||
// QCloudMediaPlayer.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by renqiu on 2022/1/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QCloudTTS/QCPlayerError.h>
|
||||
#import <QCloudTTS/QCloudPlayerDelegate.h>
|
||||
|
||||
/// <#Description#>
|
||||
@interface QCloudMediaPlayer : NSObject
|
||||
@property (assign,nonnull)id <QCloudPlayerDelegate>playerDelegate;
|
||||
//
|
||||
/// 数据入队列
|
||||
/// @param data 加入队列的音频
|
||||
/// @param text 音频对应的文本
|
||||
/// @param utteranceId 音频对应的ID
|
||||
-(void)enqueueWithData:(NSData* _Nonnull )data Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
|
||||
//
|
||||
/// 数据入队列
|
||||
/// @param data 加入队列的音频
|
||||
/// @param text 音频对应的文本
|
||||
/// @param utteranceId 音频对应的ID
|
||||
/// @param server 服务端返回的信息,包含Subtitles时会使用Subtitle来进行时间戳判断
|
||||
-(void)enqueueWithData:(NSData* _Nonnull )data Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId RespJson:(NSString* _Nullable)respjson;
|
||||
|
||||
/// 数据入队列
|
||||
/// @param file 加入队列的音频文件
|
||||
/// @param text 音频文件对应的文本
|
||||
/// @param utteranceId 音频文件对应的ID
|
||||
-(void)enqueueWithFile:(NSURL* _Nullable)file Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
|
||||
//
|
||||
/// 停止播放
|
||||
-(QCPlayerError* _Nullable)StopPlay;
|
||||
/// 暂停播放
|
||||
-(QCPlayerError* _Nullable)PausePlay;
|
||||
/// 恢复播放
|
||||
-(QCPlayerError* _Nullable)ResumePlay;
|
||||
-(NSInteger)getAudioQueueSize;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
//
|
||||
// QCloudMediaPlayer.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by renqiu on 2022/1/11.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QCloudTTS/QCPlayerError.h>
|
||||
#import <QCloudTTS/QCloudMediaPlayer.h>
|
||||
|
||||
/// <#Description#>
|
||||
@interface QCloudMediaPlayer2 : NSObject
|
||||
@property (weak)id <QCloudPlayerDelegate> _Nullable playerDelegate;
|
||||
//
|
||||
/// 数据入队列
|
||||
/// @param data 加入队列的音频
|
||||
/// @param text 音频对应的文本
|
||||
/// @param utteranceId 音频对应的ID
|
||||
-(void)enqueueWithData:(NSData* _Nonnull )data Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
/// 数据入队列
|
||||
/// @param file 加入队列的音频文件
|
||||
/// @param text 音频文件对应的文本
|
||||
/// @param utteranceId 音频文件对应的ID
|
||||
-(void)enqueueWithFile:(NSURL* _Nullable)file Text:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
//
|
||||
/// 停止播放
|
||||
-(QCPlayerError* _Nullable)StopPlay;
|
||||
/// 暂停播放
|
||||
-(QCPlayerError* _Nullable)PausePlay;
|
||||
/// 恢复播放
|
||||
-(QCPlayerError* _Nullable)ResumePlay;
|
||||
-(NSInteger)getAudioQueueSize;
|
||||
|
||||
@end
|
||||
@ -0,0 +1,48 @@
|
||||
//
|
||||
// QCloudOfflineAuthInfo.h
|
||||
// QCloudTTS
|
||||
//
|
||||
// Created by dgw on 2022/6/15.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
/*如果您下载的是在线版TTS SDK ,请忽略此接口文件*/
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// 离线授权错误吗
|
||||
typedef NS_ENUM(NSInteger, AuthErrorCode) {
|
||||
OFFLINE_AUTH_SUCCESS = 0,//"Auth Success"
|
||||
|
||||
OFFLINE_AUTH_NETWORK_CONNECT_FAILED = -10,//"Network connect failed."
|
||||
OFFLINE_AUTH_NETWORK_SERVER_AUTH_FAILED = -11,//"Server Authorization Error !See Response Message."
|
||||
|
||||
OFFLINE_AUTH_PARAMETERS_ERROR = -12,//"Parameter cannot be empty."
|
||||
OFFLINE_AUTH_PACKAGENAME_ERROR = -13,//"Authorization package name error."
|
||||
OFFLINE_AUTH_DEVICE_ID_ERROR = -14,//"Authorization device ID error."
|
||||
OFFLINE_AUTH_GET_DEVICE_ID_FAILED = -15,//"The device is abnormal and the device ID cannot be obtained."
|
||||
OFFLINE_AUTH_PLATFORM_ERROR = -16,//"The platform is not authorized."
|
||||
OFFLINE_AUTH_BIZCODE_ERROR = -17,//"License business does not match."
|
||||
OFFLINE_AUTH_EXPIRED = -18,//"Authorization has expired.")
|
||||
OFFLINE_AUTH_JSON_PARSE_FAILED = -19,//"JSON Parsing Error."
|
||||
OFFLINE_AUTH_DECODE_ERROR = -20,//"Could not decode license, please check input parameters."
|
||||
OFFLINE_AUTH_UNKNOWN_ERROR = -21,//"Unknown authorization error."
|
||||
|
||||
};
|
||||
// 离线授权信息类
|
||||
@interface QCloudOfflineAuthInfo : NSObject
|
||||
|
||||
@property (nonatomic, copy, nullable) NSString* respose; //使用在线拉取授权时,服务器返回到json数据
|
||||
|
||||
@property (nonatomic, assign) AuthErrorCode err_code; //错误码
|
||||
@property (nonatomic, copy, nullable) NSString* err_msg; //错误信息
|
||||
|
||||
@property (nonatomic, copy, nullable) NSString* deviceId; //设备id
|
||||
@property (nonatomic, copy, nullable) NSString* expireTime; //到期时间
|
||||
@property (nonatomic, copy, nullable) NSString* voiceAuthList; //已授权的音色名列表,用分号隔开
|
||||
|
||||
+(instancetype _Nonnull )getQCloudOfflineAuthInfo:(AuthErrorCode)err_code Respose:(NSString*_Nullable)respose;
|
||||
|
||||
+(NSString* _Nonnull )getErrorMsg:(AuthErrorCode)code;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -0,0 +1,37 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QCloudTTS/QCPlayerError.h>
|
||||
|
||||
@protocol QCloudPlayerDelegate <NSObject>
|
||||
//播放开始
|
||||
-(void) onTTSPlayStart;
|
||||
|
||||
//队列所有音频播放完成,音频等待中
|
||||
-(void) onTTSPlayWait;
|
||||
|
||||
//恢复播放
|
||||
-(void) onTTSPlayResume;
|
||||
|
||||
//暂停播放
|
||||
-(void) onTTSPlayPause;
|
||||
|
||||
//播放中止
|
||||
-(void)onTTSPlayStop;
|
||||
|
||||
//即将播放播放下一句,即将播放音频对应的句子,以及这句话utteranceId
|
||||
/// 即将播放播放下一句,即将播放音频对应的句子,以及这句话utteranceId
|
||||
/// @param text 当前播放句子的文本
|
||||
/// @param utteranceId 当前播放音频对应的ID
|
||||
-(void) onTTSPlayNextWithText:(NSString* _Nullable)text UtteranceId:(NSString* _Nullable)utteranceId;
|
||||
|
||||
|
||||
|
||||
//播放器异常
|
||||
-(void)onTTSPlayError:(QCPlayerError* _Nullable)playError;
|
||||
|
||||
/// 当前播放的字符,当前播放的字符在所在的句子中的下标.
|
||||
/// @param currentWord 当前读到的单个字,是一个估算值不一定准确
|
||||
/// @param currentIdex 当前播放句子中读到文字的下标
|
||||
-(void)onTTSPlayProgressWithCurrentWord:(NSString*_Nullable)currentWord CurrentIndex:(NSInteger)currentIdex;
|
||||
|
||||
|
||||
@end
|
||||
@ -0,0 +1,222 @@
|
||||
//
|
||||
// QCloudTTSEngine.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by dgw on 2022/1/10.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QCloudTTS/TtsError.h>
|
||||
#import <QCloudTTS/QCloudOfflineAuthInfo.h>
|
||||
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TtsMode) {
|
||||
TTS_MODE_ONLINE = 0, //在线模式
|
||||
TTS_MODE_OFFLINE = 1, //离线模式
|
||||
TTS_MODE_MIX = 2 //离在线混合模式
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// 回调接口
|
||||
@protocol QCloudTTSEngineDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
/// 合成结果回调
|
||||
/// @param data 音频数据
|
||||
/// @param utteranceId utteranceId
|
||||
/// @param text text
|
||||
/// @param type 该句话是以何种引擎生成的:0:在线 1:离线
|
||||
/// @deprecated
|
||||
-(void) onSynthesizeData:(NSData *_Nullable)data UtteranceId:(NSString *_Nullable)utteranceId Text:(NSString *_Nullable)text EngineType:(NSInteger)type;
|
||||
|
||||
/// 合成结果回调
|
||||
/// @param data 音频数据
|
||||
/// @param utteranceId utteranceId
|
||||
/// @param text text
|
||||
/// @param type 该句话是以何种引擎生成的:0:在线 1:离线
|
||||
/// @param requestId 请求ID,仅engineType为0时不为nil,用于排查问题
|
||||
-(void) onSynthesizeData:(NSData *_Nullable)data UtteranceId:(NSString *_Nullable)utteranceId Text:(NSString *_Nullable)text EngineType:(NSInteger)type RequestId:(NSString* _Nullable)requestId;
|
||||
|
||||
/// 合成结果回调
|
||||
/// @param data 音频数据
|
||||
/// @param utteranceId utteranceId
|
||||
/// @param text text
|
||||
/// @param type 该句话是以何种引擎生成的:0:在线 1:离线
|
||||
/// @param respJson 请求结果
|
||||
-(void) onSynthesizeData:(NSData *_Nullable)data UtteranceId:(NSString *_Nullable)utteranceId Text:(NSString *_Nullable)text EngineType:(NSInteger)type RequestId:(NSString* _Nullable)requestId RespJson:(NSString* _Nullable)respJson;
|
||||
|
||||
@required
|
||||
/// 错误回调
|
||||
/// @param error 错误信息
|
||||
/// @param utteranceId utteranceId
|
||||
/// @param text text
|
||||
-(void) onError:(TtsError *_Nullable)error UtteranceId:(NSString *_Nullable)utteranceId Text:(NSString *_Nullable)text;
|
||||
|
||||
|
||||
/// 返回离线合成模块授权信息,使用混合或者离线模式时,收到此方法成功回调后才可以调用合成接口
|
||||
/// 如果您下载的是在线版TTS SDK ,或者只使用在线合成模式,请忽略此方法
|
||||
/// @param OfflineAuthInfo 授权信息,当OfflineAuthInfo.err_msg为0时授权成功,详见QCloudOfflineAuthInfo.h
|
||||
-(void) onOfflineAuthInfo:(QCloudOfflineAuthInfo* _Nonnull )OfflineAuthInfo;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/// 语音合成引擎接口
|
||||
@interface QCloudTTSEngine : NSObject
|
||||
|
||||
|
||||
/// 获得QCloudTTSEngine实例
|
||||
+(id _Nullable )getShareInstance;
|
||||
|
||||
/// 销毁QCloudTTSEngine实例
|
||||
+(void) instanceRelease;
|
||||
|
||||
|
||||
/// 初始化引擎
|
||||
/// @param mode 引擎模式,在线、离线、混合,如切换引擎,需要先执行instanceRelease
|
||||
/// @param delegate 用于接收结果的代理
|
||||
-(void) engineInit:(TtsMode)mode Delegate:(id<QCloudTTSEngineDelegate> _Nonnull) delegate;
|
||||
|
||||
|
||||
/// 取消合成,清空内部合成队列
|
||||
-(TtsError *_Nullable) cancel;
|
||||
|
||||
/// 合成接口,支持持续调用添加文本
|
||||
/// @param text 需要合成的文本
|
||||
/// @param utteranceId 用于标记文本的id,合成完成后随音频文件或者错误接口返回,可为空
|
||||
-(TtsError *_Nullable) synthesize:(NSString *_Nonnull)text UtteranceId:(NSString *_Nullable)utteranceId;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// 配置在线引擎鉴权参数
|
||||
/// @param appId appId
|
||||
/// @param secretId secretId
|
||||
/// @param secretKey secretKey
|
||||
/// @param token token,可为空,如果使用sts临时证书鉴权,secretId和secretKey均入参临时的,同时需要入参对应的token,
|
||||
/// sts临时证书具体详见https://cloud.tencent.com/document/product/598/33416 (开发调试时建议先用普通方式鉴权,token填nil)
|
||||
-(void) setOnlineAuthParam:(NSInteger)appId SecretId:(NSString* _Nonnull)secretId SecretKey:(NSString* _Nonnull)secretKey Token:(NSString* _Nullable)token;
|
||||
|
||||
|
||||
|
||||
///online语音相关设置
|
||||
|
||||
/// 设置在线语速,对setOnlineParam的封装
|
||||
/// @param voiceSpeed 默认0,代表正常速度
|
||||
-(void)setOnlineVoiceSpeed:(float)voiceSpeed;
|
||||
|
||||
/// 设置在线音色ID,对setOnlineParam的封装
|
||||
/// @param voiceType 默认1001,音色id可查看官网文档https://cloud.tencent.com/document/product/1073/37995
|
||||
-(void)setOnlineVoiceType:(int)voiceType;
|
||||
|
||||
/// 设置在线引擎音量,对setOnlineParam的封装
|
||||
/// @param voiceVolume 默认0,代表正常音量,没有静音选项
|
||||
-(void)setOnlineVoiceVolume:(float)voiceVolume;
|
||||
|
||||
/// 设置主语言类型,对setOnlineParam的封装
|
||||
/// @param primaryLanguage 1:中文 2:英文 默认1
|
||||
-(void)setOnlineVoiceLanguage:(int)primaryLanguage;
|
||||
|
||||
///在线编码格式,如无业务特殊需求不建议更改(默认"mp3",目前支持"mp3","wav","pcm",若更改为pcm不支持直接播放,对setOnlineParam的封装
|
||||
-(void)setOnlineCodec:(NSString* _Nonnull) code;
|
||||
|
||||
/// 项目ID
|
||||
/// @param projectId 默认0, 对setOnlineParam的封装
|
||||
-(void)setOnlineProjectId:(int)projectId;
|
||||
|
||||
/// 是否开启时间戳功能,默认为false,对setOnlineParam的封装
|
||||
- (void)setOnlineEnableSubtitle:(Boolean)val;
|
||||
|
||||
/// 断句敏感阈值,默认值为:0,对setOnlineParam的封装
|
||||
- (void)setOnlineSegmentRate:(int)val;
|
||||
|
||||
/// 控制合成音频的情感,仅支持多情感音色使用,对setOnlineParam的封装
|
||||
- (void)setOnlineEmotionCategory:(NSString* _Nullable)val;
|
||||
|
||||
/// 控制合成音频情感程度,对setOnlineParam的封装
|
||||
- (void)setOnlineEmotionIntensity:(int)val;
|
||||
|
||||
/// 设置自定义参数,可使用该方法控制请求时的参数
|
||||
/// @param value为nil时将删除参数,否则会在请求中添加参数
|
||||
- (void)setOnlineParam:(NSString* _Nonnull)key value:(NSObject* _Nullable)value;
|
||||
|
||||
/// 设置区域
|
||||
/// @param region 默认为ap-shanghai,无特殊需求请勿更改
|
||||
- (void)setOnlineRegion:(NSString *)region;
|
||||
|
||||
//设置是否输出日志
|
||||
-(void)setEnableDebugLog:(BOOL)enableDebugLog;
|
||||
|
||||
|
||||
|
||||
|
||||
/// timeoutIntervalForRequest ,0.5s - 30s 默认15000ms(15s)
|
||||
/// @param timeout [2200,60000] 单位ms
|
||||
- (void)setTimeoutIntervalForRequest:(int)timeout;
|
||||
|
||||
|
||||
/// timeoutIntervalForResource 2.2s - 60s 默认30000ms(30s)
|
||||
/// @param timeout [500,30000] 单位ms
|
||||
-(void)setTimeoutIntervalForResource:(int) timeout;
|
||||
|
||||
|
||||
/// Mix模式下,出现网络错误后的检测间隔时间, 默认值5分钟
|
||||
///注意:每次检测时将使用所入参的一句文本请求服务器,如果后端合成成功将会额外消耗该句字数的合成额度
|
||||
/// @param checkNetworkIntervalTime 大于等于0 单位s, 等于0时持续检测,直到成功
|
||||
-(void)setCheckNetworkIntervalTime:(int) checkNetworkIntervalTime;
|
||||
|
||||
|
||||
//以下为离线语音相关参数配置
|
||||
|
||||
//resourceDir 离线资源路径
|
||||
-(void)setOfflineResourceDir:(NSString * _Nonnull) resourceDir;
|
||||
|
||||
//voiceSpeed [0.5,2.0]
|
||||
-(void)setOfflineVoiceSpeed:(float) voiceSpeed;
|
||||
|
||||
//voiceType 离线音色名称,名称配置位于音色资源目录\voices\config.json 中,可自行指定更多的音色,demo中仅提供"pb"、"femalen"两种
|
||||
-(void)setOfflineVoiceType:(NSString *_Nonnull) voiceType;
|
||||
|
||||
//voiceVolume >0
|
||||
-(void)setOfflineVoiceVolume:(float) voiceVolume;
|
||||
|
||||
/// 配置离线TTS授权参数: 在线下载密钥(第一次激活设备需要联网)
|
||||
/// @param licPk 密钥对应的licPk,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param licKey 密钥对应的licKey,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param secretId 腾讯云secretId (可能与在线模式不是同一个账号,需要输入购买离线SDK对应的账号的secretId)
|
||||
/// @param secretKey 腾讯云 secretKey(可能与在线模式不是同一个账号,需要输入购买离线SDK对应的账号的secretKey)
|
||||
/// @param token token,可为空,如果使用sts临时证书鉴权,secretId和secretKey均入参临时的,同时需要入参对应的token,
|
||||
-(void)setOfflineAuthParamDoOnline:(NSString* _Nonnull)licPk
|
||||
LicKey:(NSString* _Nonnull)licKey
|
||||
SecretId:(NSString* _Nonnull)secretId
|
||||
SecretKey:(NSString* _Nonnull)secretKey
|
||||
Token:(NSString* _Nullable)token;
|
||||
|
||||
/// 配置离线TTS授权参数: 在线下载密钥(第一次激活设备需要联网)
|
||||
/// @param licPk 密钥对应的licPk,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param licKey 密钥对应的licKey,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param secretId 腾讯云secretId (可能与在线模式不是同一个账号,需要输入购买离线SDK对应的账号的secretId)
|
||||
/// @param secretKey 腾讯云 secretKey(可能与在线模式不是同一个账号,需要输入购买离线SDK对应的账号的secretKey)
|
||||
/// @param token token,可为空,如果使用sts临时证书鉴权,secretId和secretKey均入参临时的,同时需要入参对应的token,
|
||||
/// @param refreshAuth 是否强制联网刷新授权(NO:仅第一次联网激活下载授权文件; YES:联网刷新授权文件,无网络下将激活失败)
|
||||
-(void)setOfflineAuthParamDoOnline:(NSString* _Nonnull)licPk
|
||||
LicKey:(NSString* _Nonnull)licKey
|
||||
SecretId:(NSString* _Nonnull)secretId
|
||||
SecretKey:(NSString* _Nonnull)secretKey
|
||||
Token:(NSString* _Nullable)token
|
||||
RefreshAuth:(BOOL)refreshAuth;
|
||||
|
||||
|
||||
/// 配置离线TTS授权参数: 直接传入密钥(第一次激活也不需要联网)
|
||||
/// @param lic 授权密钥 ,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param licPk 该密钥对应的licPk,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
/// @param licSign 该密钥对应的licSign,请在腾讯云官网页面获取,或者由腾讯云商务线下下发
|
||||
-(void)setOfflineAuthParamDoOffline:(NSString* _Nonnull)lic
|
||||
LicPk:(NSString* _Nonnull)licPk
|
||||
LicSign:(NSString* _Nonnull)licSign;
|
||||
@end
|
||||
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
//
|
||||
// TtsError.h
|
||||
// cloud-tts-sdk-ios
|
||||
//
|
||||
// Created by dgw on 2022/1/10.
|
||||
//
|
||||
|
||||
#ifndef TtsError_h
|
||||
#define TtsError_h
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, TtsErrorCode) {
|
||||
|
||||
TTS_ERROR_CODE_UNINITIALIZED = -100, //Engine uninitialized
|
||||
TTS_ERROR_CODE_GENERATE_SIGN_FAIL = -101, //generate sign failed
|
||||
TTS_ERROR_CODE_NETWORK_CONNECT_FAILED = 102, //network connect failed
|
||||
TTS_ERROR_CODE_DECODE_FAIL = -103, //JSON Response Parsing Error
|
||||
TTS_ERROR_CODE_SERVER_RESPONSE_ERROR = -104, //Server response error
|
||||
TTS_ERROR_CODE_CANCEL_FAILURE = -106, //Cancel failure,please try again later
|
||||
|
||||
TTS_ERROR_CODE_OFFLINE_FAILURE = -107,//Offline synthesize failed, please check your text and VoiceType
|
||||
TTS_ERROR_CODE_OFFLINE_INIT_FAILURE = -108,//Offline engine initialization failed, please check resource files
|
||||
TTS_ERROR_CODE_OFFLINE_AUTH_FAILURE = -109,//Offline engine auth failure
|
||||
TTS_ERROR_CODE_OFFLINE_TEXT_TOO_LONG = -110, //Offline synthesize failed,text too long,MAX <= 1024 byte
|
||||
TTS_ERROR_CODE_OFFLINE_VOICE_AUTH_FAILURE = -111, //This voice not authorized, please change it
|
||||
|
||||
TTS_ERROR_CODE_OFFLINE_NOSUPPORT = -900 //This SDK only supports online mode
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// 后端返回的错误信息
|
||||
@interface TtsServiceError : NSObject
|
||||
|
||||
@property (nonatomic, copy) NSString* _Nullable err_code;
|
||||
@property (nonatomic, copy) NSString* _Nullable msg;
|
||||
@property (nonatomic, copy) NSString* _Nullable respose;
|
||||
|
||||
+(instancetype _Nonnull)getTtsServiceError:(NSString *_Nullable)err_code ErrorMsg:(NSString* _Nullable)msg Respose:(NSString* _Nullable)respose;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/// 错误信息类
|
||||
@interface TtsError : NSObject
|
||||
|
||||
@property (nonatomic, assign) TtsErrorCode err_code; //错误码
|
||||
|
||||
@property (nonatomic, copy, nullable) NSString* msg; //错误信息
|
||||
|
||||
@property (nonatomic, copy, nullable) NSError * error; //系统抛出的错误信息(不一定有,可能为空)
|
||||
|
||||
@property (nonatomic, strong ,nullable) TtsServiceError * serviceError;//服务器返回的错误信息(不一定有,可能为空)
|
||||
|
||||
+(instancetype _Nonnull)getTtsError:(TtsErrorCode)err_code
|
||||
TtsServiceError:(TtsServiceError* _Nullable)serviceError
|
||||
NSErrorMsg:(NSError *_Nullable)error;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* TtsError_h */
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,207 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>files</key>
|
||||
<dict>
|
||||
<key>Headers/QCPlayerError.h</key>
|
||||
<data>
|
||||
GcBglYzaVwjgHfWYqQ+ZUSG3Uao=
|
||||
</data>
|
||||
<key>Headers/QCloudMediaPlayer.h</key>
|
||||
<data>
|
||||
cSuhgHCm42prRzNangBO/0w2qVA=
|
||||
</data>
|
||||
<key>Headers/QCloudMediaPlayer2.h</key>
|
||||
<data>
|
||||
WJT6QPmSe5jTGllxIhKljhOzgds=
|
||||
</data>
|
||||
<key>Headers/QCloudOfflineAuthInfo.h</key>
|
||||
<data>
|
||||
tolrRjjKQqWWjKFyUooedkLsIpc=
|
||||
</data>
|
||||
<key>Headers/QCloudPlayerDelegate.h</key>
|
||||
<data>
|
||||
EegDLAlAPciyhnxDnXB4oChNttQ=
|
||||
</data>
|
||||
<key>Headers/QCloudTTSEngine.h</key>
|
||||
<data>
|
||||
UQB6vhAlGndL5YeDl1ZEw3vyc2M=
|
||||
</data>
|
||||
<key>Headers/TtsError.h</key>
|
||||
<data>
|
||||
325otzQ/Cu8q0kGDUVU4SMibWZU=
|
||||
</data>
|
||||
<key>Info.plist</key>
|
||||
<data>
|
||||
2dDQqFGhXP8TDAtqPWpKsMxer5Y=
|
||||
</data>
|
||||
</dict>
|
||||
<key>files2</key>
|
||||
<dict>
|
||||
<key>Headers/QCPlayerError.h</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
GcBglYzaVwjgHfWYqQ+ZUSG3Uao=
|
||||
</data>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
B5vdIZRO7860RHiBmzU42oztYKV5/+TSI8nZImlfEHI=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Headers/QCloudMediaPlayer.h</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
cSuhgHCm42prRzNangBO/0w2qVA=
|
||||
</data>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
dkOfBxGqa1bMsg4SkwH8H4qtwDba0not3AqU/goz0Mk=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Headers/QCloudMediaPlayer2.h</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
WJT6QPmSe5jTGllxIhKljhOzgds=
|
||||
</data>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
aWSR35tX7sKARPhOHbJmpq4FYVNmlR7ST5aqDc4aLn4=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Headers/QCloudOfflineAuthInfo.h</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
tolrRjjKQqWWjKFyUooedkLsIpc=
|
||||
</data>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
KLQptLzwtaJYFeFD49+ue23NLWqaZAyjWljo3VimNwg=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Headers/QCloudPlayerDelegate.h</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
EegDLAlAPciyhnxDnXB4oChNttQ=
|
||||
</data>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
LrSEc56s6we6W+qm6wzJ4RFsfJXfvIM0MDzD1swuSqE=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Headers/QCloudTTSEngine.h</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
UQB6vhAlGndL5YeDl1ZEw3vyc2M=
|
||||
</data>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
hsHHpz1PLxxiMLlxsy6ZqRbS7NlmoYybdFTUHQnrsXA=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Headers/TtsError.h</key>
|
||||
<dict>
|
||||
<key>hash</key>
|
||||
<data>
|
||||
325otzQ/Cu8q0kGDUVU4SMibWZU=
|
||||
</data>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
Jtc052fx72HaSNcpnKz0cL2f8VNTIYa1+DhDUcQX2v8=
|
||||
</data>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^version.plist$</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>rules2</key>
|
||||
<dict>
|
||||
<key>.*\.dSYM($|/)</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>11</real>
|
||||
</dict>
|
||||
<key>^(.*/)?\.DS_Store$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>2000</real>
|
||||
</dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^Info\.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^PkgInfo$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^embedded\.provisionprofile$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^version\.plist$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
Reference in New Issue
Block a user