改了画中画
authorliangzhenying <867174124@qq.com>
Fri, 13 Mar 2026 09:16:10 +0000 (17:16 +0800)
committerliangzhenying <867174124@qq.com>
Fri, 13 Mar 2026 09:16:10 +0000 (17:16 +0800)
20 files changed:
ShenYin/DeepChordsSdk/DCBleManager.swift
ShenYin/DeepChordsSdk/DCBleRecord.swift
ShenYin/ShenYin.xcodeproj/project.pbxproj
ShenYin/ShenYin/Api/HttpClient.swift
ShenYin/ShenYin/Cache/SubTitleCache.swift
ShenYin/ShenYin/Sdk/DcSdk/VC/AiFunctionVC.swift
ShenYin/ShenYin/Sdk/DcSdk/VC/DcSubTitleVC.swift [new file with mode: 0644]
ShenYin/ShenYin/Sdk/DcSdk/tool/CCConfig.swift
ShenYin/ShenYin/Sdk/DcSdk/tool/CCPage.swift
ShenYin/ShenYin/Sdk/DcSdk/tool/DcSubTitle.swift [new file with mode: 0644]
ShenYin/ShenYin/Sdk/JoySdk/VC/AiFunctionVC.swift
ShenYin/ShenYin/Sdk/JoySdk/VC/JoySubTitleVC.swift [moved from ShenYin/ShenYin/UI/Home/SubTitle/SubTitleVC.swift with 62% similarity]
ShenYin/ShenYin/Sdk/JoySdk/tool/CCPage.swift
ShenYin/ShenYin/UI/Home/SubTitle/PiPManager.swift [deleted file]
ShenYin/ShenYin/UI/Home/SubTitle/PipContentVC.swift [new file with mode: 0644]
ShenYin/ShenYin/UI/Home/SubTitle/SubTitleCell.swift [new file with mode: 0644]
ShenYin/ShenYin/UI/Home/SubTitle/SubTitleSetCell.swift
ShenYin/ShenYin/UI/Home/SubTitle/SubTitleSetVC.swift
ShenYin/ShenYin/UI/common/LogVC.swift
ShenYin/ShenYin/UI/common/pop/LanguagePicker/LanguageSelectItem.swift

index 47fdc46..ca49314 100644 (file)
@@ -35,7 +35,7 @@ public class DCBleManager{
         full.append(data)
         full.addCrc()
         if let connectPeripheral = connectPeripheral, let writeCha = writeCha {
-//            DCLogger.debug("发",writeCha.uuid.uuidString,full.joined())
+            DCLogger.debug("发",writeCha.uuid.uuidString,full.joined())
             connectPeripheral.writeValue(full, for: writeCha, type:.withoutResponse)
         }
     }
@@ -94,7 +94,7 @@ extension DCBleManager{
             }
             else if data[1] == 0x0D{
                 let subData = data.subdata(in: 2..<data.count - 3)
-                //DCLogger.debug("传给字节sdk",subData.joined())
+                DCLogger.debug("传给字节sdk",subData.joined())
                 StarburstSdk.shared().receiveBleData(subData)
             }else{
                 receiveNoticeData(data)
index de894a7..b629e91 100644 (file)
@@ -69,13 +69,13 @@ public class DCBleRecord {
         config.ttsFormat = ttsFormat
         
         StarburstSdk.shared().setupDeviceRecord(with: nil, asrConfig: config) { config in
-            DCLogger.debug("录音类型 \(config!.type == 0x00 ? "实时录音" : "通话录音")")
+//            DCLogger.debug("录音类型 \(config!.type == 0x00 ? "实时录音" : "通话录音")")
         } recognizeText: { [weak self]  model in
             guard let self = self else {return}
             guard let model = model else {return}
             
             if let text = model.textResult,!text.isEmpty{
-                DCLogger.debug("asr = \(text)")
+//                DCLogger.debug("asr = \(text)")
                 asrSplitCallback?(DCAsrModel(text: text, index: model.definiteIndex, definite: model.definite))
                 let msg = asrList.firstIndex (where: { (str,idx) in
                     return idx == model.definiteIndex;
@@ -122,8 +122,10 @@ public class DCBleRecord {
         }
     }
     
-    /// 开始
-    public func start(){
+    
+    /// 开始录音
+    /// - Parameter type: /0x00实时录音,0x0c通话录音,0x30字幕翻译
+    public func start(type:Int = 0x00){
             asrList = []
             asrText = ""
             
@@ -134,7 +136,7 @@ public class DCBleRecord {
         
         setupRecord()
         let config = StarburstBleAsrConfig()
-        config.type = 0x00 // 0x00实时录音,0x0c通话录音
+        config.type = type // 0x00实时录音,0x0c通话录音
         StarburstSdk.shared().startDeviceRecord(config)
     }
     
index 23cb084..bd1acd4 100644 (file)
                                Sdk/DcSdk/tool/DcChinese2Enligsh.swift,
                                Sdk/DcSdk/tool/DcSdkManager.swift,
                                Sdk/DcSdk/tool/DcStereo.swift,
+                               Sdk/DcSdk/tool/DcSubTitle.swift,
                                Sdk/DcSdk/tool/DcTcty.swift,
                                Sdk/DcSdk/tool/DcXcly.swift,
                                Sdk/DcSdk/tool/JLAudioUnitKit.xcframework,
                                Sdk/DcSdk/VC/DcChinese2EnglishVC.swift,
                                Sdk/DcSdk/VC/DcDialogTranslateVC.swift,
                                Sdk/DcSdk/VC/DcStereoCallVC.swift,
+                               Sdk/DcSdk/VC/DcSubTitleVC.swift,
                                Sdk/DcSdk/VC/DcTctyVC.swift,
                                Sdk/DcSdk/VC/DcXclyVC.swift,
                                Sdk/DcSdk/VC/HomeDeviceVC.swift,
                                Sdk/JoySdk/VC/JoyChinese2EnglishVC.swift,
                                Sdk/JoySdk/VC/JoyDialogTranlateVC.swift,
                                Sdk/JoySdk/VC/JoyStereoCallVC.swift,
+                               Sdk/JoySdk/VC/JoySubTitleVC.swift,
                                Sdk/JoySdk/VC/JoyTctyVC.swift,
                                Sdk/JoySdk/VC/JoyXclyVC.swift,
                                Sdk/JoySdk/VC/ModeVC.swift,
-                               UI/Home/SubTitle/PiPManager.swift,
-                               UI/Home/SubTitle/SubTitleSetCell.swift,
-                               UI/Home/SubTitle/SubTitleSetVC.swift,
-                               UI/Home/SubTitle/SubTitleVC.swift,
                        );
                        target = 3FD1DFE32F0E00BF00A62733 /* playboy */;
                };
                                CODE_SIGN_ENTITLEMENTS = ShenYin/PLAYBOY.entitlements;
                                CODE_SIGN_IDENTITY = "Apple Development";
                                CODE_SIGN_STYLE = Automatic;
-                               CURRENT_PROJECT_VERSION = 202603091640;
+                               CURRENT_PROJECT_VERSION = 202603121640;
                                DEVELOPMENT_TEAM = JKLJ58J33Q;
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "@executable_path/Frameworks",
                                );
                                LIBRARY_SEARCH_PATHS = "$(inherited)";
-                               MARKETING_VERSION = 0.01;
+                               MARKETING_VERSION = 0.02;
                                PRODUCT_BUNDLE_IDENTIFIER = com.ios.playboy;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                PROVISIONING_PROFILE_SPECIFIER = "";
                                CODE_SIGN_ENTITLEMENTS = ShenYin/PLAYBOY.entitlements;
                                CODE_SIGN_IDENTITY = "Apple Development";
                                CODE_SIGN_STYLE = Automatic;
-                               CURRENT_PROJECT_VERSION = 202603091640;
+                               CURRENT_PROJECT_VERSION = 202603121640;
                                DEVELOPMENT_TEAM = JKLJ58J33Q;
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(inherited)",
                                        "@executable_path/Frameworks",
                                );
                                LIBRARY_SEARCH_PATHS = "$(inherited)";
-                               MARKETING_VERSION = 0.01;
+                               MARKETING_VERSION = 0.02;
                                PRODUCT_BUNDLE_IDENTIFIER = com.ios.playboy;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                PROVISIONING_PROFILE_SPECIFIER = "";
index e976207..d12a3c4 100644 (file)
@@ -449,30 +449,30 @@ class HttpClient{
         }
     }
     
-    static func uploadVoiceFile1<T: HandyJSON>(_ target: CommomApi,completionHandler:@escaping ((T, String) -> Void)) {
-        Logger.debug("request => ",target.url)
-        guard let fileUrl = target.param["fileUrl"] as? URL else {
-            Logger.debug("后",target.param)
-            completionHandler(T(),"")
-            return
-        }
-        if FileManager.default.fileExists(atPath: fileUrl.path){
-            Logger.debug("文件存在")
-        }
-        else{
-            
-            Logger.debug("文件不存在")
-            completionHandler(T(),"")
-            return
-        }
-        Logger.debug(fileUrl)
-        let request = HTTP.POST(target.url, parameters: ["form-data": Upload(fileUrl: fileUrl)]) { response in
-            handleResponse(response, completionHandler: completionHandler)
-        }
-        request?.progress = { progress in
-            Logger.debug("上传进度: \(progress)%")
-        }
-    }
+//    static func uploadVoiceFile1<T: HandyJSON>(_ target: CommomApi,completionHandler:@escaping ((T, String) -> Void)) {
+//        Logger.debug("request => ",target.url)
+//        guard let fileUrl = target.param["fileUrl"] as? URL else {
+//            Logger.debug("后",target.param)
+//            completionHandler(T(),"")
+//            return
+//        }
+//        if FileManager.default.fileExists(atPath: fileUrl.path){
+//            Logger.debug("文件存在")
+//        }
+//        else{
+//            
+//            Logger.debug("文件不存在")
+//            completionHandler(T(),"")
+//            return
+//        }
+//        Logger.debug(fileUrl)
+//        let request = HTTP.POST(target.url, parameters: ["form-data": Upload(fileUrl: fileUrl)]) { response in
+//            handleResponse(response, completionHandler: completionHandler)
+//        }
+//        request?.progress = { progress in
+//            Logger.debug("上传进度: \(progress)%")
+//        }
+//    }
     static func uploadVoiceFile<T: HandyJSON>(_ target: CommomApi,completionHandler:@escaping ((T, String) -> Void)) {
         Logger.debug("request => ",target.url)
         guard let fileUrl = target.param["fileUrl"] as? URL else {
index d2ede5d..9bb21a1 100644 (file)
@@ -24,7 +24,7 @@ enum SubTitleShowType:Int,HandyJSONEnum{
         }
     }
 }
-enum SubTitleSFontType:Int,HandyJSONEnum{
+enum SubTitleFontType:Int,HandyJSONEnum{
     case min = 12
     case stand = 14
     case big = 18
@@ -42,13 +42,30 @@ enum SubTitleSFontType:Int,HandyJSONEnum{
         return .regular(CGFloat(self.rawValue))
     }
 }
+enum SubTitleSoureType:Int,HandyJSONEnum{
+    case mic = 0
+    case phone = 1
 
+    var title:String{
+        switch self {
+        case .mic:
+            return "麦克风".l10n
+        case .phone:
+            return "紧手机内部".l10n
+        }
+    }
+    var font:UIFont{
+        return .regular(CGFloat(self.rawValue))
+    }
+}
 
 class SubTitleCacheModel:NSObject,HandyJSON,NSCoding {
     var lan_form:CCAiLanguage = .english
     var lan_to:CCAiLanguage = .chinse
-    var fontType:SubTitleSFontType = .stand
+    var soure:CCAiLanguage = .chinse
+    var fontType:SubTitleFontType = .stand
     var showType:SubTitleShowType = .all
+    var sourceType:SubTitleSoureType = .mic
     required public override init() { }
     
     func encode(with aCoder: NSCoder) {
@@ -56,6 +73,7 @@ class SubTitleCacheModel:NSObject,HandyJSON,NSCoding {
         aCoder.encode(lan_to.rawValue, forKey: "lan_to")
         aCoder.encode(fontType.rawValue, forKey: "fontType")
         aCoder.encode(showType.rawValue, forKey: "showType")
+        aCoder.encode(sourceType.rawValue, forKey: "sourceType")
     }
     
     required init?(coder aDecoder: NSCoder) {
@@ -63,11 +81,13 @@ class SubTitleCacheModel:NSObject,HandyJSON,NSCoding {
         let lanToString = aDecoder.decodeObject(forKey: "lan_to") as? String ?? "chinse"
         let fontTypeValue = aDecoder.decodeInteger(forKey: "fontType")
         let showTypeValue = aDecoder.decodeInteger(forKey: "showType")
+        let sourceTypeValue = aDecoder.decodeInteger(forKey: "sourceType")
         
         lan_form = CCAiLanguage(rawValue: lanFormString) ?? .english
         lan_to = CCAiLanguage(rawValue: lanToString) ?? .chinse
-        fontType = SubTitleSFontType(rawValue: fontTypeValue) ?? .stand
+        fontType = SubTitleFontType(rawValue: fontTypeValue) ?? .stand
         showType = SubTitleShowType(rawValue: showTypeValue) ?? .all
+        sourceType = SubTitleSoureType(rawValue: sourceTypeValue) ?? .mic
     }
 }
 
index 5c1787e..6ba49cb 100644 (file)
@@ -27,6 +27,8 @@ class AiFunctionVC:BaseVC{
     override func setupViews() {
         navBar.title = device.productName
         navBar.backgroundColor = .color(.bgColor)
+//        navBar.rightView.isHidden = false
+//        navBar.rightView.setTitle("字幕翻译", for: .normal)
         view.backgroundColor = .color(.bgColor)
         //        navBar.rightView.setImage(UIImage(named: "add_icon"), for: .normal)
         view.addSubview(bgView)
@@ -57,6 +59,9 @@ class AiFunctionVC:BaseVC{
             make.width.equalTo(kScreenWid)
         }
     }
+    override func navRightViewTapped() {
+        CCPage.gotoSubTitle()
+    }
     func updateUI(){
         if CCBleManager.shared.isConected(mac: device.mac){
             headerView.enable = true
@@ -81,6 +86,7 @@ class AiFunctionVC:BaseVC{
                 CCPage.gotoFieldRecord()
             case .callRecord:
                 CCPage.gotoCallRecord()
+//                CCPage.gotoSubTitle()
             case .chinese2English:
                 CCPage.gotoChinese2Enlgish()
             case .recordTranslate:
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/VC/DcSubTitleVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcSubTitleVC.swift
new file mode 100644 (file)
index 0000000..e7f2a20
--- /dev/null
@@ -0,0 +1,184 @@
+//
+//  Untitled.swift
+//  ShenYin
+//
+//  Created by liangshi on 2026/3/5.
+//
+
+
+import UIKit
+import AVKit
+
+@available(iOS 15.0, *)
+class DcSubTitleVC: BaseVC {
+    let languageItem = LanguageSelectItem()
+    let toolBar = RecordBar()
+    let tableView = UITableView(frame: CGRectZero, style: .plain)
+    
+    
+    let pipManager = PipManager()
+    let sdk = DcSubTitle()
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+    }
+
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+        let cache = SubTitleCache.shared.get()
+        languageItem.leftLabel.language = cache.lan_form
+        languageItem.rightLabel.language = cache.lan_to
+    }
+    override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+        
+    }
+    override func viewDidDisappear(_ animated: Bool) {
+        super.viewDidDisappear(animated)
+        sdk.stopEarRecord()
+    }
+    override func setupViews() {
+        view.backgroundColor = .color(.bgColor)
+        navBar.do { v in
+            v.addSubview(languageItem)
+            v.rightView.isHidden = false
+//            v.rightView.setImage(UIImage(named: "set_right"), for: .normal)
+            navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
+        }
+        
+        view.addSubviews([toolBar,tableView])
+        
+        toolBar.do { v in
+            v.delegate = self
+            v.leftItem.isHidden = true
+            v.rightItem.isHidden = true
+        }
+        languageItem.do { v in
+            v.languageChange = { (from,to) in
+                let cache = SubTitleCache.shared.get()
+                cache.lan_form = from
+                cache.lan_to = to
+                SubTitleCache.shared.save(cache)
+            }
+        }
+        tableView.do { v in
+            v.backgroundColor = .color(.bgColor)
+            v.delegate = self
+            v.dataSource = self
+            v.estimatedRowHeight = 60
+            v.separatorStyle = .none
+            v.register(SubTitleCell.self, forCellReuseIdentifier: SubTitleCell.reuseID)
+        }
+//        let soureView = UIView()
+//        soureView.backgroundColor = .red
+//        view.addSubviews([soureView])
+//        soureView.snp.makeConstraints { make in
+//            make.size.equalTo(10)
+//            make.center.equalToSuperview()
+//        }
+        pipManager.setupPictureInPicture(soureceView: self.view)
+    }
+    override func setupLayout() {
+        languageItem.snp.makeConstraints { make in
+            make.left.right.equalToSuperview().inset(80)
+            make.centerX.equalToSuperview()
+            make.bottom.equalToSuperview().offset(5)
+        }
+        toolBar.snp.makeConstraints { make in
+            make.width.centerX.equalToSuperview()
+            make.height.equalTo(120)
+            make.bottom.equalToSuperview()
+        }
+        tableView.snp.makeConstraints { make in
+            make.top.equalToSuperview().inset(kNavBtm)
+            make.left.equalToSuperview()
+            make.width.equalTo(kScreenWid)
+            make.bottom.equalTo(toolBar.snp.top)
+        }
+    }
+    
+    override func setupData() {
+        setupSdk()
+        NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(appDidEnterBackground(_:)),
+            name: UIApplication.willResignActiveNotification,
+            object: nil
+        )
+        
+        NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(appWillEnterForeground(_:)),
+            name: UIApplication.didBecomeActiveNotification,
+            object: nil
+        )
+        
+    }
+    override func navRightViewTapped() {
+        if !languageItem.enable {
+            return
+        }
+        let vc = SubTitleSetVC()
+        App.shared.goToPage(vc)
+    }
+
+    @objc private func appDidEnterBackground(_ notification: Notification) {
+        if sdk.recording {
+            pipManager.startPictureInPicture()
+        }
+    }
+    
+    @objc private func appWillEnterForeground(_ notification: Notification) {
+        pipManager.stopPictureInPicture()
+    }
+    func setupSdk(){
+        sdk.recordNeedReloadData = {[weak self] in
+            guard let self = self else{return}
+            if let model = sdk.dataList.last{
+                pipManager.contentVC.updateRaw(model.send)
+                pipManager.contentVC.updateTrans(model.response)
+                tableView.reloadData()
+                if sdk.dataList.count > 0 {
+                    tableView.scrollToRow(at: IndexPath(row: sdk.dataList.count - 1, section: 0), at: .bottom, animated: true)
+                }
+            }
+        }
+    }
+}
+
+
+@available(iOS 15.0, *)
+extension DcSubTitleVC:RecordBarDelegate{
+    func recordBarLanguageChange(_ bar: RecordBar) {
+        
+        sdk.stopEarRecord()
+        sdk.startEarRecord(from: languageItem.leftLabel.language, to: languageItem.rightLabel.language)
+    }
+    func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
+        if state == .start {
+            sdk.startEarRecord(from: languageItem.leftLabel.language, to: languageItem.rightLabel.language)
+            languageItem.enable = false
+            navBar.rightView.alpha = 0.5
+        }
+        else if state == .stop{
+            sdk.stopEarRecord()
+            languageItem.enable = true
+            navBar.rightView.alpha = 1
+        }
+    }
+}
+@available(iOS 15.0, *)
+extension DcSubTitleVC:UITableViewDelegate,UITableViewDataSource {
+    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return sdk.dataList.count
+    }
+    
+    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        let cell = SubTitleCell.cell(withTableView: tableView, indexPath: indexPath)
+        cell.data = sdk.dataList[indexPath.row]
+        return cell
+    }
+    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        
+    }
+}
index 7feb772..93e2c4d 100644 (file)
@@ -6,36 +6,36 @@
 //
 
 
-//class CCConfig{
-//    static var appLanguage = AppSupportLanguage.english
-//    
-//    static let wxAppID = "wxeb3291e720293abc"
-//    static let wxUniversalLink = "https://www.playboykq.com/app/"
-//    static let appStoreLink = "https://itunes.apple.com/cn/app/6757697090?mt=8"
-//    /// 版本检测
-//    static let appStoreVersionURL = "https://itunes.apple.com/cn/lookup?id=6757697090"
-//    
-//    /// 服务器地址
-//    static let baseURL = "https://app-api.deepchords.com"
-//    
-//    /// 用户隐私协议地址
-//    static let yonghuBaseURL = "https://pub-cdn.playboykq.com"
-//    
-//}
-
 class CCConfig{
     static var appLanguage = AppSupportLanguage.english
-
+    
     static let wxAppID = "wxeb3291e720293abc"
     static let wxUniversalLink = "https://www.playboykq.com/app/"
     static let appStoreLink = "https://itunes.apple.com/cn/app/6757697090?mt=8"
     /// 版本检测
     static let appStoreVersionURL = "https://itunes.apple.com/cn/lookup?id=6757697090"
-
+    
     /// 服务器地址
-    static let baseURL = "https://app-api.playboykq.com"
-
+    static let baseURL = "https://app-api.deepchords.com"
+    
     /// 用户隐私协议地址
     static let yonghuBaseURL = "https://pub-cdn.playboykq.com"
-
+    
 }
+
+//class CCConfig{
+//    static var appLanguage = AppSupportLanguage.english
+//
+//    static let wxAppID = "wxeb3291e720293abc"
+//    static let wxUniversalLink = "https://www.playboykq.com/app/"
+//    static let appStoreLink = "https://itunes.apple.com/cn/app/6757697090?mt=8"
+//    /// 版本检测
+//    static let appStoreVersionURL = "https://itunes.apple.com/cn/lookup?id=6757697090"
+//
+//    /// 服务器地址
+//    static let baseURL = "https://app-api.playboykq.com"
+//
+//    /// 用户隐私协议地址
+//    static let yonghuBaseURL = "https://pub-cdn.playboykq.com"
+//
+//}
index 011e325..1183b6f 100644 (file)
@@ -70,4 +70,16 @@ class CCPage{
             App.shared.goToPage(DcDialogTranslateVC())
         }
     }
+    static func gotoSubTitle(){
+        if CCDevice.isJoy {
+            //            App.shared.goToPage(JoyDialogTranslateVC())
+        }
+        else{
+            if #available(iOS 15.0, *) {
+                App.shared.goToPage(DcSubTitleVC())
+            } else {
+                // Fallback on earlier versions
+            }
+        }
+    }
 }
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/tool/DcSubTitle.swift b/ShenYin/ShenYin/Sdk/DcSdk/tool/DcSubTitle.swift
new file mode 100644 (file)
index 0000000..388e0f4
--- /dev/null
@@ -0,0 +1,97 @@
+//
+//  DcSubTitle.swift
+//  ShenYin
+//
+//  Created by liangshi on 2026/3/13.
+//
+
+
+import UIKit
+import DeepChordsSdk
+
+class DcSubTitle:NSObject{
+    var dataList:[SubTitleCellModel] = []
+    var recordNeedReloadData:(()->Void)?
+    var recording = false
+    override init() {
+        super.init()
+        setupSdk()
+    }
+    func setupSdk(){
+        DCBleRecord.shared.asrSplitCallback = { [weak self] model in
+            guard let self = self else{return}
+//            Logger.debug("asr: \(model.text),index: \(model.index)")
+            let index = dataList.firstIndex (where: { item in
+                return item.index == model.index;
+            })
+            if (index == nil) {
+                let item0 = SubTitleCellModel(send: model.text,index: model.index)
+                dataList.append(item0)
+            } else {
+                dataList[index!].send = model.text
+            }
+            recordNeedReloadData?()
+        }
+        DCBleRecord.shared.translateSplitCallback = { [weak self] model in
+            guard let self = self else{return}
+//            Logger.debug("tranlate: \(model.text),index: \(model.index)")
+            let index = dataList.firstIndex (where: { item in
+                return item.index == model.index;
+            })
+            if (index == nil) {
+                let item0 = SubTitleCellModel(response: model.text,index: model.index)
+                dataList.append(item0)
+            } else {
+                dataList[index!].response = model.text
+            }
+            recordNeedReloadData?()
+        }
+//        DCBleRecord.shared.translateDataCallback = { data in
+//            PcmSound.sharedInstance().feed(data)
+//        }
+//        DCBleRecord.shared.codeCallback = { [weak self] code in
+//            guard let self = self else{return}
+//            if code == 20002 || code == 20003{
+//                if let model = dataList.last,model.send.isEmpty{
+//                    dataList.removeLast()
+//                    refreshData()
+//                }
+//            }
+//        }
+        DCBleRecord.shared.filePathCallBack = { [weak self] path in
+            guard let self = self else{return}
+            //            self.recordBtn.isSelected = false
+            recording = false
+        }
+    }
+
+    func startEarRecord(from:CCAiLanguage,to:CCAiLanguage) {
+        recording = true
+        dataList.removeAll()
+        recordNeedReloadData?()
+        
+        DCBleRecord.shared.fromLanguage = from.value
+        DCBleRecord.shared.toLanguage = to.value
+        DCBleRecord.shared.isTranslate = true
+        DCBleRecord.shared.isTTs = false
+        
+        if SubTitleCache.shared.get().sourceType == .mic{
+            DCBleRecord.shared.start()
+        }
+        else{
+            DCBleRecord.shared.start(type: 0x30)
+        }
+        
+        do {
+            try AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: [.defaultToSpeaker])
+            try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
+        } catch {
+            print(error)
+        }
+    }
+    
+    func stopEarRecord() {
+        DCBleRecord.shared.stop()
+        recording = false
+    }
+}
index cc8e189..0329b8b 100644 (file)
@@ -84,13 +84,7 @@ class AiFunctionVC:BaseVC{
         }
     }
     @objc func subTitleAction(){
-        if #available(iOS 15.0, *) {
-//            if CCBleManager.shared.isConected(mac: device.mac){
-                App.shared.goToPage(SubTitleVC())
-//            }
-        } else {
-            // Fallback on earlier versions
-        }
+        CCPage.gotoSubTitle()
     }
 }
 
@@ -1,31 +1,29 @@
+////
+////  Untitled.swift
+////  ShenYin
+////
+////  Created by liangshi on 2026/3/5.
+////
 //
-//  Untitled.swift
-//  ShenYin
 //
-//  Created by liangshi on 2026/3/5.
-//
-
-
 import UIKit
 import AVKit
 import JoyGemAI
-import SVProgressHUD
 @available(iOS 15.0, *)
-class SubTitleVC: BaseVC {
+class JoySubTitleVC: BaseVC {
     let languageItem = LanguageSelectItem()
     let toolBar = RecordBar()
-    var startButton : UIButton!
-    
-    var stopButton : UIButton!
-    let pipManager = PiPManager()
-
-    
-    //画中画载体
-    internal var sourceView : UIView = UIView()
+    let pipManager = PipManager()
+    var messageList : [(String,UInt)] = []
+    var translateList : [(String,UInt)] = []
     
     override func viewDidLoad() {
         super.viewDidLoad()
     }
+    override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+        
+    }
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         let cache = SubTitleCache.shared.get()
@@ -34,7 +32,6 @@ class SubTitleVC: BaseVC {
     }
     override func setupViews() {
         view.backgroundColor = UIColor.white
-        sourceView.backgroundColor = .clear
         navBar.do { v in
             v.backgroundColor = .white
             v.addSubview(languageItem)
@@ -42,7 +39,7 @@ class SubTitleVC: BaseVC {
             v.rightView.setImage(UIImage(named: "set_right"), for: .normal)
         }
         
-        view.addSubviews([sourceView,toolBar])
+        view.addSubviews([toolBar])
         
         toolBar.do { v in
             v.delegate = self
@@ -50,14 +47,14 @@ class SubTitleVC: BaseVC {
             v.rightItem.isHidden = true
         }
         languageItem.do { v in
-            v.languageChange = {[weak self] (from,to) in
-                guard let self = self else { return  }
+            v.languageChange = { (from,to) in
                 let cache = SubTitleCache.shared.get()
                 cache.lan_form = from
                 cache.lan_to = to
                 SubTitleCache.shared.save(cache)
             }
         }
+        pipManager.setupPictureInPicture(soureceView: self.navigationController!.view)
     }
     override func setupLayout() {
         languageItem.snp.makeConstraints { make in
@@ -70,12 +67,6 @@ class SubTitleVC: BaseVC {
             make.height.equalTo(120)
             make.bottom.equalToSuperview()
         }
-        sourceView.snp.makeConstraints { make in
-            make.top.equalTo(kNavBtm + 20)
-            make.height.equalTo(200)
-            make.centerX.equalToSuperview()
-            make.width.equalTo(200)
-        }
     }
     
     override func setupData() {
@@ -85,69 +76,68 @@ class SubTitleVC: BaseVC {
         } catch {
             print(error)
         }
-        
         JoyGemSubtitleManager.shared().delegate = self
-        // 初始化画中画管理器
-        pipManager.setupPictureInPicture(sourceView: self.sourceView)
         
-        // 监听画中画状态变化
         NotificationCenter.default.addObserver(
             self,
-            selector: #selector(pipStateChanged(_:)),
-            name: NSNotification.Name("PiPStateChanged"),
+            selector: #selector(appDidEnterBackground(_:)),
+            name: UIApplication.willResignActiveNotification,
             object: nil
         )
+        
+        NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(appWillEnterForeground(_:)),
+            name: UIApplication.didBecomeActiveNotification,
+            object: nil
+        )
+        
     }
     override func navRightViewTapped() {
         let vc = SubTitleSetVC()
         App.shared.goToPage(vc)
     }
-
-    @objc private func pipStateChanged(_ notification: Notification) {
-        if let userInfo = notification.userInfo,
-           let isActive = userInfo["isActive"] as? Bool {
-            print("画中画状态: \(isActive ? "活跃" : "非活跃")")
-        }
+    
+    
+    @objc private func appDidEnterBackground(_ notification: Notification) {
+        pipManager.startPictureInPicture()
+    }
+    
+    @objc private func appWillEnterForeground(_ notification: Notification) {
+        pipManager.stopPictureInPicture()
     }
 }
 
+
+
 @available(iOS 15.0, *)
-extension SubTitleVC:RecordBarDelegate{
+extension JoySubTitleVC:RecordBarDelegate{
     func recordBarLanguageChange(_ bar: RecordBar) {
-
+        
     }
     func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
         if state == .start {
             JoyGemSubtitleManager.shared().originalLanguage = languageItem.leftLabel.language.value
             JoyGemSubtitleManager.shared().targetLanguage = languageItem.rightLabel.language.value
             JoyGemSubtitleManager.shared().start()
-            
-            guard AVPictureInPictureController.isPictureInPictureSupported() else {
-                print("设备不支持画中画")
-                return
-            }
-            
-            pipManager.startPictureInPicture()
         }
         else if state == .stop{
             JoyGemSubtitleManager.shared().stop()
-            
-            pipManager.stopPictureInPicture()
         }
     }
 }
 
 @available(iOS 15.0, *)
-extension SubTitleVC : JoyGemSubtitleManagerDelegate {
+extension JoySubTitleVC : JoyGemSubtitleManagerDelegate {
     
     func subtitleManager(_ manager: JoyGemSubtitleManager, didUpdateRaw model: JoyGemAsrModel) {
         debugPrint("text: \(model.text),index: \(model.index)")
-        pipManager.updateRaw(model.text,model.index)
+        updateRaw(model.text,model.index)
     }
     
     func subtitleManager(_ manager: JoyGemSubtitleManager, didUpdateTranslate model: JoyGemAsrModel) {
         debugPrint("translate text: \(model.text),index: \(model.index)")
-        pipManager.updateTrans(model.text,model.index)
+        updateTrans(model.text,model.index)
     }
     
     func subtitleManagerStopped(_ manager: JoyGemSubtitleManager) {
@@ -170,4 +160,35 @@ extension SubTitleVC : JoyGemSubtitleManagerDelegate {
         
     }
     
+    func updateRaw(_ text: String,_ index: UInt) {
+        let msg = messageList.firstIndex (where: { (str,idx) in
+            return idx == index;
+        })
+        if (msg == nil) {
+            messageList.append((text,index))
+        } else {
+            messageList[msg!] = (text,index)
+        }
+        
+        let res = messageList.compactMap({ (str,idx) in
+            return str
+        }).joined(separator: "\n")
+        pipManager.contentVC.updateRaw(res)
+    }
+    
+    func updateTrans(_ text: String,_ index: UInt) {
+        let msg = translateList.firstIndex (where: { (str,idx) in
+            return idx == index;
+        })
+        if (msg == nil) {
+            translateList.append((text,index))
+        } else {
+            translateList[msg!] = (text,index)
+        }
+        
+        let res = translateList.compactMap({ (str,idx) in
+            return str
+        }).joined(separator: "\n")
+        pipManager.contentVC.updateTrans(res)
+    }
 }
index 28efa96..9da3a89 100644 (file)
@@ -65,4 +65,16 @@ class CCPage{
 //            App.shared.goToPage(DcDialogTranslateVC())
         }
     }
+    static func gotoSubTitle(){
+        if CCDevice.isJoy {
+            if #available(iOS 15.0, *) {
+                App.shared.goToPage(JoySubTitleVC())
+            } else {
+                // Fallback on earlier versions
+            }
+        }
+        else{
+
+        }
+    }
 }
diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/PiPManager.swift b/ShenYin/ShenYin/UI/Home/SubTitle/PiPManager.swift
deleted file mode 100644 (file)
index 5f7b0c5..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-//
-//  Untitled.swift
-//  ShenYin
-//
-//  Created by liangshi on 2026/3/5.
-//
-
-import AVKit
-import UIKit
-
-@available(iOS 15.0, *)
-class PiPManager: NSObject, ObservableObject {
-    
-    var pipController: AVPictureInPictureController?
-    
-    var contentVC: DesktopLyricsContentVC!
-    
-    var messageList : [(String,UInt)] = []
-    
-    var translateList : [(String,UInt)] = []
-    
-    func setupPictureInPicture(sourceView : UIView) {
-
-        contentVC = DesktopLyricsContentVC()
-        contentVC.preferredContentSize = CGSize(width: UIScreen.main.bounds.width, height: 240) // 画中画窗口大小
-        
-        // 设置播放器
-        pipController = AVPictureInPictureController(contentSource: AVPictureInPictureController.ContentSource(
-            activeVideoCallSourceView: sourceView,
-            contentViewController: contentVC
-        ))
-        pipController?.delegate = self
-    }
-
-    
-    func startPictureInPicture() {
-        // 1. 检查场景状态
-        if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
-            print("场景激活状态: \(scene.activationState.rawValue)")
-            print("场景状态描述: \(describeActivationState(scene.activationState))")
-        } else {
-            print("❌ 无法获取场景")
-        }
-        
-        pipController?.startPictureInPicture()
-    }
-    
-    private func describeActivationState(_ state: UIScene.ActivationState) -> String {
-        switch state {
-        case .unattached: return "unattached - 场景未连接到会话"
-        case .foregroundInactive: return "foregroundInactive - 前景但不活跃"
-        case .foregroundActive: return "foregroundActive - 前景且活跃 ✅"
-        case .background: return "background - 后台"
-        @unknown default: return "unknown"
-        }
-    }
-    
-    func stopPictureInPicture() {
-        pipController?.stopPictureInPicture()
-    }
-    
-    func updateRaw(_ text: String,_ index: UInt) {
-        let msg = messageList.firstIndex (where: { (str,idx) in
-            return idx == index;
-        })
-        if (msg == nil) {
-            messageList.append((text,index))
-        } else {
-            messageList[msg!] = (text,index)
-        }
-        
-        let res = messageList.compactMap({ (str,idx) in
-            return str
-        }).joined(separator: "\n")
-        contentVC?.updateRaw(res)
-    }
-    
-    func updateTrans(_ text: String,_ index: UInt) {
-        let msg = translateList.firstIndex (where: { (str,idx) in
-            return idx == index;
-        })
-        if (msg == nil) {
-            translateList.append((text,index))
-        } else {
-            translateList[msg!] = (text,index)
-        }
-        
-        let res = translateList.compactMap({ (str,idx) in
-            return str
-        }).joined(separator: "\n")
-        contentVC?.updateTrans(res)
-    }
-}
-
-@available(iOS 15.0, *)
-extension PiPManager: AVPictureInPictureControllerDelegate {
-    func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
-        print("画中画即将开始")
-    }
-    
-    func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
-        print("画中画已开始")
-        // 开始播放透明视频
-        //player?.play()
-    }
-    
-    func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
-        print("画中画启动失败: \(error)")
-    }
-    
-    
-    func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
-        print("画中画已结束")
-//        messageList.removeAll()
-//        translateList.removeAll()
-    }
-}
-// 画中画内容视图控制器
-@available(iOS 15.0, *)
-class DesktopLyricsContentVC : AVPictureInPictureVideoCallViewController {
-    var textView = UITextView()
-    var translateTextView = UITextView()
-    
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        setupViews()
-        setupLayout()
-    }
-    func setupViews(){
-        view.addSubviews([textView,translateTextView])
-        view.backgroundColor = .clear
-        
-        textView.do { v in
-            v.textColor = UIColor.blue
-            v.text = "原文".l10n
-            v.font = UIFont.boldSystemFont(ofSize: 14)
-            v.backgroundColor = .clear
-        }
-        
-        translateTextView.do { v in
-            v.textColor = UIColor.orange
-            v.text = "译文".l10n
-            v.font = UIFont.boldSystemFont(ofSize: 14)
-            v.backgroundColor = .clear
-        }
-    }
-    func setupLayout(){
-        let cache = SubTitleCache.shared.get()
-        
-        if cache.showType == .all {
-            textView.snp.makeConstraints { make in
-                make.top.equalToSuperview().inset(40)
-                make.leading.trailing.equalToSuperview()
-                make.bottom.equalTo(view.snp.centerY)
-            }
-            translateTextView.snp.makeConstraints { make in
-                make.leading.trailing.equalToSuperview()
-                make.top.equalTo(textView.snp.bottom)
-                make.height.equalTo(textView.snp.height)
-            }
-            textView.isHidden = false
-            translateTextView.isHidden = false
-        }
-        else if cache.showType == .from {
-            textView.snp.makeConstraints { make in
-                make.top.bottom.equalToSuperview().inset(40)
-                make.leading.trailing.equalToSuperview()
-            }
-            textView.isHidden = false
-            translateTextView.isHidden = true
-        } else {
-            translateTextView.snp.makeConstraints { make in
-                make.top.bottom.equalToSuperview().inset(40)
-                make.leading.trailing.equalToSuperview()
-            }
-            textView.isHidden = true
-            translateTextView.isHidden = false
-        }
-        
-    }
-    
-    func updateRaw(_ text: String) {
-        textView.text = text
-        textView.scrollRangeToVisible(NSRange(location: textView.text.count, length: 0))
-    }
-    
-    func updateTrans(_ text : String) {
-        translateTextView.text = text
-        translateTextView.scrollRangeToVisible(NSRange(location: translateTextView.text.count, length: 0))
-    }
-}
diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/PipContentVC.swift b/ShenYin/ShenYin/UI/Home/SubTitle/PipContentVC.swift
new file mode 100644 (file)
index 0000000..62363ef
--- /dev/null
@@ -0,0 +1,162 @@
+//
+//  Untitled.swift
+//  ShenYin
+//
+//  Created by liangshi on 2026/3/5.
+//
+
+import AVKit
+import UIKit
+
+@available(iOS 15.0, *)
+class PipManager:NSObject,AVPictureInPictureControllerDelegate{
+    var pipController: AVPictureInPictureController?
+    var contentVC: PipContentVC!
+    
+    
+    func setupPictureInPicture(soureceView:UIView) {
+        guard AVPictureInPictureController.isPictureInPictureSupported() else {
+            print("❌ 设备不支持画中画")
+            return
+        }
+        
+        contentVC = PipContentVC()
+        contentVC.preferredContentSize = CGSizeMake(kScreenWid, 200)
+        let contentSource = AVPictureInPictureController.ContentSource(
+            activeVideoCallSourceView:soureceView ,
+            contentViewController: contentVC
+        )
+        
+        pipController = AVPictureInPictureController(contentSource: contentSource)
+        pipController?.delegate = self
+        pipController?.canStartPictureInPictureAutomaticallyFromInline = false
+    }
+    
+    @objc func startPictureInPicture(){
+        guard let pipController = pipController else {
+            print("❌ pipController 未初始化,无法启动画中画")
+            return
+        }
+        
+        if pipController.isPictureInPicturePossible {
+            print("✅ 画中画可以启动,准备开始...")
+            pipController.startPictureInPicture()
+            contentVC?.reset()
+        } else {
+            print("❌ 画中画当前无法启动")
+        }
+    }
+    @objc func stopPictureInPicture() {
+        guard let pipController = pipController else {
+            print("❌ pipController 未初始化,无法停止画中画")
+            return
+        }
+        
+        if pipController.isPictureInPictureActive {
+            print("✅ 画中画正在显示,准备停止...")
+            pipController.stopPictureInPicture()
+            print("✅ 画中画已停止")
+        } else {
+            print("⚠️ 画中画当前未显示")
+        }
+    }
+
+    func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
+        print("画中画即将开始")
+    }
+    
+    func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
+        print("✅ 画中画已开始")
+    }
+    
+    func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
+        print("❌ 画中画启动失败: \(error)")
+    }
+    
+    func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
+        print("⏹️ 画中画即将结束")
+    }
+    
+    func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
+        print("🛑 画中画已结束")
+    }
+    
+}
+
+
+
+
+
+
+
+// 画中画内容视图控制器
+@available(iOS 15.0, *)
+class PipContentVC : AVPictureInPictureVideoCallViewController {
+    var textView = UITextView()
+    var translateTextView = UITextView()
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        view.addSubviews([textView,translateTextView])
+        view.backgroundColor = .rgb(0x717171)
+        reset()
+    }
+    
+    func updateRaw(_ text: String) {
+        textView.text = text
+        textView.scrollRangeToVisible(NSRange(location: textView.text.count, length: 0))
+    }
+    
+    func updateTrans(_ text : String) {
+        translateTextView.text = text
+        translateTextView.scrollRangeToVisible(NSRange(location: translateTextView.text.count, length: 0))
+    }
+    func reset(){
+        if (textView.superview == nil) {
+            return
+        }
+        let cache = SubTitleCache.shared.get()
+        
+        textView.do { v in
+            v.textColor = .rgb(0xD8D8D8)
+            v.font = cache.fontType.font
+            v.backgroundColor = .clear
+        }
+        
+        translateTextView.do { v in
+            v.textColor = .white
+            v.font = cache.fontType.font
+            v.backgroundColor = .clear
+        }
+        
+        if cache.showType == .all {
+            textView.snp.remakeConstraints { make in
+                make.top.equalToSuperview().inset(50)
+                make.leading.trailing.equalToSuperview().inset(16)
+                make.bottom.equalTo(view.snp.centerY)
+            }
+            translateTextView.snp.remakeConstraints { make in
+                make.leading.trailing.equalToSuperview().inset(16)
+                make.top.equalTo(textView.snp.bottom).offset(2)
+                make.bottom.equalToSuperview().inset(16)
+            }
+            textView.isHidden = false
+            translateTextView.isHidden = false
+        }
+        else if cache.showType == .from {
+            textView.snp.remakeConstraints { make in
+                make.top.bottom.equalToSuperview().inset(50)
+                make.leading.trailing.equalToSuperview().inset(16)
+            }
+            textView.isHidden = false
+            translateTextView.isHidden = true
+        } else {
+            translateTextView.snp.remakeConstraints { make in
+                make.top.bottom.equalToSuperview().inset(50)
+                make.leading.trailing.equalToSuperview().inset(16)
+            }
+            textView.isHidden = true
+            translateTextView.isHidden = false
+        }
+    }
+}
diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleCell.swift b/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleCell.swift
new file mode 100644 (file)
index 0000000..cfde55a
--- /dev/null
@@ -0,0 +1,143 @@
+//
+//  SubTitleCell.swift
+//  ShenYin
+//
+//  Created by liangshi on 2026/3/13.
+//
+
+class SubTitleCellModel{
+    var send = ""
+    var response = ""
+    var index : Int = 0
+    
+    init(send: String = "", response: String = "",index:Int = 0) {
+        self.send = send
+        self.response = response
+        self.index = index
+    }
+}
+
+
+
+
+class SubTitleCell:BaseTableViewCell{
+    let bgView = UIView()
+    private let line = BrokenLineView()
+    let originalLabel = UILabel()
+    let translationLabel = UILabel()
+    let playIcon = UIImageView()
+    
+    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
+        super.init(style: style, reuseIdentifier: reuseIdentifier)
+        
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    override func setupViews() {
+        contentView.backgroundColor = .clear
+        backgroundView?.backgroundColor = .clear
+        backgroundColor = .clear
+        
+        bgView.do { v in
+            v.yc.setCornerRadius(12)
+            v.backgroundColor = .color(.cellBg)
+        }
+        originalLabel.do { v in
+            v.font = .regular(14)
+            v.textColor = .color(.secondary)
+            v.numberOfLines = 0
+            v.textAlignment = .left
+        }
+        translationLabel.do { v in
+            v.font = .regular(14)
+            v.textColor = .color(.first)
+            v.numberOfLines = 0
+            v.textAlignment = .left
+        }
+        line.do { v in
+        }
+        playIcon.do { v in
+            v.image = UIImage(named: "play_animate_3")
+            v.animationImages = [UIImage(named: "play_animate_1")!,UIImage(named: "play_animate_2")!,UIImage(named: "play_animate_3")!]
+            v.animationDuration = 0.6
+            v.animationRepeatCount = 0
+            v.yc.addTap(target: self, action: #selector(playAction))
+            v.isHidden = true
+        }
+        contentView.addSubview(bgView)
+        bgView.addSubviews([originalLabel,translationLabel,line,playIcon])
+    }
+    
+    override func setupLayout() {
+        //        bgView.snp.makeConstraints { make in
+        //            make.top.bottom.equalToSuperview().inset(10)
+        //            make.width.lessThanOrEqualTo(kScreenWid - 58)
+        //            make.left.equalToSuperview().inset(18)
+        //        }
+        //
+        originalLabel.snp.makeConstraints { make in
+            make.top.equalToSuperview().inset(14)
+            make.height.greaterThanOrEqualTo(15)
+            make.left.equalToSuperview().inset(12)
+            make.right.equalToSuperview().inset(50)
+            make.width.lessThanOrEqualTo(kScreenWid - 120)
+        }
+        line.snp.makeConstraints { make in
+            make.left.right.equalToSuperview().inset(12)
+            make.height.equalTo(1)
+            make.top.equalTo(originalLabel.snp.bottom).offset(15)
+        }
+        
+        translationLabel.snp.makeConstraints { make in
+            make.top.equalTo(line.snp.bottom).offset(15)
+            make.left.equalToSuperview().inset(12)
+            make.right.equalToSuperview().inset(12)
+            make.height.greaterThanOrEqualTo(15)
+            make.bottom.equalToSuperview().inset(14)
+        }
+        playIcon.snp.makeConstraints { make in
+            make.right.equalToSuperview().inset(12)
+            make.size.equalTo(24)
+            make.top.equalToSuperview().inset(12)
+        }
+    }
+    
+    var data:SubTitleCellModel!{
+        didSet{
+            originalLabel.text = data.send
+            translationLabel.text = data.response
+            
+//            if data.isPhone {
+//                bgView.snp.remakeConstraints { make in
+//                    make.top.bottom.equalToSuperview().inset(10)
+//                    //                    make.width.equalTo(kScreenWid - 78)
+//                    make.right.equalToSuperview().inset(18)
+//                }
+//                bgView.backgroundColor = .color(.theme)
+//                originalLabel.textColor = UIColor.white.withAlphaComponent(0.8)
+//                translationLabel.textColor = .white
+//            }
+//            else{
+                bgView.snp.remakeConstraints { make in
+                    make.top.bottom.equalToSuperview().inset(10)
+                    make.left.equalToSuperview().inset(18)
+                }
+                bgView.backgroundColor = .color(.cellBg)
+                originalLabel.textColor = .color(.secondary)
+                translationLabel.textColor = .color(.first)
+//            }
+            line.setNeedsLayout()
+        }
+    }
+    @objc func playAction(){
+        if playIcon.isAnimating {
+            playIcon.stopAnimating()
+        }
+        else{
+            playIcon.startAnimating()
+        }
+    }
+}
index 7a52794..224097e 100644 (file)
@@ -7,6 +7,7 @@
 
 public enum SubTitleSetCellType: Int {
     case language
+    case soure
     case showType
     case font
     
@@ -14,6 +15,8 @@ public enum SubTitleSetCellType: Int {
         switch self {
         case .language:
             return "语言".l10n
+        case .soure:
+            return "声源".l10n
         case .showType:
             return "字幕展示内容".l10n
         case .font:
@@ -37,6 +40,9 @@ class SubTitleSetCell: BaseTableViewCell {
             if type == .language {
                 valueLabel.text = model.lan_form.title + "-" + model.lan_to.title
             }
+            else if type == .soure {
+                valueLabel.text = model.sourceType.title
+            }
             else if type == .showType {
                 valueLabel.text = model.showType.title
             }
index d35a33c..9f72411 100644 (file)
@@ -8,7 +8,7 @@
 import UIKit
 class SubTitleSetVC: BaseVC{
     let tableView = UITableView(frame: .zero, style: .plain)
-    var list:[SubTitleSetCellType] = [.language,.showType,.font]
+    var list:[SubTitleSetCellType] = [.language,.soure,.showType,.font]
     let imgPicker = ImagePickerManager()
     
     override func viewDidLoad() {
@@ -62,6 +62,8 @@ extension SubTitleSetVC:UITableViewDelegate,UITableViewDataSource {
         switch data {
         case .language:
             languageAction()
+        case .soure:
+            sourceTypeAction()
         case .showType:
             showTypeAction()
         case .font:
@@ -89,6 +91,20 @@ extension SubTitleSetVC{
             tableView.reloadData()
         }
     }
+    
+    @objc func sourceTypeAction(){
+        let cache = SubTitleCache.shared.get()
+        let list:[SubTitleSoureType] = [.mic,.phone]
+        let picker = CustomPicker(title: "声音源".l10n, list: list.map{$0.title})
+        picker.selectedIndex = list.firstIndex(where: {cache.sourceType.title == $0.title})!
+        picker.show()
+        picker.didSelected = {[weak self] (index,value) in
+            guard let self = self else { return  }
+            cache.sourceType = list.first(where: {$0.title == value})!
+            SubTitleCache.shared.save(cache)
+            tableView.reloadData()
+        }
+    }
     @objc func showTypeAction(){
         let cache = SubTitleCache.shared.get()
         let list:[SubTitleShowType] = [.all,.from,.to]
@@ -104,7 +120,7 @@ extension SubTitleSetVC{
     }
     @objc func fontAction(){
         let cache = SubTitleCache.shared.get()
-        let list:[SubTitleSFontType] = [.min,.stand,.big]
+        let list:[SubTitleFontType] = [.min,.stand,.big]
         let picker = CustomPicker(title: "字体大小".l10n, list: list.map{$0.title})
         picker.selectedIndex = list.firstIndex(where: {cache.fontType.title == $0.title})!
         picker.show()
index 5511b90..d713487 100644 (file)
@@ -6,6 +6,7 @@
 //
 
 import UIKit
+import DeepChordsSdk
 class LogVC: BaseVC {
     
     var textView =  UITextView()
@@ -32,7 +33,12 @@ class LogVC: BaseVC {
     override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
         
-        textView.text = Logger.logs.joined()
+        if CCDevice.isJoy {
+            
+        }
+        else{
+            textView.text = DCLogger.logs.joined()
+        }
         let range = NSMakeRange(textView.text.count - 1, 1)
         textView.scrollRangeToVisible(range)
     }
index 19aa902..6ce55dd 100644 (file)
@@ -12,6 +12,12 @@ class LanguageSelectItem: BaseView {
     let switcIcon = UIImageView()
     var languageChange:((_ from:CCAiLanguage,_ to:CCAiLanguage)->Void)?
     
+    var enable:Bool = true{
+        didSet{
+            self.alpha = enable ? 1:0.5
+        }
+    }
+    
     override func setupViews() {
         addSubviews([bottonView])
         bottonView.addSubviews([leftLabel,rightLabel,switcIcon])
@@ -58,6 +64,9 @@ class LanguageSelectItem: BaseView {
         }
     }
     @objc func switchAction(){
+        if !enable {
+            return
+        }
         let text1 = leftLabel.language
         let text2 = rightLabel.language
         leftLabel.language = text2
@@ -67,6 +76,9 @@ class LanguageSelectItem: BaseView {
         languageChange?(leftLabel.language,rightLabel.language)
     }
     @objc func leftAction(){
+        if !enable {
+            return
+        }
         let v = LanguagePickerView(languages: CCAiLanguage.all,isLeft: true,left: leftLabel.language,right: rightLabel.language)
         v.selectedIndex = v.list.firstIndex(where: {$0.title == leftLabel.language.title}) ?? 0
         v.show()
@@ -84,6 +96,9 @@ class LanguageSelectItem: BaseView {
         }
     }
     @objc func rightAction(){
+        if !enable {
+            return
+        }
         let v = LanguagePickerView(languages: CCAiLanguage.all,isLeft: false,left: leftLabel.language,right: rightLabel.language)
         v.selectedIndex = v.list.firstIndex(where: {$0.title == rightLabel.language.title}) ?? 0
         v.show()