Spotify Looper

february 23, 2026

A precision playback tool that empowers Spotify users to loop their favorite song segments and skip unwanted sections, elevating the standard listening experience.

Web · Mobile · Utility · UX Improvement · Spotify API · Audio Control

FlutterRiverpodSpotify SDKMaterial 3Web Auth

Spotify Looper

Spotify Looper

A cross-platform precision playback tool built with Flutter. Spotify Looper fills the gap Spotify has ignored for 20 years — millisecond-accurate A/B looping and automatic segment skipping on any track in your library. Runs on Android and the web from a single codebase.

The Problem

The official Spotify experience is passive by design. If you want to loop a 15-second guitar riff, repeat a specific chorus, or skip a 90-second spoken intro every time a track plays, you're stuck manually scrubbing an imprecise seek bar. Spotify has no native A/B looping, no persistent segment markers, and no automatic skip boundaries.

The Solution

Spotify Looper wraps the Spotify App Remote SDK (Android) and Web Playback SDK (web) to expose the precision controls Spotify keeps hidden. Set start and end markers to the millisecond, save them per-track, and let the app manage playback position automatically.

Prerequisites

  • Flutter 3.19 or higher — flutter --version
  • Dart 3.3 or higher (bundled with Flutter)
  • A Spotify Premium account — both SDKs require Premium for playback control
  • A Spotify Developer App — register one at developer.spotify.com/dashboard

Spotify Developer Setup

Before running the app, you must register it with Spotify:

  1. Go to developer.spotify.com/dashboard and click Create App.
  2. Fill in any name and description.
  3. Under Redirect URIs, add:
    • Web: http://localhost:8080/callback
    • Android debug: myapp://callback
  4. Under APIs Used, enable Spotify Web Playback SDK and Android SDK.
  5. Copy your Client ID — you'll need it next.

Configuration

Create a .env file in the project root:

env
SPOTIFY_CLIENT_ID=your_client_id_here
SPOTIFY_REDIRECT_URI_WEB=http://localhost:8080/callback
SPOTIFY_REDIRECT_URI_ANDROID=myapp://callback

The app reads these at build time via flutter_dotenv. Do not commit .env to version control.

Installation

bash
git clone https://github.com/Mic-360/spotify_looper.git
cd spotify_looper
flutter pub get
git clone https://github.com/Mic-360/spotify_looper.git
cd spotify_looper
flutter pub get

Running the App

Web

bash
flutter run -d chrome --web-port 8080
flutter run -d chrome --web-port 8080

The redirect URI must match exactly what you registered in the Spotify dashboard. localhost:8080 is the default.

Android (Debug)

Connect your Android device with USB debugging enabled:

bash
flutter run -d android
flutter run -d android

Android authentication uses a deep link callback (myapp://callback) handled automatically by the app_links package.

Production Builds

Web:

bash
flutter build web --release
# Output: build/web/ — deploy to Firebase Hosting, Vercel, etc.
flutter build web --release
# Output: build/web/ — deploy to Firebase Hosting, Vercel, etc.

Android APK:

bash
flutter build apk --release
# Output: build/app/outputs/flutter-apk/app-release.apk
flutter build apk --release
# Output: build/app/outputs/flutter-apk/app-release.apk

Android App Bundle (Play Store):

bash
flutter build appbundle --release
flutter build appbundle --release

How It Works

Authentication Flow

  1. User taps Connect with Spotify.
  2. The app opens the Spotify OAuth page in a web view.
  3. Spotify redirects back to the app's callback URI with an auth code.
  4. The app exchanges the code for access_token and refresh_token.
  5. Tokens are stored securely and refreshed automatically before expiry.

Setting a Loop

  1. Play any track through the Spotify Looper app.
  2. Tap Set Start at the moment you want the loop to begin.
  3. Tap Set End at the moment you want the loop to end.
  4. Toggle Loop ON — the app monitors playback position and auto-seeks back to the start point when it passes the end point.
  5. Markers persist per-track in local storage and restore the next time you play that track.

Progress Bar Behavior

The custom progress bar polls the Spotify SDK's playback state every 250ms. Start and end markers are rendered as draggable overlays on the bar for fine-grained visual adjustment.

Project Architecture

text
spotify_looper/
├── lib/
│   ├── main.dart
│   ├── providers/
│   │   ├── auth_provider.dart        # Riverpod: Spotify OAuth state
│   │   ├── playback_provider.dart    # Riverpod: current track + position
│   │   └── loop_provider.dart        # Riverpod: A/B marker state
│   ├── screens/
│   │   ├── home_screen.dart          # Main playback UI
│   │   └── login_screen.dart
│   ├── services/
│   │   ├── spotify_service.dart      # Web Playback + App Remote wrapper
│   │   └── storage_service.dart      # Persist markers per track ID
│   └── widgets/
│       ├── loop_progress_bar.dart    # Custom scrubber with A/B markers
│       └── album_theme_provider.dart # Material 3 dynamic color from album art
├── android/                          # Android App Remote SDK integration
└── web/                              # Spotify Web Playback SDK JS bridge
spotify_looper/
├── lib/
│   ├── main.dart
│   ├── providers/
│   │   ├── auth_provider.dart        # Riverpod: Spotify OAuth state
│   │   ├── playback_provider.dart    # Riverpod: current track + position
│   │   └── loop_provider.dart        # Riverpod: A/B marker state
│   ├── screens/
│   │   ├── home_screen.dart          # Main playback UI
│   │   └── login_screen.dart
│   ├── services/
│   │   ├── spotify_service.dart      # Web Playback + App Remote wrapper
│   │   └── storage_service.dart      # Persist markers per track ID
│   └── widgets/
│       ├── loop_progress_bar.dart    # Custom scrubber with A/B markers
│       └── album_theme_provider.dart # Material 3 dynamic color from album art
├── android/                          # Android App Remote SDK integration
└── web/                              # Spotify Web Playback SDK JS bridge

Known SDK Limitations

LimitationDetails
Spotify Premium requiredBoth SDKs require a Premium subscription to control playback programmatically
Web seek precisionThe Web Playback SDK is accurate to ~100ms; fine for looping in practice
Android seek resolutionThe App Remote SDK has ~500ms seek resolution — coarser than web
Browser background tabBrowser autoplay policies may pause the web player when the tab is backgrounded — a browser constraint, not a Flutter one

Live demo: spotify-looper-cc1ad.web.app · Source: github.com/Mic-360/spotify_looper

back to projects