Scrozam! is a web application that detects songs using the ACRCloud API and scrobbles the identified tracks to a user's Last.fm account.
- Google SSO — sign in with your Google account; no password required.
- Last.fm OAuth — connect your Last.fm account in-app; no manual session key steps.
- Detects songs from audio input using ACRCloud.
- Scrobbles detected tracks to Last.fm automatically.
- Displays detected track information and album art.
- Continuous listening mode for uninterrupted scrobbling.
- Node.js and npm installed on your machine.
- ACRCloud and Last.fm API accounts.
- A Google Cloud project with an OAuth 2.0 Web Client ID (create one here).
-
Configure Google OAuth
- Go to Google Cloud Console → APIs & Services → Credentials.
- Create an OAuth 2.0 Client ID (Web application).
- Add
http://localhost:3001to Authorised JavaScript origins. - Copy the client ID for use in the frontend
.env.
-
Add environment variables
Create a
.envfile in thebackenddirectory (seebackend/.env.example):ACR_URL="your_acrcloud_url" ACR_ACCESS_KEY="your_acr_access_key" ACR_SHARED="your_acr_shared_secret" LAST_API_KEY="your_lastfm_api_key" LAST_SHARED_SECRET="your_lastfm_shared_secret" SESSION_SECRET="any_random_string" FRONTEND_URL="http://localhost:3001" BACKEND_URL="http://localhost:3000"
Create a
.envfile in thefrontenddirectory (seefrontend/.env.example):REACT_APP_GOOGLE_CLIENT_ID="your_google_oauth_client_id.apps.googleusercontent.com"
-
Configure your Last.fm app callback
- In your Last.fm API account settings, set the callback URL to:
http://localhost:3000/auth/lastfm/callback
- In your Last.fm API account settings, set the callback URL to:
-
Start the backend server
cd backend npm install node app.js -
Start the frontend
cd frontend npm install npm startType
yif prompted to use port 3001. -
Sign in
- Open http://localhost:3001.
- Click Sign in with Google.
- After Google authentication, click Connect Last.fm and authorise Scrozam.
- You're now fully signed in and ready to scrobble.
-
Detect songs
- Click Start Listening and play some music.
- The application will detect the song, display the track info and album art, and scrobble it to Last.fm.
- Enable Continuous Listening Mode to auto-detect song changes without stopping.
Sample backend output:
ACRCloud Response: { ... }
Full music data from ACRCloud: { ... }
Detected Song -> Title: Killah, Artist: Lady Gaga
📀 Stored detected song in songStore: { title: 'Killah', artist: 'Lady Gaga' }
🎨 Album art found for Lady Gaga - Killah
🎧 Sending detected song to frontend: Killah - Lady Gaga
🎵 Scrobbled successfully -> Lady Gaga - Killah @ ...
To avoid duplication, if the same song is detected you will see:
📭 No new song detected, returning null.
It is normal to see the following when a song first switches:
ACRCloud Response: { status: { code: 1001, version: '1.0', msg: 'No result' } }
No result detected. Retrying...
📭 No new song detected, returning null.
The song will update eventually, usually well before the midpoint of the current song. If it gets stuck in a No result loop, please open an issue.
- Add more detailed song information display (release year, genre, etc.).
- Implement more robust error handling.
- Information / history tab showing recent scrobbles.
- Production deployment with HTTPS and persistent session storage.
backend/
app.js — Express server, session & auth middleware
userStore.js — In-memory user profiles & Last.fm session keys
songStore.js — In-memory detected song state
routes/
auth.js — Google SSO + Last.fm OAuth endpoints
detectSong.js — ACRCloud song identification
detectedSong.js — Detected song polling endpoint
scrobbleSong.js — Last.fm scrobbling
albumArt.js — Album art lookup + image proxy
frontend/
src/
App.js — App shell (auth routing) + MainApp component
AuthContext.js — React context for auth state
components/
LoginPage.js — Google sign-in + Last.fm connect flow
testing/
send_post.py — Manual testing scripts
- User signs in with Google (ID token verified server-side via Google's tokeninfo endpoint).
- A server-side session is created (cookie-based, 7-day expiry).
- User connects their Last.fm account via OAuth — the session key is stored per-user in memory.
- All song detection, polling, and scrobbling routes require an active session. Scrobbling additionally requires a connected Last.fm account.
Feel free to contribute by opening issues and submitting pull requests. Ensure you follow the project's coding guidelines and standards.
Replace all placeholder values in your .env files with your actual API keys and secrets before running the application.