{"id":31710404,"url":"https://github.com/programming-sai/seekbeat-ui","last_synced_at":"2026-05-16T17:40:37.226Z","repository":{"id":308417094,"uuid":"1032690364","full_name":"Programming-Sai/SeekBeat-UI","owner":"Programming-Sai","description":"Frontend for SeekBeat – a music streaming platform. Built with React Native for Web. Clean UI, responsive design, and offline-first behavior.","archived":false,"fork":false,"pushed_at":"2025-10-08T01:54:58.000Z","size":90872,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-08T03:31:42.687Z","etag":null,"topics":["eas","expo","frontend","fullstack","music","react-native-web","seekbeat","yt-dlp"],"latest_commit_sha":null,"homepage":"https://seekbeat.expo.app","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/Programming-Sai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2025-08-05T17:13:47.000Z","updated_at":"2025-09-23T15:27:13.000Z","dependencies_parsed_at":"2025-08-20T04:05:48.971Z","dependency_job_id":"a60570aa-dc87-4120-bf0a-09b8e7f5cc50","html_url":"https://github.com/Programming-Sai/SeekBeat-UI","commit_stats":null,"previous_names":["programming-sai/seekbeat-ui"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Programming-Sai/SeekBeat-UI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Programming-Sai%2FSeekBeat-UI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Programming-Sai%2FSeekBeat-UI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Programming-Sai%2FSeekBeat-UI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Programming-Sai%2FSeekBeat-UI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Programming-Sai","download_url":"https://codeload.github.com/Programming-Sai/SeekBeat-UI/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Programming-Sai%2FSeekBeat-UI/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000720,"owners_count":26082879,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["eas","expo","frontend","fullstack","music","react-native-web","seekbeat","yt-dlp"],"created_at":"2025-10-09T00:27:15.976Z","updated_at":"2025-10-09T00:27:17.477Z","avatar_url":"https://github.com/Programming-Sai.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://seekbeat.expo.app/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\n    \u003cimg\n      src=\"https://raw.githubusercontent.com/Programming-Sai/SeekBeat-UI/snapmock/output_laptop.png\"\n      srcset=\"\n        https://raw.githubusercontent.com/Programming-Sai/SeekBeat-UI/snapmock/output_mobile.png  767w,\n        https://raw.githubusercontent.com/Programming-Sai/SeekBeat-UI/snapmock/output_tablet.png 1023w,\n        https://raw.githubusercontent.com/Programming-Sai/SeekBeat-UI/snapmock/output_laptop.png 1280w\n      \"\n      sizes=\"(max-width: 767px) 100vw,\n             (max-width: 1023px) 80vw,\n             60vw\"\n      alt=\"SeekBeat Preview”\"\n      style=\"width:100%; height:auto;\"\n    /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# SeekBeat-UI\n\nFrontend for SeekBeat – a music streaming platform supporting both local library. Built with React Native for Web. Clean UI, responsive design, and offline-first behavior.\n\n## 📑 Table of Contents\n\n1. [Screenshots](#2-screenshots)\n2. [Overview / Motivation](#3-overview--motivation)\n3. [Architecture](#4-architecture-at-a-glance)\n4. [Key Features](#5-key-features)\n5. [Companion Backend](#6-companion-backend)\n6. [Quick Start (Frontend)](#7-quick-start-frontend)\n7. [Technical Highlights](#8-technical-highlights--lessons-learned)\n8. [Roadmap](#9-roadmap--future-ideas)\n\n---\n\n## 2. Screenshots\n\n### Desktop View\n\n| **Dark**                                     | **Light**                                      |\n| -------------------------------------------- | ---------------------------------------------- |\n| ![Home](/demo/home-desktop-dark.png)         | ![Desktop Home](/demo/home-desktop-light.png)  |\n| ![Settings](/demo/settings-desktop-dark.png) | ![ Settings](/demo/settings-desktop-light.png) |\n| ![Player](/demo/player-desktop-dark.png)     | ![Player](/demo/player-desktop-light.png)      |\n\n### Mobile View\n\n| Home                                       | Settings                                           | Player                                          |\n| ------------------------------------------ | -------------------------------------------------- | ----------------------------------------------- |\n| ![ Home Dark](/demo/home-mobile-dark.png)  | ![ Settings Dark](/demo/settings-mobile-dark.png)  | ![ Player Light](/demo/player-mobile-dark.png)  |\n| ![ Home Dark](/demo/home-mobile-light.png) | ![ Settings Dark](/demo/settings-mobile-light.png) | ![ Player Light](/demo/player-mobile-light.png) |\n\n---\n\n## 3. Overview / Motivation\n\n### Problem\n\nDuring a semester project, I surveyed classmates about how they discover and download music.  \nHere’s what stood out:\n\n| Pain Point               | Real User Quotes                                              |\n| ------------------------ | ------------------------------------------------------------- |\n| **Ads everywhere**       | “Multiple routing to different pages… and several ads.”       |\n| **Hard to download**     | “It’s too complex to download the songs to my local storage.” |\n| **Limited availability** | “I mostly don’t find the very music I intend looking for.”    |\n| **Locked features**      | “Some songs are for premium users.”                           |\n\nStudents mostly used **YouTube, Telegram, and Mp3Juice**—and _everyone_ wished for a **simple, direct way** to search and download music.\n\n### My Goal\n\nCreate a **clean, ad-free platform** that lets anyone:\n\n- 🔎 **Search** for music (YouTube API)\n- 🎧 **Stream** instantly\n- 💾 **Download** without jumping through shady links or pop-ups\n- 🌓 **Customize** the look (themes \u0026 colors) while staying responsive across devices\n\n### Why React Native for Web\n\nSeekBeat started as the **frontend for my Django backend**, but I chose **React Native Web** because:\n\n- I plan to reuse the **same codebase** for a future **mobile app** and **desktop client**.\n- It provides a **native-like experience** while staying web-deployable.\n\n### What Makes It Different\n\n- **User-hostable backend**: A packaged Django executable (SeekBeat Companion) lets anyone run the backend locally or tunnel it via ngrok.\n- **Dynamic backend URL**: Users can switch between a hosted API (for search) and their own companion server—no rebuild required.\n\n---\n\n## 4. Architecture at a Glance\n\nSeekBeat is built as a small, modular full-stack system designed for both local-first usage and web deployment. The goal is practical portability: a single frontend codebase (React Native for Web / Expo) that talks to a simple Django backend which can be run locally (packaged as a `.exe`) or hosted for search-only usage.\n\nKey points:\n\n- **Frontend:** React Native for Web (Expo), single codebase for web and future native/desktop clients. Uses built-in React Contexts for state, default stylesheet-based theming, and localStorage/session storage for persistence \u0026 splash handling.\n- **Backend:** Django + Django REST Framework, `yt-dlp` for extracting stream/download URLs, `mutagen` for ID3 injection. Packaged for end users via **PyInstaller** as a self-contained `.exe` for desktop use; also optionally deployed to a host for search-only features (cookies and YouTube auth make hosted streaming unreliable).\n- **Streaming:** Backend fetches direct stream URLs from YouTube or serves proxied streams for clients (supports HTTP range requests).\n- **Storage \u0026 Caching:** Music is not permanently stored on the hosted server—backend can cache transiently; frontend uses local storage for metadata, caches, and session flags.\n- **CI/CD \u0026 Releases:** GitHub Actions builds and publishes preview/production via EAS/Expo hosting; backend desktop builds are published as GitHub Releases (PyInstaller artifacts).\n\nBelow are two diagrams — a high-level flow and a more detailed integration map — that make the architecture concrete.\n\n```mermaid\nflowchart LR\n  subgraph ClientDevices\n    U[\"User Devices\n    (Phone / Desktop / Browser)\"]\n  end\n\n  Frontend[\"Frontend\n  React Native Web (Expo)\"]\n  BackendHosted[\"Hosted Backend\n  (Render) — Search only\"]\n  BackendLocal[\"Companion Backend (.exe)\n  (Django + yt-dlp)\"]\n  YouTube[\"YouTube / Upstream\"]\n  GitHub[\"GitHub Releases / CI\"]\n  Tunnel[\"Ngrok / Localtunnel\"]\n  Storage[\"Local Storage / Cache\"]\n\n  U --\u003e Frontend\n  Frontend --\u003e|REST / API| BackendHosted\n  Frontend --\u003e|REST / API| BackendLocal\n  BackendLocal --\u003e|\"yt-dlp / stream\"| YouTube\n  BackendHosted --\u003e|\"search fallback\"| YouTube\n  BackendLocal --\u003e Storage\n  Frontend --\u003e Storage\n  GitHub --\u003e|\"releases\"| BackendLocal\n  Tunnel -.-\u003e BackendLocal\n  U --\u003e|\"optional remote access\"| Tunnel\n\n```\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n```mermaid\nflowchart TD\n  User[\"User Device\"]\n  Browser[\"Web (Expo) / Mobile App\"]\n  Player[\"Audio Element / Player Context\"]\n  API[\"REST API endpoints: /api/search, /api/stream\"]\n  Backend[\"SeekBeat Companion\n  (Django + DRF)\"]\n  YTDL[\"yt-dlp + mutagen\"]\n  CI[\"GitHub Actions → EAS Preview/Prod\"]\n  Releases[\"GitHub Releases (.exe)\"]\n  Tunnel[\"ngrok / localtunnel\"]\n  Upstream[\"YouTube / CDN\"]\n  LocalCache[\"Frontend localStorage \u0026 Indexed cache\"]\n\n  User --\u003e Browser\n  Browser --\u003e Player\n  Browser --\u003e API\n  API --\u003e Backend\n  Backend --\u003e YTDL\n  YTDL --\u003e Upstream\n  Backend --\u003e LAN\n  Backend --\u003e|\"stream proxy\"| Browser\n  Backend --\u003e|\"range requests\"| Browser\n  Backend --\u003e LocalCache\n  Browser --\u003e LocalCache\n  CI --\u003e Releases\n  Tunnel --\u003e Backend\n\n```\n\n---\n\n## 5. Key Features\n\nSeekBeat is focused on giving users a clean, local-first music experience with practical editing, fast streaming, and robust UX features.\n\n- 🎧 **Real-time streaming** — Play YouTube-based audio quickly via direct stream URLs or via the companion backend proxy for maximum compatibility. Player includes full transport controls (play/pause/seek/skip).\n\n- ✂️ **On-the-fly editing \u0026 trimming** — Trim start/end, change playback speed and volume, and remove unwanted parts before streaming or downloading. Edits are applied server-side when producing downloadable files.\n\n- 💿 **Server-side downloads with metadata** — Request downloadable MP3 outputs created by the backend. Files are produced on-the-fly with embedded ID3 tags and cover art using `mutagen`.\n\n- 🎛️ **Playback shortcuts \u0026 UX parity** — Keyboard shortcuts that mimic YouTube’s playback keys (seek forward/back, play/pause, volume), giving power users a familiar control scheme.\n\n- 🎚️ **Player queue \u0026 prefetching** — Robust queue UI for managing playback order, plus intelligent prefetching of the next track for seamless gapless-like transitions and reduced startup latency.\n\n- 🗂️ **Download history \u0026 search history UIs** — Persistent download history (pending / in-progress / done / error states) and search history that make it easy to revisit recent activity. Frontend stores metadata locally so history survives reloads.\n\n- 📱 **Responsive UI / Single codebase** — Built with **React Native for Web (Expo)** so a single codebase supports desktop and mobile web. Uses React Contexts and local/session storage for state and splash handling.\n\n- 💾 **Self-hostable companion backend (.exe)** — Packaged with **PyInstaller** for easy desktop distribution. Running locally avoids cookie/auth issues that make hosted streaming unreliable. Optional tunneling (ngrok/localtunnel) enables remote phone access.\n\n- 🔁 **Simple REST API \u0026 auto docs** — Clean endpoints for search, stream and downloads (`/api/search`, `/api/stream/\u003cid\u003e`) with auto-generated DRF Spectacular docs to make integration simple.\n\n- ⚙️ **CI/CD \u0026 distribution** — GitHub Actions automates preview builds (EAS/Expo) and production deployments; backend executables are published via GitHub Releases for straightforward end-user consumption.\n\n- 🛡️ **Rate limiting (server-side protection)** — To protect resources and discourage abuse, the backend applies IP-based rate limiting on key endpoints. Example decorators used on the backend:\n  ```py\n  @ratelimit(key='ip', rate='25/m', block=True)  # search endpoint\n  @ratelimit(key='ip', rate='30/m', block=True)  # stream endpoint\n  ```\n\nThese limits ensure fair usage and help keep a single-hosted/desktop instance responsive under load.\n\n\u003e [!NOTE]\n\u003e Hosted search (Render) is reliable for discovery, but streaming and downloads are best run via the local companion executable because of YouTube cookie/auth constraints\n\n---\n\nGreat — here’s a polished, recruiter- and user-friendly **“Companion Backend”** section you can paste into the README. It covers download/run, quick dev build instructions, mobile/ngrok usage, testing the service, security notes, and release practices.\n\nPaste as-is and replace the `↳` placeholders with your real links where noted.\n\n---\n\n## 6. Companion Backend\n\n### What you get\n\n- A lightweight Django + DRF backend that uses `yt-dlp` to resolve streams and produce downloadable MP3s with ID3 metadata.\n- Packaged builds are published as release artifacts (Windows `.exe` available). macOS / Linux builds are available via the Releases page when published, or can be built from source.\n- The companion backend is intended for **local / LAN use**; use ngrok/localtunnel for optional remote access from a mobile device.\n\n### Quick start — Windows (prebuilt `.exe`)\n\n1. Download the latest release from:  \n   **Releases:**[ `https://github.com/Programming-Sai/SeekBeat/releases`](https://github.com/Programming-Sai/SeekBeat/releases)\n2. Double-click the downloaded `.exe`. A console window will open and the server will print a local URL, for example:\n\n```text\nServing on: [http://127.0.0.1:8000](http://127.0.0.1:8000)\nHost IP: 192.168.1.42\n```\n\n3. In the SeekBeat app (Settings → Backend URL) enter either:\n\n- `http://127.0.0.1:8000` (if running frontend on same machine), or\n- `http://192.168.x.x:8000` (if accessing from another device on the same LAN).\n\n### Quick start — Build \u0026 run from source (Python)\n\nIf you prefer to run from source or are on macOS/Linux:\n\n```bash\ngit clone https://github.com/Programming-Sai/SeekBeat.git\ncd SeekBeat\npython -m venv .seekbeat\nsource .venv/bin/activate   # on Windows: .venv\\Scripts\\activate\npip install -r requirements.txt\n# create .env / config if needed (see repo README)\npython manage.py migrate\npython manage.py runserver 0.0.0.0:8000\n```\n\n### Optional: expose to phone (ngrok / localtunnel)\n\nIf you want to use the backend from a phone outside your LAN:\n\n1. Install ngrok (`https://ngrok.com`) and run:\n\n   ```bash\n   ngrok http 8000\n   ```\n\n2. Copy the provided HTTPS URL (e.g. `https://abcd1234.ngrok-free.app`) and paste it into the app’s Backend URL.\n3. Note: free ngrok links expire after the tunnel stops. Also: when using ngrok you may need to send the special ngrok header from clients to bypass the ngrok browser warning (`ngrok-skip-browser-warning: true`). SeekBeat automatically adds that header when it detects an ngrok-style URL.\n\n### Security \u0026 privacy notes\n\n- The companion backend is intended for **personal / LAN use**. If you expose it publicly (ngrok or hosted), treat the public URL like any public service — don’t leak it, and be aware free ngrok URLs can be re-used and expire.\n- The hosted search server (Render) is provided for discovery only. Streaming and downloads work best via the local .exe because `yt-dlp` often requires local cookie/state or session handling which is fragile on public hosts.\n- The backend applies IP-based rate limiting on critical endpoints to prevent abuse (see Releases/README for decorators used).\n\n### Troubleshooting\n\n- **Server won’t start**: check for blocked ports or firewall. Confirm Python/venv if running from source.\n- **Cannot access from phone**: confirm you used the machine’s LAN IP (e.g. `192.168.x.x`) and that both devices are on the same Wi-Fi. Disable strict firewall rules if necessary.\n- **ngrok warnings**: temporary — copy the tunnel password if asked, or set the special header when doing automated API calls.\n- **Search works but stream/download fails**: this is expected for hosted deployments due to cookies/YouTube auth. Use the local .exe for full functionality.\n\n### Where to download \u0026 support\n\n- **Backend Releases:** [`https://github.com/Programming-Sai/SeekBeat/releases`](https://github.com/Programming-Sai/SeekBeat/releases)\n- For troubleshooting / issues see the backend repo’s README / Issues tab.\n\n---\n\n## 7. Quick Start (Frontend)\n\nRun the SeekBeat UI locally or deploy a web build in minutes.\n\n### 1️⃣ Clone \u0026 Install\n\n```bash\ngit clone https://github.com/Programming-Sai/SeekBeat-UI.git\ncd SeekBeat-UI\nnpm ci   # or npm install\n```\n\n### 2️⃣ Development\n\nStart the Expo dev server and open in a browser or the Expo Go mobile app:\n\n```bash\nnpm start         # interactive menu (choose web / android / ios)\nnpm run web       # web only\n```\n\n- For remote access (e.g. mobile data), expose your local backend with **ngrok** and paste the URL in **Settings → Set Backend Connection URL** inside the app.\n\n### 3️⃣ Production Builds\n\nThe project uses **EAS Deploy** for static web hosting.\n\n```bash\nnpm run build      # export static web build to /dist\nnpm run build:web  # deploy preview (EAS)\nnpm run build:prod # deploy production (EAS)\n```\n\n\u003e **Backend Reminder:**\n\u003e The frontend needs a running SeekBeat Companion backend for streaming \u0026 downloads.\n\u003e\n\u003e - Use the [hosted demo](https://seekbeat.onrender.com/) for _search only_, or\n\u003e - Download the [Companion Backend executable](https://cgithub.com/Programming-Sai/SeekBeat/releases) and run it locally for full functionality.\n\nThat’s it—no extra environment variables or auth required.\n\n---\n\n## 8. Technical Highlights / Lessons Learned\n\nEngineering decisions that made SeekBeat fast, flexible, and deployable:\n\n- **Efficient Streaming \u0026 Caching** – Used HTTP **range requests** so the player fetches only the needed audio chunks, reducing bandwidth and enabling smooth seeking.  \n  Added browser-level caching headers to avoid unnecessary re-downloads.\n- **Self-Contained Backend** – Packaged a Python **FastAPI** server into a single Windows **`.exe`** (via PyInstaller) so non-technical users can double-click and run a local host without Python installed.\n- **React Native Web Responsiveness** – Built the entire UI with **React Native primitives** and tuned layout logic for fluid resizing across desktop and mobile browsers (via Expo Web).  \n  Single codebase → multiple screen sizes.\n- **User Customization \u0026 Shortcuts** – Implemented **keyboard shortcuts** patterned after YouTube (play/pause, skip, volume) and added an **accent selector** + **theme switcher** for a personal touch.\n- **Playback Pipeline** – Added **player queue**, **download history**, and **search history** UIs; songs are **prefetched** while the current track plays to achieve nearly gapless playback.\n- **API Protection** – Applied IP-based **rate limits** (`25/m` search, `30/m` stream) to prevent abuse and keep backend resources predictable.\n\nThese solutions demonstrate practical experience in **media streaming**, **cross-platform frontends**, and **packaging Python for end-user distribution**.\n\n---\n\n## 9. Roadmap / Future Ideas\n\nWhere SeekBeat could go next:\n\n- **Playlist Management** – Create, edit, and share custom playlists.\n- **Offline Caching** – Save tracks for playback without an internet connection.\n- **Advanced Analytics** – Track listening patterns, top searches, and usage trends.\n- **Mobile Apps** – Package for Android/iOS once the core web experience is stable.\n- **Enhanced Editing Tools** – Waveform-based trimming and batch metadata editing.\n- **Social Features** – Optional user profiles or shared queues for collaborative sessions.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogramming-sai%2Fseekbeat-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprogramming-sai%2Fseekbeat-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogramming-sai%2Fseekbeat-ui/lists"}