|  | @@ -220,6 +220,7 @@ public class BFRecordScreenController: BFBaseViewController {
 | 
	
		
			
				|  |  |              withDrawBtn.isHidden = isNormalPlaying
 | 
	
		
			
				|  |  |              subtitleBtn.isHidden = isNormalPlaying
 | 
	
		
			
				|  |  |              soundSettingBtn.isHidden = isNormalPlaying
 | 
	
		
			
				|  |  | +            voiceSettingBtn.isHidden = isNormalPlaying
 | 
	
		
			
				|  |  |              withDrawBtn.isHidden = isNormalPlaying
 | 
	
		
			
				|  |  |              recordBtn.isHidden = isNormalPlaying
 | 
	
		
			
				|  |  |              cameraFlipBtn.isHidden = !(!isNormalPlaying && (currMediaType == .Camera) && !isDragingProgressSlder)
 | 
	
	
		
			
				|  | @@ -770,12 +771,33 @@ public class BFRecordScreenController: BFBaseViewController {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              // 更新缓存数据
 | 
	
		
			
				|  |  |              if index < (wself.itemModels[wself.currItemModelIndex ].titleStickers.count ) {
 | 
	
		
			
				|  |  | +                //add by ak 1刷新变音缓存
 | 
	
		
			
				|  |  | +                let deleteTaskids:[String]? = wself.tts?.changedTitle(newtext, oldText:      wself.itemModels[wself.currItemModelIndex ].titleStickers[index].text) as? [String]
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  | +                //2刷新变量后的老音频数据
 | 
	
		
			
				|  |  | +                if((deleteTaskids?.count ?? 0) > 0){
 | 
	
		
			
				|  |  | +                    for taskid in deleteTaskids!{
 | 
	
		
			
				|  |  | +                        wself.itemModels[wself.currItemModelIndex].voiceChangeStickers =         wself.itemModels[wself.currItemModelIndex].voiceChangeStickers.filter { (model) -> Bool in
 | 
	
		
			
				|  |  | +                            if model.ttsTaskID == taskid {
 | 
	
		
			
				|  |  | +                                //fase 是不要
 | 
	
		
			
				|  |  | +                                return false
 | 
	
		
			
				|  |  | +                            }else {
 | 
	
		
			
				|  |  | +                                return true
 | 
	
		
			
				|  |  | +                            }
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  | +             
 | 
	
		
			
				|  |  |                  if newtext.count == 0 {
 | 
	
		
			
				|  |  |                      // 删除数据
 | 
	
		
			
				|  |  |                      BFLog(message: "清空字幕操作要删除原字幕 sticker 数据")
 | 
	
		
			
				|  |  |                      wself.itemModels[wself.currItemModelIndex ].titleStickers.remove(at: index)
 | 
	
		
			
				|  |  |                      wself.subtitleLabel.text = ""
 | 
	
		
			
				|  |  |                  } else {
 | 
	
		
			
				|  |  | +                    wself.loadingView.loadShow()
 | 
	
		
			
				|  |  | +                    wself.tts?.runNextTask()
 | 
	
		
			
				|  |  | +                    //更新已经变音数据
 | 
	
		
			
				|  |  |                      // 更新数据
 | 
	
		
			
				|  |  |                      wself.itemModels[wself.currItemModelIndex ].titleStickers[index].text = newtext
 | 
	
		
			
				|  |  |                      wself.subtitleLabel.text = newtext
 | 
	
	
		
			
				|  | @@ -815,6 +837,18 @@ public class BFRecordScreenController: BFBaseViewController {
 | 
	
		
			
				|  |  |              if actionType == .VoiceSettingActionConfirm{//要生成真实音频文件
 | 
	
		
			
				|  |  |                  wself.tts?.stopTTS("")
 | 
	
		
			
				|  |  |                  BFLog(2, message: "确认选择发音人操作")
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  | +                //切换了发音人
 | 
	
		
			
				|  |  | +                if(wself.mSelectVoiced != selectVoice){
 | 
	
		
			
				|  |  | +                    BFLog(2, message: "老发音人\(wself.mSelectVoiced?.name ?? "") 新发音人\(selectVoice?.name ?? "")")
 | 
	
		
			
				|  |  | +                    //1,清空发音人缓存数据
 | 
	
		
			
				|  |  | +                    wself.tts?.changedVoice(selectVoice?.voice ?? "")
 | 
	
		
			
				|  |  | +                    //2,清空已经生成的变音sticker
 | 
	
		
			
				|  |  | +                    for itemModel in wself.itemModels{
 | 
	
		
			
				|  |  | +                         itemModel.voiceChangeStickers.removeAll()
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  |                  wself.mSelectVoiced = selectVoice
 | 
	
		
			
				|  |  |                  wself.voiceSettingView.flushSelectVoiceStatus(voiceStatue: .isSelected)
 | 
	
		
			
				|  |  |                  if(wself.mSelectVoiced != nil){
 | 
	
	
		
			
				|  | @@ -822,7 +856,7 @@ public class BFRecordScreenController: BFBaseViewController {
 | 
	
		
			
				|  |  |                      wself.voiceIconView.setNetImage(url: "\(wself.mSelectVoiced?.avatarUrl ?? "")")
 | 
	
		
			
				|  |  |                      if(!wself.voiceChangeStickerFinish(itemIndex: wself.currItemModelIndex)){
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                        wself.loadingView.loading()
 | 
	
		
			
				|  |  | +                        wself.loadingView.loadShow()
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                      //静默转换语音
 | 
	
		
			
				|  |  |                      wself.tts?.runNextTask()
 | 
	
	
		
			
				|  | @@ -846,9 +880,7 @@ public class BFRecordScreenController: BFBaseViewController {
 | 
	
		
			
				|  |  |                      //首次选直接转
 | 
	
		
			
				|  |  |                      wself.tts?.startTTS("", taskId: "", isAudition: true,fontName: selectVoice?.voice ?? "")
 | 
	
		
			
				|  |  |                      wself.voiceSettingView.flushSelectVoiceStatus(voiceStatue: .isLoading)
 | 
	
		
			
				|  |  | -                }else{
 | 
	
		
			
				|  |  | -                    
 | 
	
		
			
				|  |  | -         
 | 
	
		
			
				|  |  | +                }else{ 
 | 
	
		
			
				|  |  |                      if(wself.mSelectVoiced == selectVoice){  //是同一个发音人暂停
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                          BFLog(message: "试听播放器状态\(String(describing: wself.tts?.voicePlayer.state.rawValue) )")
 | 
	
	
		
			
				|  | @@ -866,8 +898,7 @@ public class BFRecordScreenController: BFBaseViewController {
 | 
	
		
			
				|  |  |                          wself.voiceSettingView.flushSelectVoiceStatus(voiceStatue: .isLoading)
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                wself.mSelectVoiced = selectVoice
 | 
	
		
			
				|  |  | + 
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -1041,18 +1072,19 @@ public class BFRecordScreenController: BFBaseViewController {
 | 
	
		
			
				|  |  |                  newSubtitle.setting = wself.subtitleSettingView.subtitle.setting
 | 
	
		
			
				|  |  |                  tempItem?.titleStickers.append(newSubtitle)
 | 
	
		
			
				|  |  |                  
 | 
	
		
			
				|  |  | -                //add by ak 有字幕&设置发音人 添加到转换缓存
 | 
	
		
			
				|  |  | -                if(wself.mSelectVoiced != nil){
 | 
	
		
			
				|  |  | -                    let ttsModel = BFTTSTaskModel.init()
 | 
	
		
			
				|  |  | -                    ttsModel.timelineIn = newSubtitle.timelineIn
 | 
	
		
			
				|  |  | -                    ttsModel.timelineOut = newSubtitle.timelineOut
 | 
	
		
			
				|  |  | -                    ttsModel.fontName = wself.mSelectVoiced?.voice ?? ""
 | 
	
		
			
				|  |  | -                    ttsModel.recordId = recordId ?? ""
 | 
	
		
			
				|  |  | -                    ttsModel.tTtaskId = getUniqueId(desc: "tTtaskId")
 | 
	
		
			
				|  |  | -                    ttsModel.text = showText
 | 
	
		
			
				|  |  | -                    wself.tts?.pushTaskCache(ttsModel)
 | 
	
		
			
				|  |  | +                //add by ak 有字幕& 没有设置发音人也要添加到转换缓存
 | 
	
		
			
				|  |  | +                let ttsModel = BFTTSTaskModel.init()
 | 
	
		
			
				|  |  | +                ttsModel.timelineIn = newSubtitle.timelineIn
 | 
	
		
			
				|  |  | +                ttsModel.timelineOut = newSubtitle.timelineOut
 | 
	
		
			
				|  |  | +                ttsModel.fontName = wself.mSelectVoiced?.voice ?? ""
 | 
	
		
			
				|  |  | +                ttsModel.recordId = recordId ?? ""
 | 
	
		
			
				|  |  | +                ttsModel.tTtaskId = getUniqueId(desc: "tTtaskId")
 | 
	
		
			
				|  |  | +                ttsModel.text = showText
 | 
	
		
			
				|  |  | +                if(wself.mSelectVoiced == nil){
 | 
	
		
			
				|  |  | +                    wself.tts?.pushTaskCache(ttsModel, autoTranslate:false)
 | 
	
		
			
				|  |  | +                }else{
 | 
	
		
			
				|  |  | +                    wself.tts?.pushTaskCache(ttsModel, autoTranslate:true)
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2124,6 +2156,11 @@ public class BFRecordScreenController: BFBaseViewController {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      func play() {
 | 
	
		
			
				|  |  | +        //如果当前段有没有转完的发音人显示 Loadingview
 | 
	
		
			
				|  |  | +        if(!voiceChangeStickerFinish(itemIndex: currItemModelIndex,isShowLoadView: true)){
 | 
	
		
			
				|  |  | +          
 | 
	
		
			
				|  |  | +            return
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          BFLog(1, message: "开始播放 \(currentAssetProgress.seconds)")
 | 
	
		
			
				|  |  |          recorderManager?.voiceModel = nil
 | 
	
		
			
				|  |  |          events.append(WithDrawModel(type: 1, timestamp: currentAssetProgress, recordItem: rscurrentManager.recordItem!))
 | 
	
	
		
			
				|  | @@ -2794,17 +2831,51 @@ extension BFRecordScreenController: BFTTSManagerDelegte{
 | 
	
		
			
				|  |  |          voice.wavFilePath = model.wavFilePath
 | 
	
		
			
				|  |  |          voice.startCMTime = model.timelineIn
 | 
	
		
			
				|  |  |          voice.endCMTime = model.timelineOut
 | 
	
		
			
				|  |  | +        voice.ttsTaskID = model.tTtaskId
 | 
	
		
			
				|  |  |          itemModels[currItemModelIndex].voiceChangeStickers.append(voice)
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  |          //
 | 
	
		
			
				|  |  |          loadingView.titleL.text = "变音中 \(itemModels[currItemModelIndex].voiceChangeStickers.count / itemModels[currItemModelIndex].titleStickers.count)%"
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  | +        if(voiceChangeStickerFinish(itemIndex: currItemModelIndex)){
 | 
	
		
			
				|  |  | +            loadingView.loadHidden()
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | + 
 | 
	
		
			
				|  |  | +    public func ttsDebugHandle(_ msg:String, isShow: Bool){
 | 
	
		
			
				|  |  | +        BFLog(message: "TTS 出现错误\(msg)")
 | 
	
		
			
				|  |  | +        let alertController = UIAlertController(title: "哎呀,变声失败了",
 | 
	
		
			
				|  |  | +                       message: "", preferredStyle: .alert)
 | 
	
		
			
				|  |  | +        let cancelAction = UIAlertAction(title: "取消变音", style: .default, handler: {[weak self]
 | 
	
		
			
				|  |  | +            action in
 | 
	
		
			
				|  |  | +             guard let wself = self else { return }
 | 
	
		
			
				|  |  | +            //不使用变音数据 缓存都要清空
 | 
	
		
			
				|  |  | +            wself.tts?.tasksCache.removeAllObjects()
 | 
	
		
			
				|  |  | +            for itemModel in wself.itemModels{
 | 
	
		
			
				|  |  | +                 itemModel.voiceChangeStickers.removeAll()
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +         })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let okAction = UIAlertAction(title: "重试", style: .cancel, handler: {[weak self]
 | 
	
		
			
				|  |  | +           action in
 | 
	
		
			
				|  |  | +            guard let wself = self else { return }
 | 
	
		
			
				|  |  | +            wself.tts?.runNextTask()
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +        okAction.setValue(UIColor.red, forKey:"titleTextColor")
 | 
	
		
			
				|  |  | +        alertController.addAction(okAction)
 | 
	
		
			
				|  |  | +        alertController.addAction(cancelAction)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        self.present(alertController, animated: true, completion: nil)
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  |      /// 查看发音人文件是否已经全都完成,如果没有完成不能进行预览,合成操作
 | 
	
		
			
				|  |  |      /// - Parameter itemIndex: 段落 ID ,不传值是所有段落
 | 
	
		
			
				|  |  | -    /// - Returns: 是否全都完成
 | 
	
		
			
				|  |  | -    func voiceChangeStickerFinish(itemIndex:Int = -100) -> Bool{
 | 
	
		
			
				|  |  | +    /// - Returns: 是否全都完成  true 是全部完成
 | 
	
		
			
				|  |  | +    public func voiceChangeStickerFinish(itemIndex:Int = -100,isShowLoadView:Bool = false) -> Bool{
 | 
	
		
			
				|  |  |          if(mSelectVoiced == nil){
 | 
	
		
			
				|  |  |              return true
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -2825,10 +2896,14 @@ extension BFRecordScreenController: BFTTSManagerDelegte{
 | 
	
		
			
				|  |  |                  FinishCount += itemModel.voiceChangeStickers.count
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        BFLog(message: "总任务数:\(AllCount) 已经完成数:\(FinishCount)")
 | 
	
		
			
				|  |  | +        BFLog(message: "翻译任务总数:\(AllCount) 已经完成数:\(FinishCount)")
 | 
	
		
			
				|  |  |          if(FinishCount < AllCount){
 | 
	
		
			
				|  |  |              isFinish = false
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        if(isShowLoadView && !isFinish){
 | 
	
		
			
				|  |  | +            loadingView.loadShow()
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |       
 | 
	
		
			
				|  |  |          return isFinish
 | 
	
		
			
				|  |  |      }
 |