123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- //
- // TSGenerateRintoneOperation.swift
- // AIRingtone
- //
- // Created by 100Years on 2025/3/21.
- //
- import Combine
- import Alamofire
- class TSGenerateRintoneOperationQueue: TSBaseOperationQueue {
- static let shared:TSGenerateRintoneOperationQueue = TSGenerateRintoneOperationQueue()
-
-
- // 存储每个操作的 AnyCancellable
- private var stateables: [String: AnyCancellable] = [:]
-
- var rintoneOperationStateChanged:((String)->Void)?
-
- func creatOperation(uuid: String) -> TSGenerateRintoneOperation {
- let operation = super.creatOperation(uuid: uuid, type: TSGenerateRintoneOperation.self)
- if let rintoneOperation = operation as? TSGenerateRintoneOperation {
- stateables[uuid] = rintoneOperation.$stateDatauPblished.sink { [weak self] state in
- guard let self = self else { return }
- DispatchQueue.main.async {
- self.rintoneOperationStateChanged?(uuid)
-
- let uuidData = self.getUUIDData(uuid: uuid)
- NotificationCenter.default.post(
- name: .kGenerateRintoneOperationChanged,
- object: nil,
- userInfo: [
- "uuid": uuid,
- "count":self.queue.maxConcurrentOperationCount,
- "state":uuidData.0,
- "actionInfo":uuidData.1,
- ])
- }
- }
- }
- return operation as! TSGenerateRintoneOperation
- }
-
- func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
- if let rintoneOperation = TSGenerateRintoneOperationQueue.shared.findOperation(uuid: uuid) as? TSGenerateRintoneOperation {
- dePrint("TSBaseOperation stateDatauPblished 发送 = \(rintoneOperation.stateDatauPblished)")
- return (rintoneOperation.stateDatauPblished.0,rintoneOperation.currentActionInfoModel)
- }
- return (.none,TSActionInfoModel())
- }
-
- override func cancelOperations(uuid: String) {
- super.cancelOperations(uuid: uuid)
- stateables.removeValue(forKey: uuid)
- }
- }
- class TSGenerateRintoneOperation: TSBaseOperation , @unchecked Sendable{
-
- let actionInfoDict:[String:Any] = [
- "actionType":"music_create",
- "comments": "Success",
- "costTime":15,
- "createdTimestamp":1741338454,
- "id":1536,
- "percent":1,
- "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}",
- "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\"}",
- "status":"success"
- ]
-
- @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil){
- didSet{
- dePrint("TSBaseOperation stateDatauPblished didSet = \(stateDatauPblished)")
- if case .start = stateDatauPblished.0 {
- start()
- }else if stateDatauPblished.0.isResult {
- finished()
- }
- }
- }
-
- private var creatRequest:Request?
- private var queryRequest:Request?
- private var stopNetwork = false
- private var generatingProgress = 0
- private var aiText:String = ""
- private var action_id:Int = 0
-
- var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
- @Published var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
- func replaceSaveInfoModel(model:TSActionInfoModel){
- model.uuid = uuid
- TSAIRintoneHistory.replaceModel(oldID: currentActionInfoModel.id, newModel: model)
- currentActionInfoModel = model
- dePrint("TSAIRintoneHistory.listModelArray.count=\(TSAIRintoneHistory.listModelArray.count)")
- dePrint("model actionStatus 发出=\(model.actionStatus)")
- currentActionInfoModelChanged?(currentActionInfoModel)
- }
- //模拟数据
- func creatRintone(oldModel:TSActionInfoModel? = nil,prompt:String,promptSort:String) {
- stateDatauPblished = (.start,nil)
- if let model = oldModel {
- currentActionInfoModel = model
- }else {
- currentActionInfoModel.id = Int.timestampInt()
- currentActionInfoModel.request.prompt = prompt
- currentActionInfoModel.request.promptSort = promptSort
- currentActionInfoModel.actionStatus = .pending
- currentActionInfoModel.status = "pending"
- }
-
- replaceSaveInfoModel(model: currentActionInfoModel)
- stateDatauPblished = (.start,currentActionInfoModel)
- let time = 2.0
-
- for i in 0..<Int(time){
- kDelayOnMainThread(Double(i)) {
- let progress = Float(i)/100.0
- self.currentActionInfoModel.percent = progress
- self.currentActionInfoModel.actionStatus = .running
- self.currentActionInfoModel.status = "running"
- self.replaceSaveInfoModel(model: self.currentActionInfoModel)
- self.stateDatauPblished = (.progressString(self.generating(progress: progress)),nil)
- }
- }
- kDelayOnMainThread(time+1.0) {
- if Bool.random(), let infoModel = TSActionInfoModel(JSON: self.actionInfoDict){
- infoModel.id = Int.uuid
- self.replaceSaveInfoModel(model: infoModel)
- self.stateDatauPblished = (.success(nil),self.currentActionInfoModel)
- }else{
- self.currentActionInfoModel.actionStatus = .failed
- self.currentActionInfoModel.status = "failed"
- self.replaceSaveInfoModel(model: self.currentActionInfoModel)
- self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
- }
- TSAIRintoneHistory.dePrintAllModel()
- }
- }
-
- // func creatRintone(text:String) {
- // generatingProgress = 0
- // aiText = text
- // let postDict:[String : Any] = [
- // "prompt":text,
- // "duration":20
- // ]
- // stateDatauPblished = (.start,nil)
- // creatRequest = TSNetworkShared.post(urlType: .musicCreate,parameters: postDict) { [weak self] data,error in
- // guard let self = self else { return }
- // if let dataDict = data as? [String:Any] ,
- // dataDict.safeInt(forKey: "code") == 200,
- // let actionId = dataDict["actionId"] as? Int{
- // if stopNetwork == false {
- // self.getActionInfo(action_id:actionId)
- // }
- // }else{
- // self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
- // }
- // }
- // }
-
- func getActionInfo(action_id:Int){
- self.action_id = action_id
- queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
- guard let self = self else { return }
- if let result = kNetWorkResultSuccess(data: data) {
- if let genmojiModel = TSActionInfoModel(JSON: result) {
- switch genmojiModel.actionStatus {
- case .success:
- TSToastShared.hideLoading()
- self.stateDatauPblished = (.success(nil),genmojiModel)
- generatingProgress = 0
- case .failed:
- self.stateDatauPblished = (.failed(kNetWorkMessage(data: data) ?? ""),nil)
- generatingProgress = 0
- default:
- stateDatauPblished = (.progressString(generating(progress: genmojiModel.percent)),nil)
- if stopNetwork == false {
- kDelayOnMainThread(1.0) {
- self.getActionInfo(action_id: action_id)
- }
- }
- }
- }
- }else{
- self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
- }
- }
- }
- func generating(progress:Float) -> String {
- //Generating 0%-100%
- var progressInt = Int(progress*100)
- if generatingProgress >= progressInt{
- return "Generating \(generatingProgress)%"
- }
- if progressInt > 99 {
- progressInt = 99
- }
-
- generatingProgress = progressInt
- return "Generating \(progressInt)%"
- }
-
-
-
- func cancelAllRequest(){
- creatRequest?.cancel()
- queryRequest?.cancel()
- stopNetwork = true
-
- cancel()
- }
-
-
- }
|