Skip to content

Commit 000ef24

Browse files
committed
Create 241220_MPNowPlayingInfoCenter,_MPRemoteCommandCenter.md
1 parent 5b87f9a commit 000ef24

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# 241220 MPNowPlayingInfoCenter, MPRemoteCommandCenter
2+
3+
์•Œ๋ฆผ์„ผํ„ฐ์— ์•ฑ์—์„œ ์žฌ์ƒ์ค‘์ธ ์˜ค๋””์˜ค ์ •๋ณด๋ฅผ ๋„์›Œ๋ณด์ž~
4+
5+
12์›” 20์ผ (๊ธˆ)
6+
7+
8+
# ํ•™์Šต๋‚ด์šฉ
9+
10+
11+
- MPNowPlayingInfoCenter๋ฅผ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•˜๋Š”๊ฑฐ์ง€?
12+
- MPRemoteCommandCenter์—๋Š” ์–ด๋–ค ๊ธฐ๋Šฅ๋“ค์ด ์žˆ์ง€?
13+
- ์žฌ์ƒ์‹œ๊ฐ„ ์—†์ด '์‹ค์‹œ๊ฐ„'์œผ๋กœ ํ‘œ๊ธฐํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜์ง€?
14+
- ์ด๋ฏธ์ง€๋ฅผ ๋„คํŠธ์›Œํฌ๋กœ ๋‹ค์šด๋ฐ›์•„์„œ ํ‘œ์‹œํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜์ง€?
15+
16+
17+
# ๊ณ ๋ฏผํ•œ ์  / ํ•ด๊ฒฐ๋ฐฉ๋ฒ•
18+
19+
## MPNowPlayingInfoCenter
20+
21+
* ์•ฑ์ด ์žฌ์ƒํ•˜๋Š” ๋ฏธ๋””์–ด์˜ ์ •๋ณด๋ฅผ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด.
22+
* `nowPlayingInfo`๋ผ๋Š” ํ”„๋กœํผํ‹ฐ์— dictionary๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์€ ์ •๋ณด๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
23+
24+
|**ํ‚ค ๊ฐ’**|**์„ค๋ช…**|
25+
|---|---|
26+
|`MPMediaItemPropertyAlbumTitle`|์•จ๋ฒ”์˜ ์ œ๋ชฉ|
27+
|`MPMediaItemPropertyAlbumTrackCount`|์•จ๋ฒ”์— ํฌํ•จ๋œ ์ด ํŠธ๋ž™ ์ˆ˜|
28+
|`MPMediaItemPropertyAlbumTrackNumber`|ํ˜„์žฌ ํŠธ๋ž™์˜ ๋ฒˆํ˜ธ|
29+
|`MPMediaItemPropertyArtist`|์•„ํ‹ฐ์ŠคํŠธ์˜ ์ด๋ฆ„|
30+
|`MPMediaItemPropertyArtwork`|์•จ๋ฒ” ์•„ํŠธ์›Œํฌ ์ด๋ฏธ์ง€. `MPMediaItemArtwork` ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์ •ํ•œ๋‹ค.|
31+
|`MPMediaItemPropertyComposer`|์ž‘๊ณก๊ฐ€์˜ ์ด๋ฆ„|
32+
|`MPMediaItemPropertyDiscCount`|์•จ๋ฒ”์˜ ์ด ๋””์Šคํฌ ์ˆ˜|
33+
|`MPMediaItemPropertyDiscNumber`|ํ˜„์žฌ ๋””์Šคํฌ์˜ ๋ฒˆํ˜ธ|
34+
|`MPMediaItemPropertyGenre`|์žฅ๋ฅด|
35+
|`MPMediaItemPropertyPlaybackDuration`|์žฌ์ƒ ์‹œ๊ฐ„(์ดˆ ๋‹จ์œ„)|
36+
|`MPMediaItemPropertyTitle`|ํŠธ๋ž™์˜ ์ œ๋ชฉ|
37+
|`MPNowPlayingInfoPropertyElapsedPlaybackTime`|ํ˜„์žฌ ์žฌ์ƒ๋œ ์‹œ๊ฐ„(์ดˆ ๋‹จ์œ„)|
38+
|`MPNowPlayingInfoPropertyPlaybackRate`|์žฌ์ƒ ์†๋„. ์ผ๋ฐ˜์ ์œผ๋กœ 1.0์€ ์ •์ƒ ์žฌ์ƒ, 0.0์€ ์ผ์‹œ ์ •์ง€๋ฅผ ์˜๋ฏธํ•œ๋‹ค.|
39+
|`MPNowPlayingInfoPropertyDefaultPlaybackRate`|๊ธฐ๋ณธ ์žฌ์ƒ ์†๋„|
40+
|`MPNowPlayingInfoPropertyPlaybackQueueIndex`|ํ˜„์žฌ ์žฌ์ƒ ์ค‘์ธ ํ•ญ๋ชฉ์˜ ์žฌ์ƒ ๋ชฉ๋ก ์ธ๋ฑ์Šค|
41+
|`MPNowPlayingInfoPropertyPlaybackQueueCount`|์žฌ์ƒ ๋ชฉ๋ก์˜ ์ด ํ•ญ๋ชฉ ์ˆ˜|
42+
|`MPNowPlayingInfoPropertyChapterNumber`|ํ˜„์žฌ ์žฌ์ƒ ์ค‘์ธ ์ฑ•ํ„ฐ ๋ฒˆํ˜ธ|
43+
|`MPNowPlayingInfoPropertyChapterCount`|์ด ์ฑ•ํ„ฐ ์ˆ˜|
44+
|`MPNowPlayingInfoPropertyIsLiveStream`|ํ˜„์žฌ ์žฌ์ƒ ์ค‘์ธ ํ•ญ๋ชฉ์ด ๋ผ์ด๋ธŒ ์ŠคํŠธ๋ฆผ์ธ์ง€ ์—ฌ๋ถ€ (`true` ๋˜๋Š” `false`)|
45+
|`MPNowPlayingInfoPropertyMediaType`|ํ˜„์žฌ ์žฌ์ƒ ์ค‘์ธ ๋ฏธ๋””์–ด์˜ ์œ ํ˜•. `MPNowPlayingInfoMediaType` ๊ฐ’์„ ์‚ฌ์šฉ.|
46+
47+
```swift
48+
import MediaPlayer
49+
50+
func updateNowPlayingInfo(title: String, artist: String, albumTitle: String, duration: TimeInterval, currentTime: TimeInterval, artworkImage: UIImage?) {
51+
var nowPlayingInfo: [String: Any] = [
52+
MPMediaItemPropertyTitle: title,
53+
MPMediaItemPropertyArtist: artist,
54+
MPMediaItemPropertyAlbumTitle: albumTitle,
55+
MPMediaItemPropertyPlaybackDuration: duration,
56+
MPNowPlayingInfoPropertyElapsedPlaybackTime: currentTime,
57+
MPNowPlayingInfoPropertyPlaybackRate: 1.0 // 1.0์€ ์žฌ์ƒ ์ค‘, 0.0์€ ์ผ์‹œ ์ •์ง€ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋ƒ„
58+
]
59+
60+
// ์•จ๋ฒ” ์•„ํŠธ์›Œํฌ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์„ค์ •
61+
if let artworkImage {
62+
let artwork = MPMediaItemArtwork(boundsSize: artworkImage.size) { size in
63+
return artworkImage
64+
}
65+
nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork
66+
}
67+
68+
// MPNowPlayingInfoCenter์— ์ •๋ณด ์„ค์ •
69+
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
70+
}
71+
```
72+
73+
## ์ด๋ฏธ์ง€๋ฅผ ๋น„๋™๊ธฐ๋กœ ๋ฐ›์•„ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•
74+
75+
Kingfisher ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•ด์„œ ์ด๋ฏธ์ง€๋ฅผ ๋น„๋™๊ธฐ๋กœ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
76+
77+
์ด๋ ‡๊ฒŒ ๋น„๋™๊ธฐ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๋Š” ๊ฒฝ์šฐ์—๋Š”, nowPlayingInfo ์„ค์ • ๋˜ํ•œ ๋งจ ๋งˆ์ง€๋ง‰์— ๋น„๋™๊ธฐ๋กœ ์„ค์ •ํ•˜๊ฒŒ ๋œ๋‹ค.
78+
79+
```swift
80+
import MediaPlayer
81+
import Kingfisher
82+
83+
func fetchArtwork(from url: URL) async -> MPMediaItemArtwork? {
84+
do {
85+
let result = try await KingfisherManager.shared.retrieveImage(with: url)
86+
let artwork = MPMediaItemArtwork(boundsSize: result.image.size) { _ in
87+
return result.image
88+
}
89+
return artwork
90+
} catch {
91+
print("์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์‹คํŒจ: \(error)")
92+
return nil
93+
}
94+
}
95+
```
96+
97+
## MPRemoteCommandCenter
98+
99+
* ์™ธ๋ถ€ ์•ก์„ธ์„œ๋ฆฌ ๋ฐ ์‹œ์Šคํ…œ ์ปจํŠธ๋กค์ด ์ „์†กํ•˜๋Š” ์›๊ฒฉ ์ œ์–ด ์ด๋ฒคํŠธ์— ์‘๋‹ตํ•˜๋Š” ๊ฐ์ฒด.
100+
* ์ด ๊ฐ์ฒด๋กœ '์žฌ์ƒ', '์ผ์‹œ์ •์ง€' ๋ฒ„ํŠผ์˜ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•„ ์•ฑ ๋‚ด์—์„œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
101+
102+
```swift
103+
private func setupRemoteCommandHandlers() {
104+
// ์žฌ์ƒ ๋ฒ„ํŠผ ์ฒ˜๋ฆฌ
105+
commandCenter.playCommand.addTarget { [weak self] event in
106+
guard let self = self else { return .commandFailed }
107+
108+
if !self.isPlaying {
109+
self.play()
110+
return .success
111+
}
112+
return .commandFailed
113+
}
114+
115+
// ์ผ์‹œ์ •์ง€ ๋ฒ„ํŠผ ์ฒ˜๋ฆฌ
116+
commandCenter.pauseCommand.addTarget { [weak self] event in
117+
guard let self = self else { return .commandFailed }
118+
119+
if self.isPlaying {
120+
self.pause()
121+
return .success
122+
}
123+
return .commandFailed
124+
}
125+
}
126+
```
127+
128+
> ์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ๋ช…๋ น๋“ค์ด ์กด์žฌํ•œ๋‹ค.
129+
130+
|**Command**|**์„ค๋ช…**|
131+
|---|---|
132+
|`playCommand`|์žฌ์ƒ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์„ ๋•Œ|
133+
|`pauseCommand`|์ผ์‹œ ์ •์ง€ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์„ ๋•Œ|
134+
|`stopCommand`|์ •์ง€ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์„ ๋•Œ|
135+
|`togglePlayPauseCommand`|์žฌ์ƒ/์ผ์‹œ ์ •์ง€ ํ† ๊ธ€ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์„ ๋•Œ|
136+
|`nextTrackCommand`|๋‹ค์Œ ํŠธ๋ž™ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์„ ๋•Œ|
137+
|`previousTrackCommand`|์ด์ „ ํŠธ๋ž™ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์„ ๋•Œ|
138+
|`seekForwardCommand`|์•ž์œผ๋กœ ํƒ์ƒ‰ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์„ ๋•Œ|
139+
|`seekBackwardCommand`|๋’ค๋กœ ํƒ์ƒ‰ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์„ ๋•Œ|
140+
|`skipForwardCommand`|์ •ํ•ด์ง„ ์‹œ๊ฐ„๋งŒํผ ์•ž์œผ๋กœ ๊ฑด๋„ˆ๋œ€|
141+
|`skipBackwardCommand`|์ •ํ•ด์ง„ ์‹œ๊ฐ„๋งŒํผ ๋’ค๋กœ ๊ฑด๋„ˆ๋œ€|
142+
|`changePlaybackRateCommand`|์žฌ์ƒ ์†๋„ ๋ณ€๊ฒฝ|
143+
|`changeRepeatModeCommand`|๋ฐ˜๋ณต ๋ชจ๋“œ ๋ณ€๊ฒฝ|
144+
|`changeShuffleModeCommand`|์…”ํ”Œ ๋ชจ๋“œ ๋ณ€๊ฒฝ|
145+
|`rateCommand`|๋ฏธ๋””์–ด ํ‰๊ฐ€(๋ณ„์  ๋“ฑ)|
146+
|`likeCommand`|์ข‹์•„์š” ๋ฒ„ํŠผ|
147+
|`dislikeCommand`|์‹ซ์–ด์š” ๋ฒ„ํŠผ|
148+
|`bookmarkCommand`|๋ถ๋งˆํฌ ์ถ”๊ฐ€ ๋ฒ„ํŠผ|
149+
150+
## ์žฌ์ƒ์ด ๋ชจ๋‘ ๋๋‚ฌ์„ ๋•Œ ์•Œ๋ฆผ ๋ฐ›๋Š” ๋ฐฉ๋ฒ•
151+
152+
์•„๋ž˜์ฒ˜๋Ÿผ NotificationCenter๋ฅผ ํ™œ์šฉํ•ด์„œ AVPlayerItemDidPlayToEndTime์„ ๊ตฌ๋…ํ•˜๋ฉด ๋œ๋‹ค!
153+
154+
```swift
155+
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime,
156+
object: item,
157+
queue: .main,
158+
using: { _ in
159+
// ์—ฌ๊ธฐ์„œ ์•ฑ ๋‚ด์—์„œ ์žฌ์ƒ์ค‘์ธ AVPlayer์˜ ์žฌ์ƒ์„ ๋ฉˆ์ถ”๋„๋ก ๊ตฌํ˜„ํ•ด๋ณด์ž.
160+
})
161+
```
162+
163+
164+
---
165+
166+
167+
# ์ฐธ๊ณ  ๋งํฌ
168+
169+
170+
- [https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter](https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter)
171+
- [https://developer.apple.com/documentation/mediaplayer/mpremotecommandcenter](https://developer.apple.com/documentation/mediaplayer/mpremotecommandcenter)
172+
- [https://developer.apple.com/documentation/avfoundation/avplayeritem/didplaytoendtimenotification](https://developer.apple.com/documentation/avfoundation/avplayeritem/didplaytoendtimenotification)

0 commit comments

Comments
ย (0)