{"id":26493746,"url":"https://github.com/djleamen/scrozam","last_synced_at":"2026-04-02T17:25:57.140Z","repository":{"id":282977667,"uuid":"927533088","full_name":"djleamen/Scrozam","owner":"djleamen","description":"Scrozam! is a web application that detects songs using the ACRCloud API and scrobbles the identified tracks to a user's Last.fm account.","archived":false,"fork":false,"pushed_at":"2026-03-26T00:21:53.000Z","size":56974,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-03-26T22:35:20.337Z","etag":null,"topics":["api","lastfm","lastfm-api","music","scrobble","scrobbler"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/djleamen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"djleamen","patreon":"djleamen"}},"created_at":"2025-02-05T05:36:44.000Z","updated_at":"2026-03-26T00:21:55.000Z","dependencies_parsed_at":"2025-03-18T00:31:38.998Z","dependency_job_id":"c6a11ec0-da3f-465b-a8ee-cfc639098626","html_url":"https://github.com/djleamen/Scrozam","commit_stats":null,"previous_names":["djleamen/scrozam"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/djleamen/Scrozam","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djleamen%2FScrozam","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djleamen%2FScrozam/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djleamen%2FScrozam/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djleamen%2FScrozam/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djleamen","download_url":"https://codeload.github.com/djleamen/Scrozam/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djleamen%2FScrozam/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31311441,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","lastfm","lastfm-api","music","scrobble","scrobbler"],"created_at":"2025-03-20T09:56:59.265Z","updated_at":"2026-04-02T17:25:57.132Z","avatar_url":"https://github.com/djleamen.png","language":"JavaScript","funding_links":["https://github.com/sponsors/djleamen","https://patreon.com/djleamen"],"categories":[],"sub_categories":[],"readme":"# Scrozam!\n\n![Status](https://img.shields.io/badge/status-active-brightgreen)\n![Frontend](https://img.shields.io/badge/frontend-React-61DAFB?logo=react)\n![Backend](https://img.shields.io/badge/backend-Node.js-339933?logo=node.js)\n![ACRCloud API](https://img.shields.io/badge/API-ACRCloud-orange)\n![Last.fm](https://img.shields.io/badge/Integration-Last.fm-red)\n![Last Commit](https://img.shields.io/github/last-commit/djleamen/Scrozam)\n![Issues](https://img.shields.io/github/issues/djleamen/scrozam)\n\n*Scrozam!* is a web application that detects songs using the ACRCloud API and scrobbles the identified tracks to a user's Last.fm account.\n\n\u003cimg width=\"1512\" height=\"862\" alt=\"Screenshot 2026-02-26 at 10 11 48 PM\" src=\"https://github.com/user-attachments/assets/7622d50f-e76d-4864-a1ee-14a055d14a2f\" /\u003e\n\n## Features\n- **Google SSO** — sign in with your Google account; no password required.\n- **Last.fm OAuth** — connect your Last.fm account in-app; no manual session key steps.\n- Detects songs from audio input using ACRCloud.\n- Scrobbles detected tracks to Last.fm automatically.\n- Displays detected track information and album art.\n- Continuous listening mode for uninterrupted scrobbling.\n\n## Setup Instructions\n\n### Prerequisites\n- Node.js and npm installed on your machine.\n- ACRCloud and Last.fm API accounts.\n- A Google Cloud project with an OAuth 2.0 Web Client ID ([create one here](https://console.cloud.google.com/)).\n\n### Steps\n\n1. **Configure Google OAuth**\n   - Go to [Google Cloud Console](https://console.cloud.google.com/) → APIs \u0026 Services → Credentials.\n   - Create an **OAuth 2.0 Client ID** (Web application).\n   - Add `http://localhost:3001` to **Authorised JavaScript origins**.\n   - Copy the client ID for use in the frontend `.env`.\n\n2. **Add environment variables**\n\n   Create a `.env` file in the `backend` directory (see `backend/.env.example`):\n   ```env\n   ACR_URL=\"your_acrcloud_url\"\n   ACR_ACCESS_KEY=\"your_acr_access_key\"\n   ACR_SHARED=\"your_acr_shared_secret\"\n\n   LAST_API_KEY=\"your_lastfm_api_key\"\n   LAST_SHARED_SECRET=\"your_lastfm_shared_secret\"\n\n   SESSION_SECRET=\"any_random_string\"\n   FRONTEND_URL=\"http://localhost:3001\"\n   BACKEND_URL=\"http://localhost:3000\"\n   ```\n\n   Create a `.env` file in the `frontend` directory (see `frontend/.env.example`):\n   ```env\n   REACT_APP_GOOGLE_CLIENT_ID=\"your_google_oauth_client_id.apps.googleusercontent.com\"\n   ```\n\n3. **Configure your Last.fm app callback**\n   - In your [Last.fm API account settings](https://www.last.fm/api/accounts), set the callback URL to:\n     ```\n     http://localhost:3000/auth/lastfm/callback\n     ```\n\n4. **Start the backend server**\n   ```bash\n   cd backend\n   npm install\n   node app.js\n   ```\n\n5. **Start the frontend**\n   ```bash\n   cd frontend\n   npm install\n   npm start\n   ```\n   Type `y` if prompted to use port 3001.\n\n6. **Sign in**\n   - Open http://localhost:3001.\n   - Click **Sign in with Google**.\n   - After Google authentication, click **Connect Last.fm** and authorise Scrozam.\n   - You're now fully signed in and ready to scrobble.\n\n7. **Detect songs**\n   - Click **Start Listening** and play some music.\n   - The application will detect the song, display the track info and album art, and scrobble it to Last.fm.\n   - Enable **Continuous Listening Mode** to auto-detect song changes without stopping.\n\nSample backend output:\n```\nACRCloud Response: { ... }\nFull music data from ACRCloud: { ... }\nDetected Song -\u003e Title: Killah, Artist: Lady Gaga\n📀 Stored detected song in songStore: { title: 'Killah', artist: 'Lady Gaga' }\n🎨 Album art found for Lady Gaga - Killah\n🎧 Sending detected song to frontend: Killah - Lady Gaga\n🎵 Scrobbled successfully -\u003e Lady Gaga - Killah @ ...\n```\n\nTo avoid duplication, if the same song is detected you will see:\n```\n📭 No new song detected, returning null.\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eIt is normal to see the following when a song first switches:\u003c/summary\u003e\n\u003cbr\u003e\n\n```\nACRCloud Response: { status: { code: 1001, version: '1.0', msg: 'No result' } }\nNo result detected. Retrying...\n📭 No new song detected, returning null.\n```\n\nThe 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.\n\n\u003c/details\u003e\n\n---\n\n## Future Improvements\n\n- Add more detailed song information display (release year, genre, etc.).\n- Implement more robust error handling.\n- Information / history tab showing recent scrobbles.\n- Production deployment with HTTPS and persistent session storage.\n\n---\n\n## Additional Information\n\n### Project Structure\n\n```\nbackend/\n  app.js              — Express server, session \u0026 auth middleware\n  userStore.js        — In-memory user profiles \u0026 Last.fm session keys\n  songStore.js        — In-memory detected song state\n  routes/\n    auth.js           — Google SSO + Last.fm OAuth endpoints\n    detectSong.js     — ACRCloud song identification\n    detectedSong.js   — Detected song polling endpoint\n    scrobbleSong.js   — Last.fm scrobbling\n    albumArt.js       — Album art lookup + image proxy\nfrontend/\n  src/\n    App.js            — App shell (auth routing) + MainApp component\n    AuthContext.js    — React context for auth state\n    components/\n      LoginPage.js    — Google sign-in + Last.fm connect flow\ntesting/\n  send_post.py        — Manual testing scripts\n```\n\n### Authentication Flow\n\n1. User signs in with Google (ID token verified server-side via Google's tokeninfo endpoint).\n2. A server-side session is created (cookie-based, 7-day expiry).\n3. User connects their Last.fm account via OAuth — the session key is stored per-user in memory.\n4. All song detection, polling, and scrobbling routes require an active session. Scrobbling additionally requires a connected Last.fm account.\n\n### Development and Contribution\n\nFeel free to contribute by opening issues and submitting pull requests. Ensure you follow the project's coding guidelines and standards.\n\nReplace all placeholder values in your `.env` files with your actual API keys and secrets before running the application.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjleamen%2Fscrozam","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjleamen%2Fscrozam","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjleamen%2Fscrozam/lists"}