TSGenerateRintoneOperation.swift 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. //
  2. // TSGenerateRintoneOperation.swift
  3. // AIRingtone
  4. //
  5. // Created by 100Years on 2025/3/21.
  6. //
  7. import Combine
  8. import Alamofire
  9. class TSGenerateRintoneOperationQueue: TSBaseOperationQueue {
  10. static let shared:TSGenerateRintoneOperationQueue = TSGenerateRintoneOperationQueue()
  11. // 存储每个操作的 AnyCancellable
  12. private var stateables: [String: AnyCancellable] = [:]
  13. var rintoneOperationStateChanged:((String)->Void)?
  14. func creatOperation(uuid: String) -> TSGenerateRintoneOperation {
  15. let operation = super.creatOperation(uuid: uuid, type: TSGenerateRintoneOperation.self)
  16. if let rintoneOperation = operation as? TSGenerateRintoneOperation {
  17. stateables[uuid] = rintoneOperation.$stateDatauPblished.sink { [weak self] state in
  18. guard let self = self else { return }
  19. DispatchQueue.main.async {
  20. self.rintoneOperationStateChanged?(uuid)
  21. let uuidData = self.getUUIDData(uuid: uuid)
  22. NotificationCenter.default.post(
  23. name: .kGenerateRintoneOperationChanged,
  24. object: nil,
  25. userInfo: [
  26. "uuid": uuid,
  27. "count":self.queue.maxConcurrentOperationCount,
  28. "state":uuidData.0,
  29. "actionInfo":uuidData.1,
  30. ])
  31. }
  32. }
  33. }
  34. return operation as! TSGenerateRintoneOperation
  35. }
  36. func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
  37. if let rintoneOperation = TSGenerateRintoneOperationQueue.shared.findOperation(uuid: uuid) as? TSGenerateRintoneOperation {
  38. dePrint("TSBaseOperation stateDatauPblished 发送 = \(rintoneOperation.stateDatauPblished)")
  39. return (rintoneOperation.stateDatauPblished.0,rintoneOperation.currentActionInfoModel)
  40. }
  41. return (.none,TSActionInfoModel())
  42. }
  43. override func cancelOperations(uuid: String) {
  44. super.cancelOperations(uuid: uuid)
  45. stateables.removeValue(forKey: uuid)
  46. }
  47. }
  48. class TSGenerateRintoneOperation: TSBaseOperation , @unchecked Sendable{
  49. let actionInfoDict:[String:Any] = [
  50. "actionType":"music_create",
  51. "comments": "Success",
  52. "costTime":15,
  53. "createdTimestamp":1741338454,
  54. "id":1536,
  55. "percent":1,
  56. "request":"{\"prompt\": \"Create a Techno ringtone with a repetitive bassline, crisp hi-hats, and subtle synth textures. Use a BPM of 125-130 for a sleek, modern sound., Create a uplifting and modern music track blending Pop, Electronic, and Ambient elements. Use a BPM of 100-120, a catchy melody with synth or piano, warm harmonies, and a mix of electronic and organic sounds. Ensure a clear structure (Intro, Verse, Chorus, Outro) and a light, positive vibe suitable for background or casual listening\", \"duration\": 5}",
  57. "response":"{\"coverUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/f0fb7739-a5cc-4805-9b68-b4a5890eb285.png\", \"title\": \"Neon Pulse\\\" \\n\\\"Horizon Glow\", \"musicUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/c47d40dd-d07c-4edc-a6d9-8382438149d1.wav\"}",
  58. "status":"success"
  59. ]
  60. @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil){
  61. didSet{
  62. dePrint("TSBaseOperation stateDatauPblished didSet = \(stateDatauPblished)")
  63. if case .start = stateDatauPblished.0 {
  64. start()
  65. }else if stateDatauPblished.0.isResult {
  66. finished()
  67. }
  68. }
  69. }
  70. private var creatRequest:Request?
  71. private var queryRequest:Request?
  72. private var stopNetwork = false
  73. private var generatingProgress = 0
  74. private var aiText:String = ""
  75. private var action_id:Int = 0
  76. var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
  77. @Published var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
  78. func replaceSaveInfoModel(model:TSActionInfoModel){
  79. model.uuid = uuid
  80. TSAIRintoneHistory.replaceModel(oldID: currentActionInfoModel.id, newModel: model)
  81. currentActionInfoModel = model
  82. dePrint("TSAIRintoneHistory.listModelArray.count=\(TSAIRintoneHistory.listModelArray.count)")
  83. dePrint("model actionStatus 发出=\(model.actionStatus)")
  84. currentActionInfoModelChanged?(currentActionInfoModel)
  85. }
  86. //模拟数据
  87. func creatRintone(oldModel:TSActionInfoModel? = nil,prompt:String,promptSort:String) {
  88. stateDatauPblished = (.start,nil)
  89. if let model = oldModel {
  90. currentActionInfoModel = model
  91. }else {
  92. currentActionInfoModel.id = Int.timestampInt()
  93. currentActionInfoModel.request.prompt = prompt
  94. currentActionInfoModel.request.promptSort = promptSort
  95. currentActionInfoModel.actionStatus = .pending
  96. currentActionInfoModel.status = "pending"
  97. }
  98. replaceSaveInfoModel(model: currentActionInfoModel)
  99. stateDatauPblished = (.start,currentActionInfoModel)
  100. let time = 2.0
  101. for i in 0..<Int(time){
  102. kDelayOnMainThread(Double(i)) {
  103. let progress = Float(i)/100.0
  104. self.currentActionInfoModel.percent = progress
  105. self.currentActionInfoModel.actionStatus = .running
  106. self.currentActionInfoModel.status = "running"
  107. self.replaceSaveInfoModel(model: self.currentActionInfoModel)
  108. self.stateDatauPblished = (.progressString(self.generating(progress: progress)),nil)
  109. }
  110. }
  111. kDelayOnMainThread(time+1.0) {
  112. if Bool.random(), let infoModel = TSActionInfoModel(JSON: self.actionInfoDict){
  113. infoModel.id = Int.uuid
  114. self.replaceSaveInfoModel(model: infoModel)
  115. self.stateDatauPblished = (.success(nil),self.currentActionInfoModel)
  116. }else{
  117. self.currentActionInfoModel.actionStatus = .failed
  118. self.currentActionInfoModel.status = "failed"
  119. self.replaceSaveInfoModel(model: self.currentActionInfoModel)
  120. self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
  121. }
  122. TSAIRintoneHistory.dePrintAllModel()
  123. }
  124. }
  125. // func creatRintone(text:String) {
  126. // generatingProgress = 0
  127. // aiText = text
  128. // let postDict:[String : Any] = [
  129. // "prompt":text,
  130. // "duration":20
  131. // ]
  132. // stateDatauPblished = (.start,nil)
  133. // creatRequest = TSNetworkShared.post(urlType: .musicCreate,parameters: postDict) { [weak self] data,error in
  134. // guard let self = self else { return }
  135. // if let dataDict = data as? [String:Any] ,
  136. // dataDict.safeInt(forKey: "code") == 200,
  137. // let actionId = dataDict["actionId"] as? Int{
  138. // if stopNetwork == false {
  139. // self.getActionInfo(action_id:actionId)
  140. // }
  141. // }else{
  142. // self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
  143. // }
  144. // }
  145. // }
  146. func getActionInfo(action_id:Int){
  147. self.action_id = action_id
  148. queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
  149. guard let self = self else { return }
  150. if let result = kNetWorkResultSuccess(data: data) {
  151. if let genmojiModel = TSActionInfoModel(JSON: result) {
  152. switch genmojiModel.actionStatus {
  153. case .success:
  154. TSToastShared.hideLoading()
  155. self.stateDatauPblished = (.success(nil),genmojiModel)
  156. generatingProgress = 0
  157. case .failed:
  158. self.stateDatauPblished = (.failed(kNetWorkMessage(data: data) ?? ""),nil)
  159. generatingProgress = 0
  160. default:
  161. stateDatauPblished = (.progressString(generating(progress: genmojiModel.percent)),nil)
  162. if stopNetwork == false {
  163. kDelayOnMainThread(1.0) {
  164. self.getActionInfo(action_id: action_id)
  165. }
  166. }
  167. }
  168. }
  169. }else{
  170. self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
  171. }
  172. }
  173. }
  174. func generating(progress:Float) -> String {
  175. //Generating 0%-100%
  176. var progressInt = Int(progress*100)
  177. if generatingProgress >= progressInt{
  178. return "Generating \(generatingProgress)%"
  179. }
  180. if progressInt > 99 {
  181. progressInt = 99
  182. }
  183. generatingProgress = progressInt
  184. return "Generating \(progressInt)%"
  185. }
  186. func cancelAllRequest(){
  187. creatRequest?.cancel()
  188. queryRequest?.cancel()
  189. stopNetwork = true
  190. cancel()
  191. }
  192. }