From f909de3bfce928f4075c85b8cc098a2d68742ab5 Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Wed, 18 Dec 2024 22:02:41 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9E=A0=EA=B8=88=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=20=EC=9E=AC=EC=83=9D?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EB=8F=99=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Resources/Debug/SodaLive-dev-Info.plist | 444 +++++++++--------- .../Player/ContentPlayerPlayManager.swift | 67 ++- 2 files changed, 272 insertions(+), 239 deletions(-) diff --git a/SodaLive/Resources/Debug/SodaLive-dev-Info.plist b/SodaLive/Resources/Debug/SodaLive-dev-Info.plist index 89a964a..0828a8c 100644 --- a/SodaLive/Resources/Debug/SodaLive-dev-Info.plist +++ b/SodaLive/Resources/Debug/SodaLive-dev-Info.plist @@ -1,226 +1,226 @@ - - FirebaseAppDelegateProxyEnabled - - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - UIAppFonts - - gmarket_sans_bold.otf - gmarket_sans_medium.otf - gmarket_sans_light.otf - - UIBackgroundModes - - audio - fetch - remote-notification - - GADApplicationIdentifier - ca-app-pub-1299501215847962~3447556960 - SKAdNetworkItems - - - SKAdNetworkIdentifier - cstr6suwn9.skadnetwork - - - SKAdNetworkIdentifier - 4fzdc2evr5.skadnetwork - - - SKAdNetworkIdentifier - 4pfyvq9l8r.skadnetwork - - - SKAdNetworkIdentifier - 2fnua5tdw4.skadnetwork - - - SKAdNetworkIdentifier - ydx93a7ass.skadnetwork - - - SKAdNetworkIdentifier - 5a6flpkh64.skadnetwork - - - SKAdNetworkIdentifier - p78axxw29g.skadnetwork - - - SKAdNetworkIdentifier - v72qych5uu.skadnetwork - - - SKAdNetworkIdentifier - ludvb6z3bs.skadnetwork - - - SKAdNetworkIdentifier - cp8zw746q7.skadnetwork - - - SKAdNetworkIdentifier - 3sh42y64q3.skadnetwork - - - SKAdNetworkIdentifier - c6k4g5qg8m.skadnetwork - - - SKAdNetworkIdentifier - s39g8k73mm.skadnetwork - - - SKAdNetworkIdentifier - 3qy4746246.skadnetwork - - - SKAdNetworkIdentifier - f38h382jlk.skadnetwork - - - SKAdNetworkIdentifier - hs6bdukanm.skadnetwork - - - SKAdNetworkIdentifier - v4nxqhlyqp.skadnetwork - - - SKAdNetworkIdentifier - wzmmz9fp6w.skadnetwork - - - SKAdNetworkIdentifier - yclnxrl5pm.skadnetwork - - - SKAdNetworkIdentifier - t38b2kh725.skadnetwork - - - SKAdNetworkIdentifier - 7ug5zh24hu.skadnetwork - - - SKAdNetworkIdentifier - gta9lk7p23.skadnetwork - - - SKAdNetworkIdentifier - vutu7akeur.skadnetwork - - - SKAdNetworkIdentifier - y5ghdn5j9k.skadnetwork - - - SKAdNetworkIdentifier - n6fk4nfna4.skadnetwork - - - SKAdNetworkIdentifier - v9wttpbfk9.skadnetwork - - - SKAdNetworkIdentifier - n38lu8286q.skadnetwork - - - SKAdNetworkIdentifier - 47vhws6wlr.skadnetwork - - - SKAdNetworkIdentifier - kbd757ywx3.skadnetwork - - - SKAdNetworkIdentifier - 9t245vhmpl.skadnetwork - - - SKAdNetworkIdentifier - eh6m2bh4zr.skadnetwork - - - SKAdNetworkIdentifier - a2p9lx4jpn.skadnetwork - - - SKAdNetworkIdentifier - 22mmun2rn5.skadnetwork - - - SKAdNetworkIdentifier - 4468km3ulz.skadnetwork - - - SKAdNetworkIdentifier - 2u9pt9hc89.skadnetwork - - - SKAdNetworkIdentifier - 8s468mfl3y.skadnetwork - - - SKAdNetworkIdentifier - klf5c3l5u5.skadnetwork - - - SKAdNetworkIdentifier - ppxm28t8ap.skadnetwork - - - SKAdNetworkIdentifier - ecpz2srf59.skadnetwork - - - SKAdNetworkIdentifier - uw77j35x4d.skadnetwork - - - SKAdNetworkIdentifier - pwa73g5rt2.skadnetwork - - - SKAdNetworkIdentifier - mlmmfzh3r3.skadnetwork - - - SKAdNetworkIdentifier - 578prtvx9j.skadnetwork - - - SKAdNetworkIdentifier - 4dzt52r2t5.skadnetwork - - - SKAdNetworkIdentifier - e5fvkxwrpn.skadnetwork - - - SKAdNetworkIdentifier - 8c4e2ghe7u.skadnetwork - - - SKAdNetworkIdentifier - zq492l623r.skadnetwork - - - SKAdNetworkIdentifier - 3rd42ekr43.skadnetwork - - - SKAdNetworkIdentifier - 3qcr597p9d.skadnetwork - - - + + FirebaseAppDelegateProxyEnabled + + GADApplicationIdentifier + ca-app-pub-1299501215847962~3447556960 + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + SKAdNetworkItems + + + SKAdNetworkIdentifier + cstr6suwn9.skadnetwork + + + SKAdNetworkIdentifier + 4fzdc2evr5.skadnetwork + + + SKAdNetworkIdentifier + 4pfyvq9l8r.skadnetwork + + + SKAdNetworkIdentifier + 2fnua5tdw4.skadnetwork + + + SKAdNetworkIdentifier + ydx93a7ass.skadnetwork + + + SKAdNetworkIdentifier + 5a6flpkh64.skadnetwork + + + SKAdNetworkIdentifier + p78axxw29g.skadnetwork + + + SKAdNetworkIdentifier + v72qych5uu.skadnetwork + + + SKAdNetworkIdentifier + ludvb6z3bs.skadnetwork + + + SKAdNetworkIdentifier + cp8zw746q7.skadnetwork + + + SKAdNetworkIdentifier + 3sh42y64q3.skadnetwork + + + SKAdNetworkIdentifier + c6k4g5qg8m.skadnetwork + + + SKAdNetworkIdentifier + s39g8k73mm.skadnetwork + + + SKAdNetworkIdentifier + 3qy4746246.skadnetwork + + + SKAdNetworkIdentifier + f38h382jlk.skadnetwork + + + SKAdNetworkIdentifier + hs6bdukanm.skadnetwork + + + SKAdNetworkIdentifier + v4nxqhlyqp.skadnetwork + + + SKAdNetworkIdentifier + wzmmz9fp6w.skadnetwork + + + SKAdNetworkIdentifier + yclnxrl5pm.skadnetwork + + + SKAdNetworkIdentifier + t38b2kh725.skadnetwork + + + SKAdNetworkIdentifier + 7ug5zh24hu.skadnetwork + + + SKAdNetworkIdentifier + gta9lk7p23.skadnetwork + + + SKAdNetworkIdentifier + vutu7akeur.skadnetwork + + + SKAdNetworkIdentifier + y5ghdn5j9k.skadnetwork + + + SKAdNetworkIdentifier + n6fk4nfna4.skadnetwork + + + SKAdNetworkIdentifier + v9wttpbfk9.skadnetwork + + + SKAdNetworkIdentifier + n38lu8286q.skadnetwork + + + SKAdNetworkIdentifier + 47vhws6wlr.skadnetwork + + + SKAdNetworkIdentifier + kbd757ywx3.skadnetwork + + + SKAdNetworkIdentifier + 9t245vhmpl.skadnetwork + + + SKAdNetworkIdentifier + eh6m2bh4zr.skadnetwork + + + SKAdNetworkIdentifier + a2p9lx4jpn.skadnetwork + + + SKAdNetworkIdentifier + 22mmun2rn5.skadnetwork + + + SKAdNetworkIdentifier + 4468km3ulz.skadnetwork + + + SKAdNetworkIdentifier + 2u9pt9hc89.skadnetwork + + + SKAdNetworkIdentifier + 8s468mfl3y.skadnetwork + + + SKAdNetworkIdentifier + klf5c3l5u5.skadnetwork + + + SKAdNetworkIdentifier + ppxm28t8ap.skadnetwork + + + SKAdNetworkIdentifier + ecpz2srf59.skadnetwork + + + SKAdNetworkIdentifier + uw77j35x4d.skadnetwork + + + SKAdNetworkIdentifier + pwa73g5rt2.skadnetwork + + + SKAdNetworkIdentifier + mlmmfzh3r3.skadnetwork + + + SKAdNetworkIdentifier + 578prtvx9j.skadnetwork + + + SKAdNetworkIdentifier + 4dzt52r2t5.skadnetwork + + + SKAdNetworkIdentifier + e5fvkxwrpn.skadnetwork + + + SKAdNetworkIdentifier + 8c4e2ghe7u.skadnetwork + + + SKAdNetworkIdentifier + zq492l623r.skadnetwork + + + SKAdNetworkIdentifier + 3rd42ekr43.skadnetwork + + + SKAdNetworkIdentifier + 3qcr597p9d.skadnetwork + + + UIAppFonts + + gmarket_sans_bold.otf + gmarket_sans_medium.otf + gmarket_sans_light.otf + + UIBackgroundModes + + audio + fetch + remote-notification + + diff --git a/SodaLive/Sources/Content/Player/ContentPlayerPlayManager.swift b/SodaLive/Sources/Content/Player/ContentPlayerPlayManager.swift index 34641b1..cc61f56 100644 --- a/SodaLive/Sources/Content/Player/ContentPlayerPlayManager.swift +++ b/SodaLive/Sources/Content/Player/ContentPlayerPlayManager.swift @@ -46,11 +46,21 @@ final class ContentPlayerPlayManager: NSObject, ObservableObject { override init() { self.player = AVPlayer() + + do { + let audioSession = AVAudioSession.sharedInstance() + try audioSession.setCategory(.playback, mode: .moviePlayback) + try audioSession.setActive(true) + } catch { + DEBUG_LOG("Audio Session 설정 실패: \(error.localizedDescription)") + } + super.init() } func setPlaylist(playlist: [AudioContentPlaylistContent]) { resetPlayer() + self.registerRemoteControlEvents() self.playlist = playlist playlistManager = AudioContentPlaylistManager(playlist: playlist) playNextContent() @@ -70,7 +80,6 @@ final class ContentPlayerPlayManager: NSObject, ObservableObject { .sink { [weak self] currentTime in if !(self?.isEditing ?? false) { self?.currentTime = CMTimeGetSeconds(currentTime) - MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = self?.currentTime } } .store(in: &cancellables) @@ -110,16 +119,7 @@ final class ContentPlayerPlayManager: NSObject, ObservableObject { } .store(in: &cancellables) - do { - let audioSession = AVAudioSession.sharedInstance() - try audioSession.setCategory(.playback, mode: .moviePlayback) - try audioSession.setActive(true) - - self.fetchAlbumArtAndUpdateNowPlayingInfo() - self.registerRemoteControlEvents() - } catch { - DEBUG_LOG("Audio Session 설정 실패: \(error.localizedDescription)") - } + self.fetchAlbumArtAndUpdateNowPlayingInfo() } private func checkPlaybackStart(bufferedTime: Double, isLikelyToKeepUp: Bool) { @@ -138,6 +138,7 @@ final class ContentPlayerPlayManager: NSObject, ObservableObject { DEBUG_LOG("재생 중단: 버퍼링 부족 (\(bufferedTime)초)") } } + updateNowPlayingInfo() } private func handlePlaybackEnded() { @@ -283,10 +284,24 @@ final class ContentPlayerPlayManager: NSObject, ObservableObject { } } + private func updateNowPlayingInfo() { + guard var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo else { return } + + nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player?.currentTime().seconds + nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = isPlaying ? 1.0 : 0.0 + + let duration = CMTimeGetSeconds(player?.currentItem?.duration ?? CMTime.zero) + if duration.isFinite { + nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = duration + } + + MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo + } + private func registerNowPlayingInfoCenter(with albumArtImage: UIImage?) { - let center = MPNowPlayingInfoCenter.default() - var nowPlayingInfo = [String: Any]() + guard let currentItem = player?.currentItem else { return } + var nowPlayingInfo = [String: Any]() nowPlayingInfo[MPMediaItemPropertyTitle] = title nowPlayingInfo[MPMediaItemPropertyArtist] = nickname @@ -296,33 +311,51 @@ final class ContentPlayerPlayManager: NSObject, ObservableObject { } if let player = player { - nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = player.currentItem?.duration.seconds nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate + nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player.currentTime().seconds + + // CMTimeGetSeconds를 사용해 duration을 가져옴 + let duration = CMTimeGetSeconds(currentItem.duration) + if duration.isFinite { + nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = duration + } } - center.nowPlayingInfo = nowPlayingInfo + MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo } private func registerRemoteControlEvents() { let center = MPRemoteCommandCenter.shared() - center.playCommand.isEnabled = true center.playCommand.addTarget { [unowned self] (commandEvent) -> MPRemoteCommandHandlerStatus in self.playOrPause() return .success } - center.pauseCommand.isEnabled = true center.pauseCommand.addTarget { [unowned self] (commandEvent) -> MPRemoteCommandHandlerStatus in self.playOrPause() return .success } + + center.nextTrackCommand.isEnabled = true + center.nextTrackCommand.addTarget { [unowned self] (commandEvent) -> MPRemoteCommandHandlerStatus in + self.playNextContent() + return .success + } + + center.previousTrackCommand.isEnabled = true + center.previousTrackCommand.addTarget { [unowned self] (commandEvent) -> MPRemoteCommandHandlerStatus in + self.playPreviousContent() + return .success + } } private func unRegisterRemoteControlEvents() { let center = MPRemoteCommandCenter.shared() center.playCommand.removeTarget(nil) center.pauseCommand.removeTarget(nil) + center.nextTrackCommand.removeTarget(nil) + center.previousTrackCommand.removeTarget(nil) UIApplication.shared.endReceivingRemoteControlEvents() } }