修改了音乐停止进入后台,则去掉锁屏控制
authorliangzhenying <867174124@qq.com>
Tue, 20 Jan 2026 02:52:48 +0000 (10:52 +0800)
committerliangzhenying <867174124@qq.com>
Tue, 20 Jan 2026 02:52:48 +0000 (10:52 +0800)
ShenYin/ShenYin.xcodeproj/project.pbxproj
ShenYin/ShenYin/Sdk/DcSdk/tool/CCPage.swift
ShenYin/ShenYin/Sdk/JoySdk/tool/CCPage.swift
ShenYin/ShenYin/UI/Sleep/AudioPlayerManager.swift
ShenYin/ShenYin/UI/Sleep/MusicPlayer.swift [deleted file]
document/20260119-182015.jpg [new file with mode: 0644]

index 764a123..bb0c0c4 100644 (file)
                                CODE_SIGN_ENTITLEMENTS = ShenYin/ShenYin.entitlements;
                                CODE_SIGN_IDENTITY = "Apple Development";
                                CODE_SIGN_STYLE = Automatic;
-                               CURRENT_PROJECT_VERSION = 1002;
+                               CURRENT_PROJECT_VERSION = 1003;
                                DEVELOPMENT_TEAM = G23X75CJ67;
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(inherited)",
                                );
                                GENERATE_INFOPLIST_FILE = YES;
                                INFOPLIST_FILE = ShenYin/Info.plist;
-                               INFOPLIST_KEY_CFBundleDisplayName = PLAYBOY;
+                               INFOPLIST_KEY_CFBundleDisplayName = DeepChords;
                                INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
                                INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "扫描附近蓝牙设备需要获得权限";
                                INFOPLIST_KEY_NSCameraUsageDescription = "修改用户头像、提交意见反馈需要访问相册使用摄像头";
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/ShenYin/Sdk/DcSdk/opus/code_opus/lib",
                                );
-                               MARKETING_VERSION = 1.1.0;
+                               MARKETING_VERSION = 1.0.3;
                                PRODUCT_BUNDLE_IDENTIFIER = com.deepchords.app;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                PROVISIONING_PROFILE_SPECIFIER = "";
                                CODE_SIGN_ENTITLEMENTS = ShenYin/ShenYin.entitlements;
                                CODE_SIGN_IDENTITY = "Apple Development";
                                CODE_SIGN_STYLE = Automatic;
-                               CURRENT_PROJECT_VERSION = 1002;
+                               CURRENT_PROJECT_VERSION = 1003;
                                DEVELOPMENT_TEAM = G23X75CJ67;
                                FRAMEWORK_SEARCH_PATHS = (
                                        "$(inherited)",
                                );
                                GENERATE_INFOPLIST_FILE = YES;
                                INFOPLIST_FILE = ShenYin/Info.plist;
-                               INFOPLIST_KEY_CFBundleDisplayName = PLAYBOY;
+                               INFOPLIST_KEY_CFBundleDisplayName = DeepChords;
                                INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
                                INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "扫描附近蓝牙设备需要获得权限";
                                INFOPLIST_KEY_NSCameraUsageDescription = "修改用户头像、提交意见反馈需要访问相册使用摄像头";
                                        "$(inherited)",
                                        "$(PROJECT_DIR)/ShenYin/Sdk/DcSdk/opus/code_opus/lib",
                                );
-                               MARKETING_VERSION = 1.1.0;
+                               MARKETING_VERSION = 1.0.3;
                                PRODUCT_BUNDLE_IDENTIFIER = com.deepchords.app;
                                PRODUCT_NAME = "$(TARGET_NAME)";
                                PROVISIONING_PROFILE_SPECIFIER = "";
                                        "$(PROJECT_DIR)/DeepChordsSdk",
                                        "$(PROJECT_DIR)/ShenYin/Sdk/Ota",
                                        "$(PROJECT_DIR)/ShenYin/Sdk/JoySdk",
+                                       "$(PROJECT_DIR)/ShenYin/Sdk/JoySdk/tool",
                                );
                                GENERATE_INFOPLIST_FILE = YES;
                                INFOPLIST_FILE = "ShenYin/ShenYin copy-Info.plist";
                                        "$(PROJECT_DIR)/DeepChordsSdk",
                                        "$(PROJECT_DIR)/ShenYin/Sdk/Ota",
                                        "$(PROJECT_DIR)/ShenYin/Sdk/JoySdk",
+                                       "$(PROJECT_DIR)/ShenYin/Sdk/JoySdk/tool",
                                );
                                GENERATE_INFOPLIST_FILE = YES;
                                INFOPLIST_FILE = "ShenYin/ShenYin copy-Info.plist";
index 3272eab..011e325 100644 (file)
@@ -7,6 +7,7 @@
 
 class CCPage{
     static func gotoChat(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
 //            App.shared.goToPage(JoyChatVC())
         }
@@ -15,6 +16,7 @@ class CCPage{
         }
     }
     static func gotoFieldRecord(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
 //            App.shared.goToPage(JoyXclyVC())
         }
@@ -23,6 +25,7 @@ class CCPage{
         }
     }
     static func gotoCallRecord(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
 //            if JoySdkManager.shared.callRecord.supportStereo{
 //                App.shared.goToPage(JoyStereoCallVC())
@@ -41,6 +44,7 @@ class CCPage{
         }
     }
     static func gotoChinese2Enlgish(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
 //            App.shared.goToPage(JoyChinese2EnglishVC())
         }
@@ -49,6 +53,7 @@ class CCPage{
         }
     }
     static func gotoTcty(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
 //            App.shared.goToPage(JoyTctyVC())
         }
@@ -57,6 +62,7 @@ class CCPage{
         }
     }
     static func gotoDialogTranslate(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
 //            App.shared.goToPage(JoyDialogTranslateVC())
         }
index e73b8a5..28efa96 100644 (file)
@@ -7,6 +7,7 @@
 
 class CCPage{
     static func gotoChat(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
             App.shared.goToPage(JoyChatVC())
         }
@@ -15,6 +16,7 @@ class CCPage{
         }
     }
     static func gotoFieldRecord(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
             App.shared.goToPage(JoyXclyVC())
         }
@@ -23,6 +25,7 @@ class CCPage{
         }
     }
     static func gotoCallRecord(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
             if JoySdkManager.shared.callRecord.supportStereo{
                 App.shared.goToPage(JoyStereoCallVC())
@@ -36,6 +39,7 @@ class CCPage{
         }
     }
     static func gotoChinese2Enlgish(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
             App.shared.goToPage(JoyChinese2EnglishVC())
         }
@@ -44,6 +48,7 @@ class CCPage{
         }
     }
     static func gotoTcty(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
             App.shared.goToPage(JoyTctyVC())
         }
@@ -52,6 +57,7 @@ class CCPage{
         }
     }
     static func gotoDialogTranslate(){
+        AudioPlayView.shared.closeAction()
         if CCDevice.isJoy {
             App.shared.goToPage(JoyDialogTranslateVC())
         }
index c4642c2..30b6268 100644 (file)
@@ -12,6 +12,9 @@ class AudioPlayerManager {
         return player.isPlaying
     }
     
+    // 添加远程控制命令的target存储
+    private var playCommandTarget: Any?
+    private var pauseCommandTarget: Any?
     
     private var audioPlayer: AVAudioPlayer?
     private var isLooping = true
@@ -35,6 +38,8 @@ class AudioPlayerManager {
             audioPlayer?.prepareToPlay()
             audioPlayer?.play()
             
+            // 如果之前有设置过远程控制,先移除旧的再重新设置
+            removeRemoteControlTargets()
             setupNowPlayingInfoCenter(url)
             setupRemoteControl()
             startProgressMonitoring()
@@ -58,7 +63,6 @@ class AudioPlayerManager {
         audioPlayer?.stop()
         stopProgressMonitoring()
         
-        // 停止音频会话并设置为非活动状态
         do {
             let audioSession = AVAudioSession.sharedInstance()
             try audioSession.setActive(false)
@@ -66,12 +70,21 @@ class AudioPlayerManager {
             print("Failed to deactivate audio session: \(error)")
         }
         
-        // 停止接收远程控制事件
+        // 移除远程控制命令的目标
+        removeRemoteControlTargets()
+        
         UIApplication.shared.endReceivingRemoteControlEvents()
-        // 清除MPNowPlayingInfoCenter中的信息
         let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
         nowPlayingInfoCenter.nowPlayingInfo = nil
+        
+        // 重置播放器和相关属性
+        audioPlayer = nil
+        isReady = false
+        currentProgress = 0
+        duration = 0
+        musicModel = nil
     }
+    
     func pause() {
         audioPlayer?.pause()
         stopProgressMonitoring()
@@ -94,15 +107,32 @@ class AudioPlayerManager {
         
         if let model = musicModel{
             nowPlayingInfo[MPMediaItemPropertyTitle] = model.name
-//            nowPlayingInfo[MPMediaItemPropertyArtist] = "Unknown Artist"
+            //nowPlayingInfo[MPMediaItemPropertyArtist] = "Unknown Artist"
             let albumArtwork = MPMediaItemArtwork(boundsSize: CGSize(width: 100, height: 100)) { _ in
                 return UIImage(named: "logo_2")!
             }
             nowPlayingInfo[MPMediaItemPropertyArtwork] = albumArtwork
+            
+            downloadImage(from: model.cover.yc.asUrl) { [weak self] image in
+                guard let self = self, let downloadedImage = image else { return }
+                
+                let albumArtwork = MPMediaItemArtwork(boundsSize: CGSize(width: 100, height: 100)) { _ in
+                    return downloadedImage
+                }
+                
+                // 更新现有的nowPlayingInfo,添加新封面
+                var updatedNowPlayingInfo = nowPlayingInfoCenter.nowPlayingInfo ?? [:]
+                updatedNowPlayingInfo[MPMediaItemPropertyArtwork] = albumArtwork
+                nowPlayingInfoCenter.nowPlayingInfo = updatedNowPlayingInfo
+            }
         }
         else{
             nowPlayingInfo[MPMediaItemPropertyTitle] = url.lastPathComponent
-            nowPlayingInfo[MPMediaItemPropertyArtist] = "Unknown Artist"
+            nowPlayingInfo[MPMediaItemPropertyArtist] = ""
+            let albumArtwork = MPMediaItemArtwork(boundsSize: CGSize(width: 100, height: 100)) { _ in
+                return UIImage(named: "logo_2")!
+            }
+            nowPlayingInfo[MPMediaItemPropertyArtwork] = albumArtwork
         }
         
         // 设置音乐时长
@@ -110,24 +140,54 @@ class AudioPlayerManager {
             nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = player.duration
         }
         
-        // 设置当前播放进度(初始为 0)
         nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = 0
-        
         nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo
     }
     
+    private func downloadImage(from url: URL?, completion: @escaping (UIImage?) -> Void) {
+        guard let url = url else{
+            completion(nil)
+            return}
+        URLSession.shared.dataTask(with: url) { data, _, error in
+            guard let data = data, error == nil,
+                  let image = UIImage(data: data) else {
+                DispatchQueue.main.async {
+                    completion(nil)
+                }
+                return
+            }
+            
+            DispatchQueue.main.async {
+                completion(image)
+            }
+        }.resume()
+    }
+    
     private func setupRemoteControl() {
         UIApplication.shared.beginReceivingRemoteControlEvents()
         let commandCenter = MPRemoteCommandCenter.shared()
         
-        commandCenter.playCommand.addTarget { [weak self] event in
+        // 存储目标引用以备后续移除
+        playCommandTarget = commandCenter.playCommand.addTarget { [weak self] event in
             self?.resumeMusic()
-            return.success
+            return .success
         }
         
-        commandCenter.pauseCommand.addTarget { [weak self] event in
+        pauseCommandTarget = commandCenter.pauseCommand.addTarget { [weak self] event in
             self?.pause()
-            return.success
+            return .success
+        }
+    }
+    
+    private func removeRemoteControlTargets() {
+        let commandCenter = MPRemoteCommandCenter.shared()
+        if let playTarget = playCommandTarget {
+            commandCenter.playCommand.removeTarget(playTarget)
+            playCommandTarget = nil
+        }
+        if let pauseTarget = pauseCommandTarget {
+            commandCenter.pauseCommand.removeTarget(pauseTarget)
+            pauseCommandTarget = nil
         }
     }
     
diff --git a/ShenYin/ShenYin/UI/Sleep/MusicPlayer.swift b/ShenYin/ShenYin/UI/Sleep/MusicPlayer.swift
deleted file mode 100644 (file)
index 6911301..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-//import AVFoundation
-//import MediaPlayer
-//
-//class MusicPlayer {
-//    static let shared = MusicPlayer()
-//    
-//    var musicModel:MusicModel?
-//    var isPlaying:Bool{
-//        guard let player = audioPlayer else {
-//            return false
-//        }
-//        return player.isPlaying
-//    }
-//    
-//    
-//    private var audioPlayer: AVAudioPlayer?
-//    private var isLooping = true
-//    private var progressTimer: Timer?
-//    
-//    var currentProgress:Float = 0
-//    var duration:Float = 0
-//    
-//    typealias ProgressCallback = (_ current: Float, _ duration: Float) -> Void
-//    var progressCallback: ProgressCallback?
-//    
-//    func playMusic(with path: String) {
-//        do {
-//            let url = URL(fileURLWithPath: path)
-//            audioPlayer = try AVAudioPlayer(contentsOf: url)
-//            audioPlayer?.numberOfLoops = isLooping ? -1 : 0
-//            audioPlayer?.prepareToPlay()
-//            audioPlayer?.play()
-//            
-//            setupNowPlayingInfoCenter(url)
-//            setupRemoteControl()
-//            startProgressMonitoring()
-//        } catch let error {
-//            print("Error playing music: \(error.localizedDescription)")
-//        }
-//    }
-//    
-//    func start() {
-//        audioPlayer?.play()
-//        startProgressMonitoring()
-//    }
-//    
-//    
-//    func pauseMusic() {
-//        audioPlayer?.pause()
-//        stopProgressMonitoring()
-//    }
-//    
-//    func resumeMusic() {
-//        audioPlayer?.play()
-//        startProgressMonitoring()
-//    }
-//    
-//    private func setupNowPlayingInfoCenter(_ url: URL) {
-//        let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
-//        var nowPlayingInfo = [String : Any]()
-//        
-//        // 假设音乐文件有元数据,这里简单设置标题为文件名
-//        nowPlayingInfo[MPMediaItemPropertyTitle] = url.lastPathComponent
-//        // 你可以根据需要添加更多元数据,如艺术家等
-//        
-//        nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo
-//    }
-//    
-//    private func setupRemoteControl() {
-//        UIApplication.shared.beginReceivingRemoteControlEvents()
-//        let commandCenter = MPRemoteCommandCenter.shared()
-//        
-//        commandCenter.playCommand.addTarget { [weak self] event in
-//            self?.resumeMusic()
-//            return.success
-//        }
-//        
-//        commandCenter.pauseCommand.addTarget { [weak self] event in
-//            self?.pauseMusic()
-//            return.success
-//        }
-//    }
-//    
-//    private func startProgressMonitoring() {
-//        progressTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
-//            guard let self = self, let player = self.audioPlayer else { return }
-//            currentProgress = Float(player.currentTime)
-//            duration = Float(player.duration)
-//            self.progressCallback?(currentProgress, duration)
-//        }
-//        RunLoop.current.add(progressTimer!, forMode:.common)
-//    }
-//    
-//    private func stopProgressMonitoring() {
-//        progressTimer?.invalidate()
-//        progressTimer = nil
-//    }
-//}
-
-
-//import AVFoundation
-//
-//class AudioPlayerManager {
-//    static let shared = AudioPlayerManager()
-//    var musicModel:MusicModel?
-//    var isPlaying:Bool{
-//        guard let player = player else {
-//            return false
-//        }
-//        return player.timeControlStatus == .playing
-//    }
-//
-//    var player: AVPlayer?
-//    var playerItem: AVPlayerItem?
-//    var timeObserverToken: Any?
-//
-//    typealias ProgressCallback = (_ current: Float, _ duration: Float) -> Void
-//    var progressCallback: ProgressCallback?
-//    var currentProgress:Float = 0
-//    var duration:Float = 0
-//
-//    func play(filePath: String) {
-//        stop()
-//
-//        Logger.debug("播放路径", filePath)
-//        let url = URL(fileURLWithPath: filePath)
-//        playerItem = AVPlayerItem(url: url)
-//        player = AVPlayer(playerItem: playerItem)
-//        setupProgressObserver()
-//        setupPlayToEndObserver()
-//    }
-//
-//    func setupProgressObserver() {
-//        guard let player = player else { return }
-//        let interval = CMTimeMake(value: 1, timescale: 10) // 每 0.1 秒调用一次回调
-//        timeObserverToken = player.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main) { [weak self] time in
-//            guard let self = self, let total = self.playerItem?.duration else { return }
-//            if CMTimeGetSeconds(total) > 0 {
-//                currentProgress = Float(CMTimeGetSeconds(time))
-//                duration = Float(CMTimeGetSeconds(total))
-//                self.progressCallback?(currentProgress,duration )
-//            }
-//        }
-//    }
-//
-//    func setupPlayToEndObserver() {
-//        NotificationCenter.default.addObserver(forName: Notification.Name.AVPlayerItemDidPlayToEndTime, object: playerItem, queue: nil) { [weak self] _ in
-//            guard let self = self else { return }
-//            self.restartPlayback()
-//        }
-//    }
-//
-//    func restartPlayback() {
-//        guard let player = player, let playerItem = playerItem else { return }
-//        player.seek(to: CMTime.zero)
-//        player.play()
-//    }
-//
-//
-//
-//    func start() {
-//        player?.play()
-//    }
-//
-//    func pause() {
-//        player?.pause()
-//    }
-//
-//    func stop() {
-//        player?.pause()
-//    }
-//
-//    func setDuration(_ duration: Float) {
-//        let seekTime = CMTimeMakeWithSeconds(Float64(duration), preferredTimescale: 1)
-//        player?.seek(to: seekTime)
-//    }
-//
-//    deinit {
-//        if let token = timeObserverToken {
-//            player?.removeTimeObserver(token)
-//        }
-//        NotificationCenter.default.removeObserver(self, name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: playerItem)
-//    }
-//}
diff --git a/document/20260119-182015.jpg b/document/20260119-182015.jpg
new file mode 100644 (file)
index 0000000..2692ddf
Binary files /dev/null and b/document/20260119-182015.jpg differ