How to play selected Track from Album with ApplicationMusicPlayer?

Hi 👋 I load a bunch of user's albums and when I select Album I load all related tracks there's a player to play all album and below list of all tracks that album contains.

To play the whole album when play button pressed

var selectedAlbum: Album

player.queue = [selectedAlbum]
try await player.play()

and then when I'd like to play specific track from the album in the List cell

var track: MusicItemCollection<Track>.Element

player.queue.currentEntry = .init(track)
try await player.play()

and it's not working.

Plus when trying to get selectedAlbum.copyright and selectedAlbum.editorialNotes?.standard always return empty String

Please let me know what's the issue with that and looking forward for helpful responses 🙏

Answered by snuff4 in 726214022

I wonder why you are not setting the queue directly instead of setting the current entry. Something like this:

player.queue = [track]
try await player.play()

Or if you want to start from a specific track from the album, you can do:

player.queue = ApplicationMusicPlayer.Queue(for: tracks, startingAt: track)

The code I used to test:

struct AlbumsView: View {
  @State private var albums: MusicItemCollection<Album> = []

  var body: some View {
    NavigationView {
      List {
        ForEach(albums) { album in
          NavigationLink(destination: AlbumView(album: album)) {
            Text(album.title)
          }
        }
      }
    }
    .task {
      do {
        if await MusicAuthorization.request() == .authorized {
          let request = MusicLibraryRequest<Album>()
          let response = try await request.response()
          albums = response.items
        }
      } catch {
        print(error)
      }
    }
  }
}

struct AlbumView: View {
  var album: Album

  @State private var tracks: MusicItemCollection<Track> = []
  @State private var player = ApplicationMusicPlayer.shared

  var body: some View {
    List {
      Button("Play album") {
        player.queue = [album]
      }

      ForEach(tracks) { track in
        Button(action: {
          player.queue = ApplicationMusicPlayer.Queue(for: tracks, startingAt: track)
          play()
        }) {
          Text(track.title)
        }
      }
    }
    .task {
      do {
        tracks = try await album.with(.tracks).tracks ?? []
      } catch {
        print(error)
      }
    }
  }

  private func play() {
    Task {
      do {
        try await player.play()
      } catch {
        print(error)
      }
    }
  }
}
Accepted Answer

I wonder why you are not setting the queue directly instead of setting the current entry. Something like this:

player.queue = [track]
try await player.play()

Or if you want to start from a specific track from the album, you can do:

player.queue = ApplicationMusicPlayer.Queue(for: tracks, startingAt: track)

The code I used to test:

struct AlbumsView: View {
  @State private var albums: MusicItemCollection<Album> = []

  var body: some View {
    NavigationView {
      List {
        ForEach(albums) { album in
          NavigationLink(destination: AlbumView(album: album)) {
            Text(album.title)
          }
        }
      }
    }
    .task {
      do {
        if await MusicAuthorization.request() == .authorized {
          let request = MusicLibraryRequest<Album>()
          let response = try await request.response()
          albums = response.items
        }
      } catch {
        print(error)
      }
    }
  }
}

struct AlbumView: View {
  var album: Album

  @State private var tracks: MusicItemCollection<Track> = []
  @State private var player = ApplicationMusicPlayer.shared

  var body: some View {
    List {
      Button("Play album") {
        player.queue = [album]
      }

      ForEach(tracks) { track in
        Button(action: {
          player.queue = ApplicationMusicPlayer.Queue(for: tracks, startingAt: track)
          play()
        }) {
          Text(track.title)
        }
      }
    }
    .task {
      do {
        tracks = try await album.with(.tracks).tracks ?? []
      } catch {
        print(error)
      }
    }
  }

  private func play() {
    Task {
      do {
        try await player.play()
      } catch {
        print(error)
      }
    }
  }
}
How to play selected Track from Album with ApplicationMusicPlayer?
 
 
Q