rinukkusu / spotify-dart

A dart library for interfacing with the Spotify API.
BSD 3-Clause "New" or "Revised" License
206 stars 92 forks source link

Playlist info, tracks and artists #179

Closed addreeh closed 10 months ago

addreeh commented 10 months ago

Is there anyway to get each track from the playlist one by one? And the artist and the name of the track? I have this code:

import 'package:flutter/material.dart';
import 'package:spotify/spotify.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const SecondPage(),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Page'),
      ),
      body: Column(
        children: [
          ElevatedButton(
              onPressed: () async {
                // OBTENER CANALES DEL USUARIO
                print("DENTRO");
                final credentials = SpotifyApiCredentials(
                    "",
                    "");
                var spotify = SpotifyApi(credentials);
                print("PLAYLIST");
                var playlist =
                    await spotify.playlists.get("0UNaot0tAdf4Oqa8L1hK88");

                var tracks = spotify.playlists
                    .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
                    .all;

                print(tracks);

                for (var i = 0; i < (playlist.tracks?.total ?? 0); i++) {}

// ...

                print("TOTAL CANCIONES ${playlist.tracks?.total ?? 0}");

                print(tracks);

                print(playlist.name);
                print(playlist.description);
                print(playlist.owner?.displayName);
                print(playlist.tracks?.itemsNative);
                print("TOTAL CANCIONES ${playlist.tracks?.total}");
                print("FOLLOWERS ${playlist.followers?.total}");
              },
              child: Text("MANOLO")),
          ElevatedButton(
            onPressed: () async {
              print("DENTRO");
              final credentials = SpotifyApiCredentials(
                  "",
                  "");
              var spotify = SpotifyApi(credentials);
              print("PLAYLIST");

              var tracks = await spotify.playlists
                  .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
                  .all(100);

              var cont = 0;
              // Imprimir información de cada pista
              for (var track in tracks) {
                try {
                  print(cont);
                  print(track.trackNumber);
                  print("ALBUM ${track.album?.name}");

                  print(track.artists);

                  print(track.durationMs);
                  print('Canción: ${track.name}');
                  cont++;
                } catch (Exception) {
                  print("CHEEEEEEEEEE");
                }
              }
            },
            child: Text("PEDRO"),
          ),
        ],
      ),
    );
  }
}

and its returns me some tracks, and some info:

I/flutter (28113): Canción: AYER
I/flutter (28113): 478
I/flutter (28113): 15
I/flutter (28113): ALBUM THE KINGTAPE
I/flutter (28113): [Instance of 'Artist', Instance of 'Artist']
I/flutter (28113): 221534
I/flutter (28113): Canción: Dos Días
I/flutter (28113): 479
I/flutter (28113): 1
I/flutter (28113): ALBUM Entre Nosotros (Mashup)
I/flutter (28113): [Instance of 'Artist']
I/flutter (28113): 345783
I/flutter (28113): Canción: Entre Nosotros - Mashup
E/flutter (28113): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'Map<String, dynamic>'
E/flutter (28113): #0      Playlists.getTracksByPlaylistId.<anonymous closure> (package:spotify/src/endpoints/playlists.dart:41:38)
E/flutter (28113): #1      MappedListIterable.elementAt (dart:_internal/iterable.dart:415:31)
E/flutter (28113): #2      ListIterator.moveNext (dart:_internal/iterable.dart:344:26)
E/flutter (28113): #3      ExpandIterator.moveNext (dart:_internal/iterable.dart:477:32)
E/flutter (28113): #4      SecondPage.build.<anonymous closure> (package:trackerfy/mierda.dart:79:33)
E/flutter (28113): <asynchronous suspension>

But it dont show all the tracks, the playlist has 700 tracks and it stopped at 479, also i dont know if is posible to get the artists and the album

addreeh commented 10 months ago

I updated my code to this:

import 'package:flutter/material.dart';
import 'package:spotify/spotify.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const SecondPage(),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Page'),
      ),
      body: Column(
        children: [
          ElevatedButton(
              onPressed: () async {
                // OBTENER CANALES DEL USUARIO
                print("DENTRO");
                final credentials = SpotifyApiCredentials(
                    "",
                    "");
                var spotify = SpotifyApi(credentials);
                print("PLAYLIST");
                var playlist =
                    await spotify.playlists.get("0UNaot0tAdf4Oqa8L1hK88");

                var tracks = spotify.playlists
                    .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
                    .all;

                print(tracks);

                for (var i = 0; i < (playlist.tracks?.total ?? 0); i++) {}

// ...

                print("TOTAL CANCIONES ${playlist.tracks?.total ?? 0}");

                print(tracks);

                print(playlist.name);
                print(playlist.description);
                print(playlist.owner?.displayName);
                print(playlist.tracks?.itemsNative);
                print("TOTAL CANCIONES ${playlist.tracks?.total}");
                print("FOLLOWERS ${playlist.followers?.total}");
              },
              child: Text("MANOLO")),
          ElevatedButton(
            onPressed: () async {
              print("DENTRO");
              final credentials = SpotifyApiCredentials(
                  "",
                  "");
              var spotify = SpotifyApi(credentials);
              print("PLAYLIST");

              // var tracks = await spotify.playlists
              //     .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
              //     .all(100);

              // var cont = 0;
              // // Imprimir información de cada pista
              // for (var track in tracks) {
              //   try {
              //     if (track != null) {
              //       print(cont);
              //       print(track.trackNumber);
              //       print("ALBUM ${track.album?.name}");

              //       // Recorrer los artistas
              //       if (track.artists != null) {
              //         for (var artist in track.artists!) {
              //           print("Artista: ${artist.name}");
              //           // Puedes acceder a otras propiedades del artista aquí
              //         }
              //       }

              //       print(track.durationMs);
              //       print('Canción: ${track.name}');
              //       cont++;
              //     } else {
              //       print("Pista nula encontrada en la posición $cont");
              //     }
              //   } finally {
              //     print("CHEEEEEEEEEE");
              //   }
              // }

              var offset = 0;
              var limit = 100;
              var cont = 0;
              while (true) {
                try {
                  var tracks = await spotify.playlists
                      .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
                      .getPage(limit, offset);
                  if (tracks != null) {
                    print(tracks);
                    print(tracks.nextOffset);
                    var all_tracks = [];
                    all_tracks.add(tracks.items);
                    print(all_tracks);
                    if (tracks.items != null) {
                      print(tracks.items!.first.name);
                      print(tracks.items!.last.name);
                      for (var track in tracks.items!) {
                        print("$cont, ${track.name}");
                        cont++;
                      }

                      offset += limit;
                    }
                  }
                } catch (e) {
                  print(e);
                  break;
                }
              }

              print("FUERA");
            },
            child: Text("PEDRO"),
          ),
        ],
      ),
    );
  }
}

but I still get this error:

I/flutter (29879): 393, 22:22
I/flutter (29879): 394, Otro Día Más (Remix)
I/flutter (29879): 395, WITHOUT YOU
I/flutter (29879): 396, Price Tag
I/flutter (29879): 397, Impossible
I/flutter (29879): 398, Him & I (with Halsey)
I/flutter (29879): 399, Know No Better (feat. Travis Scott & Quavo) [Bad Bunny Remix]
I/flutter (29879): 500
I/flutter (29879): Instance of 'Page<Track>'
I/flutter (29879): 500
I/flutter (29879): type 'Null' is not a subtype of type 'Map<String, dynamic>'
I/flutter (29879): FUERA
I/flutter (29879): 500
I/flutter (29879): Instance of 'Page<Track>'
I/flutter (29879): 500
I/flutter (29879): type 'Null' is not a subtype of type 'Map<String, dynamic>'
hayribakici commented 10 months ago

It seems that there is a json weirdness going on. Looks like that this library is expecting a json object, which does not exist. If you are able to paste your json, we could see where the error is.

addreeh commented 10 months ago

I dont have any json, I am only showing the tracks of a playlist but It gives me the error and not show allí the tracks of the playlist, the playlist has 700 songs and if you check the cont It stop at 400.

rinukkusu commented 10 months ago

Can you pinpoint on which line you get the error? It's a little hard to visually debug your code just with the log clues.

hayribakici commented 10 months ago

You can retrieve the json by pasting your playlist_id on this spotify website.

addreeh commented 10 months ago

Can you pinpoint on which line you get the error? It's a little hard to visually debug your code just with the log clues.

this is the code:


import 'package:flutter/material.dart';
import 'package:spotify/spotify.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const SecondPage(),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Page'),
      ),
      body: Column(
        children: [
          ElevatedButton(
              onPressed: () async {
                // OBTENER CANALES DEL USUARIO
                print("DENTRO");
                final credentials = SpotifyApiCredentials(
                    "c71ca5e3735c44d19f10161b88a5923c",
                    "c38cedd20e444629999786810c522790");
                var spotify = SpotifyApi(credentials);
                print("PLAYLIST");
                var playlist =
                    await spotify.playlists.get("0UNaot0tAdf4Oqa8L1hK88");

                var tracks = spotify.playlists
                    .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
                    .all;

                print(tracks);

                for (var i = 0; i < (playlist.tracks?.total ?? 0); i++) {}

// ...

                print("TOTAL CANCIONES ${playlist.tracks?.total ?? 0}");

                print(tracks);

                print(playlist.name);
                print(playlist.description);
                print(playlist.owner?.displayName);
                print(playlist.tracks?.itemsNative);
                print("TOTAL CANCIONES ${playlist.tracks?.total}");
                print("FOLLOWERS ${playlist.followers?.total}");
              },
              child: Text("MANOLO")),
          ElevatedButton(
            onPressed: () async {
              print("DENTRO");
              final credentials = SpotifyApiCredentials(
                  "c71ca5e3735c44d19f10161b88a5923c",
                  "c38cedd20e444629999786810c522790");
              var spotify = SpotifyApi(credentials);
              print("PLAYLIST");

              // var tracks = await spotify.playlists
              //     .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
              //     .all(100);

              // var cont = 0;
              // // Imprimir información de cada pista
              // for (var track in tracks) {
              //   try {
              //     if (track != null) {
              //       print(cont);
              //       print(track.trackNumber);
              //       print("ALBUM ${track.album?.name}");

              //       // Recorrer los artistas
              //       if (track.artists != null) {
              //         for (var artist in track.artists!) {
              //           print("Artista: ${artist.name}");
              //           // Puedes acceder a otras propiedades del artista aquí
              //         }
              //       }

              //       print(track.durationMs);
              //       print('Canción: ${track.name}');
              //       cont++;
              //     } else {
              //       print("Pista nula encontrada en la posición $cont");
              //     }
              //   } finally {
              //     print("CHEEEEEEEEEE");
              //   }
              // }

              var offset = 0;
              var limit = 100;
              var cont = 0;
              while (true) {
                try {
                  var tracks = await spotify.playlists
                      .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
                      .getPage(limit, offset);
                  if (tracks != null) {
                    print(tracks.nextOffset);
                    if (tracks.items != null) {
                      for (var track in tracks.items!) {
                        print("$cont, ${track.name}");
                        // Recorrer los artistas
                        if (track.artists != null) {
                          for (var artist in track.artists!) {
                            print("Artista: ${artist.name}");
                            // Puedes acceder a otras propiedades del artista aquí
                          }
                        }
                        cont++;
                      }

                      offset += limit;
                    }
                  } else {
                    print("PEDRO");
                  }
                } on Exception {
                  print("FALLO");
                }
              }

              print("FUERA");
            },
            child: Text("PEDRO"),
          ),
        ],
      ),
    );
  }
}

and this is the log:

477, AYER
Artista: Bhavi
Artista: LIT killah
478, Dos Días
Artista: ToteKing
Artista: Kaze
479, Entre Nosotros - Mashup
Artista: Saigo
Error: Expected a value of type 'Map<String, dynamic>', but got one of type 'Null'
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 294:49       throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 127:3        castError
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 742:12   cast
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart 660:14      as_C
packages/spotify/src/endpoints/playlists.dart 41:25                                <fn>
dart-sdk/lib/internal/iterable.dart 415:31                                         elementAt
dart-sdk/lib/internal/iterable.dart 344:26                                         moveNext
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 1080:20  next
packages/trackerfy/mierda.dart 116:32                                              <fn>
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50                 <fn>
dart-sdk/lib/async/zone.dart 1661:54                                               runUnary
dart-sdk/lib/async/future_impl.dart 156:18                                         handleValue
dart-sdk/lib/async/future_impl.dart 840:44                                         handleValueCallback
dart-sdk/lib/async/future_impl.dart 869:13                                         _propagateToListeners
dart-sdk/lib/async/future_impl.dart 641:5                                          [_completeWithValue]
dart-sdk/lib/async/future_impl.dart 715:7                                          callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                                   _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                                    _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:15                <fn>

It says that the error is in line 116, thats the line: for (var track in tracks.items!) {

addreeh commented 10 months ago

You can retrieve the json by pasting your playlist_id on this spotify website.

but how can i get all the tracks? i mean which limit and offset have i put? image the default values dont show all the tracks

hayribakici commented 10 months ago

It seems that the playlist json does not contain any tracks after a certain offset. But we need proof for this.

@addreeh I suggest to play around with the limit and offset values. So for example, set offset to 300 and beyond and and look for the track "Know No Better (feat. Travis Scott & Quavo) [Bad Bunny Remix]", since the error happens after this.

addreeh commented 10 months ago

I think that i found the error, i have in the playlist one episode, not a track, and I think that it is the issue, because I delete it from the playlist and the code dont fail, there are anyway to exlclude episodes from the var tracks? or is there any other correct way to recover a playlist?

import 'package:flutter/material.dart';
import 'package:spotify/spotify.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const SecondPage(),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Page'),
      ),
      body: Column(
        children: [
          ElevatedButton(
              onPressed: () async {
                // OBTENER CANALES DEL USUARIO
                print("DENTRO");
                final credentials = SpotifyApiCredentials(
                    "c71ca5e3735c44d19f10161b88a5923c",
                    "c38cedd20e444629999786810c522790");
                var spotify = SpotifyApi(credentials);
                print("PLAYLIST");
                var playlist =
                    await spotify.playlists.get("0UNaot0tAdf4Oqa8L1hK88");

                var tracks = spotify.playlists
                    .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
                    .all;

                print(tracks);

                for (var i = 0; i < (playlist.tracks?.total ?? 0); i++) {}

// ...

                print("TOTAL CANCIONES ${playlist.tracks?.total ?? 0}");

                print(tracks);

                print(playlist.name);
                print(playlist.description);
                print(playlist.owner?.displayName);
                print(playlist.tracks?.itemsNative);
                print("TOTAL CANCIONES ${playlist.tracks?.total}");
                print("FOLLOWERS ${playlist.followers?.total}");
              },
              child: Text("MANOLO")),
          ElevatedButton(
            onPressed: () async {
              print("DENTRO");
              final credentials = SpotifyApiCredentials(
                  "c71ca5e3735c44d19f10161b88a5923c",
                  "c38cedd20e444629999786810c522790");
              var spotify = SpotifyApi(credentials);
              print("PLAYLIST");

              // var tracks = await spotify.playlists
              //     .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
              //     .all(100);

              // var cont = 0;
              // // Imprimir información de cada pista
              // for (var track in tracks) {
              //   try {
              //     if (track != null) {
              //       print(cont);
              //       print(track.trackNumber);
              //       print("ALBUM ${track.album?.name}");

              //       // Recorrer los artistas
              //       if (track.artists != null) {
              //         for (var artist in track.artists!) {
              //           print("Artista: ${artist.name}");
              //           // Puedes acceder a otras propiedades del artista aquí
              //         }
              //       }

              //       print(track.durationMs);
              //       print('Canción: ${track.name}');
              //       cont++;
              //     } else {
              //       print("Pista nula encontrada en la posición $cont");
              //     }
              //   } finally {
              //     print("CHEEEEEEEEEE");
              //   }
              // }

              var offset = 0;
              var limit = 100;
              var cont = offset + 1;
              while (true) {
                try {
                  var tracks = await spotify.playlists
                      .getTracksByPlaylistId("0UNaot0tAdf4Oqa8L1hK88")
                      .getPage(limit, offset);
                  if (tracks != null) {
                    if (tracks.items != null) {
                      for (var track in tracks.items!) {
                        print("$cont, ${track.name}");
                        // Recorrer los artistas
                        if (track.artists != null) {
                          for (var artist in track.artists!) {
                            print("Artista: ${artist.name}");
                            // Puedes acceder a otras propiedades del artista aquí
                          }
                        }
                        cont++;
                      }

                      offset += limit;
                    }
                  } else {
                    print("PEDRO");
                  }
                } on Exception {
                  print("FALLO");
                }
              }

              print("FUERA");
            },
            child: Text("PEDRO"),
          ),
        ],
      ),
    );
  }
}
hayribakici commented 10 months ago

Okay, this is a bug. We only support tracks so far. Spotify provides a filter in which we can restrict the return types. Thank you for pointing this out! :) I will create another issue, that also allow episodes to be returned as well.