Skip to content
Snippets Groups Projects
musicPlayerState.dart 4.84 KiB
Newer Older
  • Learn to ignore specific revisions
  • import 'dart:async';
    
    import 'package:flutter/services.dart';
    import 'package:flutter/widgets.dart';
    import 'package:flutter_dotenv/flutter_dotenv.dart';
    import 'package:spotify_sdk/models/image_uri.dart';
    
    import 'package:spotify_sdk/models/player_state.dart';
    
    import 'package:spotify_sdk/spotify_sdk.dart';
    
    
    Erik Hinkelmanns's avatar
    Erik Hinkelmanns committed
    /// InheritedWidget that holds the state of your MusicPlayer
    /// the rebuild stream builds the hole body
    /// the playStatedStream only rebuild the Image, SongInfo and the ControlsButtons
    
    class MusicPlayerState extends InheritedWidget {
    
    Erik Hinkelmanns's avatar
    Erik Hinkelmanns committed
      MusicPlayerState({super.key, required super.child});
    
      StreamController<void> rebuildStream = StreamController.broadcast();
      StreamController<void> playStatedStream = StreamController.broadcast();
    
    Erik Hinkelmanns's avatar
    Erik Hinkelmanns committed
      Image? albumImage;
    
    
      static MusicPlayerState? maybeOf(BuildContext context) =>
          context.dependOnInheritedWidgetOfExactType<MusicPlayerState>();
    
      static MusicPlayerState of(BuildContext context) {
        final MusicPlayerState? result = maybeOf(context);
        assert(result != null, 'No PlayerState found in context');
        return result!;
      }
    
    
      void setLoading(bool loading) {
    
        rebuildStream.sink.add(null);
    
    Erik Hinkelmanns's avatar
    Erik Hinkelmanns committed
      /// will be called on PlayStateChange
      /// load new Imag e
    
      void updatePlayerState() async {
        playerState = await getPlayerState();
    
        loadAlbumImage().then((value) => playStatedStream.sink.add(null));
    
    Erik Hinkelmanns's avatar
    Erik Hinkelmanns committed
      ///disconnect your app from your local spotify app
    
      Future<void> disconnect() async {
        try {
          setLoading(true);
          var result = await SpotifySdk.disconnect();
          setStatus(result ? 'disconnect successful' : 'disconnect failed');
          setLoading(false);
        } on PlatformException catch (e) {
          setLoading(false);
          setStatus(e.code, message: e.message);
        } on MissingPluginException {
          setLoading(false);
          setStatus('not implemented');
        }
      }
    
    
    Erik Hinkelmanns's avatar
    Erik Hinkelmanns committed
      /// establish connection to local spotify app
      /// connection data will be loaded in main from dotenv.env
      /// if connection successful
      /// connection will be set to true and loading to false
    
      Future<bool> connectToSpotifyRemote() async {
    
        try {
          setLoading(true);
          var result = await SpotifySdk.connectToSpotifyRemote(
              clientId: dotenv.env['CLIENT_ID'].toString(),
              redirectUrl: dotenv.env['REDIRECT_URL'].toString());
          setStatus(result
              ? 'connect to spotify successful'
              : 'connect to spotify failed');
    
          if (result) {
    
            playerState = await getPlayerState();
    
        } on PlatformException catch (e) {
          setLoading(false);
          setStatus(e.code, message: e.message);
        } on MissingPluginException {
          setLoading(false);
          setStatus('not implemented');
        }
    
      Widget spotifyImageWidget(ImageUri imageUri) {
    
        return FutureBuilder(
            future: SpotifySdk.getImage(
    
              imageUri: imageUri,
    
              dimension: ImageDimension.large,
            ),
            builder: (BuildContext context, AsyncSnapshot<Uint8List?> snapshot) {
              if (snapshot.hasData) {
    
                albumImage = Image.memory(snapshot.data!);
    
    Erik Hinkelmanns's avatar
    Erik Hinkelmanns committed
                rebuildStream.sink.add(null);
                return const Center(child: Text('Getting image...'));
    
              } else if (snapshot.hasError) {
                setStatus(snapshot.error.toString());
                return SizedBox(
                  width: ImageDimension.small.value.toDouble(),
                  height: ImageDimension.small.value.toDouble(),
                  child: const Center(child: Text('Error getting image')),
                );
              } else {
                return SizedBox(
                  width: ImageDimension.small.value.toDouble(),
                  height: ImageDimension.small.value.toDouble(),
                  child: const Center(child: Text('Getting image...')),
                );
              }
            });
      }
    
    
    Erik Hinkelmanns's avatar
    Erik Hinkelmanns committed
    
      ///loads the Album image via spotify.sdk and saves the image in MusicPlayState
      ///for global access
    
      Future<void> loadAlbumImage() async {
        currentTrackImageUri = playerState?.track?.imageUri;
    
        albumImage = Image.memory((await SpotifySdk.getImage(
          imageUri: currentTrackImageUri!,
          dimension: ImageDimension.large,
        ))!);
    
      void setStatus(String code, {String? message}) {
        var text = message ?? '';
        print(text);
      }
    
    Erik Hinkelmanns's avatar
    Erik Hinkelmanns committed
      //get PlayState from local spotify app
    
      Future<PlayerState?> getPlayerState() async {
        try {
          return await SpotifySdk.getPlayerState();
        } on PlatformException catch (e) {
          setStatus(e.code, message: e.message);
        } on MissingPluginException {
          setStatus('not implemented');
        }
      }
    
      @override
      bool updateShouldNotify(covariant MusicPlayerState oldWidget) {
        return loading != oldWidget.loading && connected != oldWidget.connected;
      }
    }