Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shuffle like VLC App #6

Open
gOzaru opened this issue Sep 4, 2021 · 10 comments
Open

Shuffle like VLC App #6

gOzaru opened this issue Sep 4, 2021 · 10 comments

Comments

@gOzaru
Copy link

gOzaru commented Sep 4, 2021

Hello,
I found out that just_audio shuffle method only made a random indexes of current playlist for once only. Meanwhile, in VLC app, it doesn't work that way. If we press Shuffle inside the app, and press Next, then the next song will jump into another index. It doesn't change the order of playlist.

Is there anyone who knows how to implement shuffle to work like VLC app?
Any tips and guidance will be a great help.
Thanks.

@suragch
Copy link
Owner

suragch commented Sep 7, 2021

I recently saw this in the docs for ConcatenatingAudioSorce:

  /// Creates a [ConcatenatingAudioSorce] with the specified [children]. If
  /// [useLazyPreparation] is `true`, children will be loaded/buffered as late
  /// as possible before needed for playback (currently supported on Android
  /// only). When [AudioPlayer.shuffleModeEnabled] is `true`, [shuffleOrder]
  /// will be used to determine the playback order (defaulting to
  /// [DefaultShuffleOrder]).

Can you try setting shuffleOrder to see if that makes a difference?

@gOzaru
Copy link
Author

gOzaru commented Sep 9, 2021

@suragch
I didn't know how to put variable Random inside the ConcatenatingAudioSource since it gave me an error.

@gOzaru
Copy link
Author

gOzaru commented Sep 10, 2021

@suragch
I think the Shuffle method from just_audio works the same way VLC works. I think maybe the main problem is located in how to implement this and combine it with audio_service.
You can view my comment here.
#ryanheise/audio_service#774

I am gonna close this for now.
If I found the way, I will let you know.

@gOzaru gOzaru closed this as completed Sep 10, 2021
@suragch
Copy link
Owner

suragch commented Sep 10, 2021

I'm reopening this until I can fix the tutorial. Thank you for your comments.

@suragch suragch reopened this Sep 10, 2021
@gOzaru
Copy link
Author

gOzaru commented Sep 13, 2021

@suragch
If you find out a way to implement it in the latest audio_service, please let me know.
Thank you.

@gOzaru
Copy link
Author

gOzaru commented Sep 16, 2021

@suragch
Actually, ryanheise just updated the example_playlist.dart in audio_service 0.18.0 and he added Shuffle function with working Loop All. I wonder if you can implement it in your tutorial?
#ryanheise/audio_service#774

@gOzaru
Copy link
Author

gOzaru commented Sep 19, 2021

@suragch
If you want to learn the complete fixed of shuffle playlist with loop all are active based on above example, you can visit my repository below:
link

@gOzaru
Copy link
Author

gOzaru commented Sep 21, 2021

@suragch
Do you know how to convert these lines of code into PlaylistRepository like yours in the tutorial:

class MediaLibrary {
  static const albumsRootId = 'albums';

  final items = <String, List<MediaItem>>{
    AudioService.browsableRootId: const [MediaItem(id: albumsRootId, title: "Albums", playable: false)],
    albumsRootId: [
      MediaItem(    // <--- I need to include these MediaItem using a function like in PlaylistRepository
        id: 'https://s3.amazonaws.com/scifri-episodes/scifri20181123-episode.mp3',
        album: "Science Monday",
        title: "I can do it",
        artist: "Science Friday and WNYC Studios",
        duration: const Duration(milliseconds: 5739820),
        artUri: Uri.parse('https://media.wnyc.org/i/1400/1400/l/80/1/ScienceFriday_WNYCStudios_1400.jpg'),
      ),
    ],
  };
}

@gOzaru
Copy link
Author

gOzaru commented Sep 21, 2021

No need. I found this as the best solution:

class MediaLibrary {
  static const albumsRootId = 'albums';
  final audioHandler = getIt<AudioHandler>();
  int status = -1;
  late final Map<String, List<MediaItem>> items; // <-- I declared it here as late variable
  List<MediaItem> mediaItems = [];

  void init() async {
    await loadPlaylist();
  }

  Future<List<MediaItem>> loadPlaylist() async {
    final songRepository = getIt<PlaylistRepository>();
    final playlistData = await songRepository.fetchInitialPlaylist();

    audioHandler.queue.listen((playlist) async {
      int lengthX = playlist.length;
      if (lengthX > 0) {
        status = 1;
      } else if (lengthX == 0) {
        status = 0;
      }
    });

    if (status == 0) {
      mediaItems = playlistData
          .map((song) => MediaItem(
                id: song['id'],
                album: song['album'],
                title: song['title'],
                artist: song['artist'],
                extras: {'url': song['url']},
              ))
          .toList();

      items = {
        AudioService.browsableRootId: const [
          MediaItem(
            id: albumsRootId,
            title: "Albums",
            playable: false,
          ),
        ],
        albumsRootId: mediaItems,  //I added here the variable of List<MediaItem>, problem solved. 
      };

      audioHandler.updateQueue(mediaItems);

      log("List of all indexes in first mediaItems");
      for (int i = 0; i < mediaItems.length; i++) {
        log("[$i] ${mediaItems[i].title}");
      }
    } else if (status == 1) {
      mediaItems = playlistData
          .map((song) => MediaItem(
                id: song['id'],
                album: song['album'],
                title: song['title'],
                artist: song['artist'],
                extras: {'url': song['url']},
              ))
          .toList();

      items = {
        AudioService.browsableRootId: const [
          MediaItem(
            id: albumsRootId,
            title: "Albums",
            playable: false,
          ),
        ],
        albumsRootId: mediaItems,
      };

      audioHandler.updateQueue(mediaItems);

      log("List of all indexes in first mediaItems");
      for (int i = 0; i < mediaItems.length; i++) {
        log("[$i] ${mediaItems[i].title}");
      }
    }

    return mediaItems;
  }
}

@suragch
Copy link
Owner

suragch commented Sep 27, 2021

Thanks for all your comments. I'm still planning to update the tutorial but haven't gotten around to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants