@@ -172,7 +172,7 @@ public static function songDetails(string $songId, string $language = 'en-US'):
172172 }
173173
174174 // call catalog: dev token only (no music-user-token necessary)
175- $ resp = \ Kirby \ Http \ Remote::get ('https://api.music.apple.com/v1/catalog/ ' . rawurlencode ($ storefront ) . '/songs/ ' . rawurlencode ($ songId ), [
175+ $ resp = Remote::get ('https://api.music.apple.com/v1/catalog/ ' . rawurlencode ($ storefront ) . '/songs/ ' . rawurlencode ($ songId ), [
176176 'headers ' => [
177177 'Authorization ' => 'Bearer ' . $ dev ,
178178 'Accept ' => 'application/json ' ,
@@ -201,8 +201,10 @@ public static function songDetails(string $songId, string $language = 'en-US'):
201201 if (!empty ($ a ['artwork ' ]['url ' ])) {
202202 $ img = str_replace (['{w} ' ,'{h} ' ], [600 , 600 ], $ a ['artwork ' ]['url ' ]);
203203 }
204- $ seconds = isset ($ a ['durationInMillis ' ]) ? (int ) floor ($ a ['durationInMillis ' ] / 1000 ) : null ;
205- $ duration = is_int ($ seconds ) ? sprintf ('%d:%02d ' , floor ($ seconds /60 ), $ seconds % 60 ) : null ;
204+
205+ $ duration = isset ($ a ['durationInMillis ' ])
206+ ? self ::ms_to_mmss ((int )$ a ['durationInMillis ' ])
207+ : null ;
206208
207209 // releaseYear from releaseDate
208210 $ releaseDate = $ a ['releaseDate ' ] ?? null ;
@@ -239,6 +241,22 @@ public static function songDetails(string $songId, string $language = 'en-US'):
239241 ], 200 );
240242 }
241243
244+ // helper: milliseconds to mm:ss
245+ public static function ms_to_mmss (?int $ ms , bool $ forceHours = false ): ?string
246+ {
247+ if ($ ms === null ) return null ;
248+ $ total = (int ) round ($ ms / 1000 );
249+ $ h = intdiv ($ total , 3600 );
250+ $ rem = $ total % 3600 ;
251+ $ m = intdiv ($ total , 60 );
252+ $ s = $ total % 60 ;
253+
254+ if ($ forceHours || $ h > 0 ) {
255+ return sprintf ('%d:%02d:%02d ' , $ h , $ m , $ s ); // H:MM:SS
256+ }
257+ return sprintf ('%d:%02d ' , $ m , $ s );
258+ }
259+
242260 // get individual album details
243261 public static function albumDetails (string $ albumId , string $ language = 'en-US ' ): Response
244262 {
@@ -262,7 +280,7 @@ public static function albumDetails(string $albumId, string $language = 'en-US')
262280 }
263281
264282 // call catalog: dev token only (no music-user-token necessary)
265- $ resp = \ Kirby \ Http \ Remote::get ('https://api.music.apple.com/v1/catalog/ ' . rawurlencode ($ storefront ) . '/albums/ ' . rawurlencode ($ albumId ), [
283+ $ resp = Remote::get ('https://api.music.apple.com/v1/catalog/ ' . rawurlencode ($ storefront ) . '/albums/ ' . rawurlencode ($ albumId ), [
266284 'headers ' => [
267285 'Authorization ' => 'Bearer ' . $ dev ,
268286 'Accept ' => 'application/json ' ,
@@ -291,6 +309,7 @@ public static function albumDetails(string $albumId, string $language = 'en-US')
291309 if (!empty ($ a ['artwork ' ]['url ' ])) {
292310 $ img = str_replace (['{w} ' ,'{h} ' ], [600 , 600 ], $ a ['artwork ' ]['url ' ]);
293311 }
312+
294313 $ seconds = isset ($ a ['durationInMillis ' ]) ? (int ) floor ($ a ['durationInMillis ' ] / 1000 ) : null ;
295314 $ duration = is_int ($ seconds ) ? sprintf ('%d:%02d ' , floor ($ seconds /60 ), $ seconds % 60 ) : null ;
296315
@@ -312,18 +331,39 @@ public static function albumDetails(string $albumId, string $language = 'en-US')
312331 $ url = null ;
313332 }
314333
334+ // albums tracks data
335+ $ tracksRaw = $ body ['data ' ][0 ]['relationships ' ]['tracks ' ]['data ' ] ?? [];
336+ $ tracks = array_map (function ($ t ) {
337+ $ a = $ t ['attributes ' ] ?? [];
338+ $ ms = $ a ['durationInMillis ' ] ?? null ;
339+ return [
340+ 'id ' => $ t ['id ' ] ?? null ,
341+ 'number ' => $ a ['trackNumber ' ] ?? null ,
342+ 'name ' => $ a ['name ' ] ?? '' ,
343+ 'durationMs ' => $ ms ,
344+ 'duration ' => self ::ms_to_mmss ($ ms ),
345+ ];
346+ }, $ tracksRaw );
347+
348+ // total duration
349+ $ totalDurationMs = array_sum (array_map (fn ($ t ) => $ t ['durationMs ' ] ?? 0 , $ tracks ));
350+ $ totalDuration = self ::ms_to_mmss ($ totalDurationMs );
351+
315352 return Response::json ([
316- 'id ' => $ id ,
317- 'name ' => $ a ['name ' ] ?? '' ,
318- 'artistName ' => $ a ['artistName ' ] ?? '' ,
319- 'albumName ' => $ a ['albumName ' ] ?? '' ,
320- 'genreNames ' => $ a ['genreNames ' ] ?? [],
321- 'releaseDate ' => $ releaseDate ,
322- 'releaseYear ' => $ releaseYear ,
323- 'url ' => $ url ,
324- 'duration ' => $ duration ,
325- 'image ' => $ img ,
326- 'raw ' => $ body , // optional: full response payload
353+ 'id ' => $ id ,
354+ 'name ' => $ a ['name ' ] ?? '' ,
355+ 'artistName ' => $ a ['artistName ' ] ?? '' ,
356+ 'genreNames ' => $ a ['genreNames ' ] ?? [],
357+ 'releaseDate ' => $ releaseDate ,
358+ 'releaseYear ' => $ releaseYear ,
359+ 'url ' => $ url ,
360+ 'image ' => $ img ,
361+ 'recordLabel ' => $ a ['recordLabel ' ],
362+ 'copyright ' => $ a ['copyright ' ],
363+ 'trackCount ' => $ a ['trackCount ' ],
364+ 'totalDuration ' => $ totalDuration ,
365+ 'tracks ' => $ tracks ,
366+ //'raw' => $body, // optional: full response payload
327367 ], 200 );
328368 }
329369
0 commit comments