Improve README and add screenshots
This commit is contained in:
159
README.md
159
README.md
@@ -1,52 +1,63 @@
|
|||||||
# BearWave for macOS
|
# BearWave for macOS
|
||||||
|
|
||||||
Native macOS 26 port of the Linux/KDE app BearWave.
|
Native macOS port of BearWave, focused on fast internet radio playback.
|
||||||
|
|
||||||
This repository is the current SwiftUI + AVFoundation version built as a
|
BearWave for macOS is a SwiftUI + AVFoundation desktop app built around the
|
||||||
SwiftPM app. The product scope is focused internet radio on macOS.
|
same product idea as the Linux version: quick station discovery, lightweight
|
||||||
|
playback, favorites, recents, and native desktop integration without turning
|
||||||
|
the app into a general-purpose audio suite.
|
||||||
|
|
||||||
## Current Scope
|
## Screenshots
|
||||||
|
|
||||||
- Radio Browser integration for Top, Germany, Netherlands, World, search, favorites, recents, and manual stations
|

|
||||||
- Native SwiftUI macOS UI with sidebar, list, detail panel, player bar, settings, and menu bar extra
|
|
||||||
- Station folders for organizing favorites and saved stations
|

|
||||||
- Stream playback through `AVPlayer`
|
|
||||||
- Playback states: connecting, buffering, playing, paused, stopped, failed
|

|
||||||
- Stream metadata display via `AVPlayerItemMetadataOutput`
|
|
||||||
- Station favicons/artwork with local disk cache
|
## Features
|
||||||
- Now Playing artwork resolution with fallback chain: metadata lookup, station favicon, app default artwork
|
|
||||||
|
- Native macOS 26 app built with SwiftUI
|
||||||
|
- Radio Browser integration
|
||||||
|
- Top, Germany, Netherlands, World, and Search Results pages
|
||||||
|
- Favorites, recents, and manual stations
|
||||||
|
- Station folders for organizing saved stations
|
||||||
|
- Menu bar controls
|
||||||
- Mini Player with `Cmd+M`
|
- Mini Player with `Cmd+M`
|
||||||
|
- Explicit playback states:
|
||||||
|
- connecting
|
||||||
|
- buffering
|
||||||
|
- playing
|
||||||
|
- paused
|
||||||
|
- stopped
|
||||||
|
- failed
|
||||||
|
- Stream metadata support through `AVPlayerItemMetadataOutput`
|
||||||
|
- Station artwork/favicon caching
|
||||||
|
- Resume last station on launch
|
||||||
|
- English and German localization
|
||||||
|
|
||||||
## Project Layout
|
## Product Direction
|
||||||
|
|
||||||
- `Package.swift`
|
This macOS version is intentionally **radio-first**.
|
||||||
SwiftPM package with:
|
|
||||||
- `BearWaveCore` shared app logic and resources
|
|
||||||
- `BearWave` app executable
|
|
||||||
- `BearWaveChecks` lightweight verification executable
|
|
||||||
- `Sources/BearWaveApp`
|
|
||||||
App entrypoint and scene setup
|
|
||||||
- `Sources/BearWaveCore`
|
|
||||||
App logic split into:
|
|
||||||
- `App/` high-level app coordinator (`AppModel.swift`)
|
|
||||||
- `Models/` domain models (`RadioStation`, `StationGroup`, `PlaybackStatus`, `PlaybackError`, `StationPage`)
|
|
||||||
- `Services/` Radio Browser client, playback controller, artwork loading, Now Playing artwork resolution
|
|
||||||
- `Stores/` persistence, settings, station library
|
|
||||||
- `Views/` SwiftUI UI (sidebar, list, detail, player bar, settings, menu bar, mini player)
|
|
||||||
- `Support/` resource helpers
|
|
||||||
- `Resources/` localized strings, assets, entitlements placeholder
|
|
||||||
- `Tests/BearWaveChecks`
|
|
||||||
Executable smoke checks for decoding, search normalization, filtering, and library behavior
|
|
||||||
- `script/build_and_run.sh`
|
|
||||||
Local build, bundle, and launch entrypoint
|
|
||||||
|
|
||||||
## Build and Run
|
That means:
|
||||||
|
- internet radio is the core product
|
||||||
|
- native macOS behavior is preferred over KDE/Qt parity
|
||||||
|
- podcast features are intentionally out of scope
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
swift build --disable-index-store
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the app bundle through the local staging script:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./script/build_and_run.sh
|
./script/build_and_run.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Useful modes:
|
Useful script modes:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./script/build_and_run.sh --verify
|
./script/build_and_run.sh --verify
|
||||||
@@ -55,66 +66,66 @@ Useful modes:
|
|||||||
./script/build_and_run.sh --telemetry
|
./script/build_and_run.sh --telemetry
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development Notes
|
Run the lightweight checks:
|
||||||
|
|
||||||
- Target platform is `macOS 26`
|
```bash
|
||||||
- Preferred workspace is:
|
CLANG_MODULE_CACHE_PATH=/private/tmp/bearwave-clang-cache swift run --disable-index-store BearWaveChecks
|
||||||
`/Users/sebastian/Development/radioappmac`
|
```
|
||||||
- Build with:
|
|
||||||
`swift build --disable-index-store`
|
|
||||||
- Lightweight verification:
|
|
||||||
`CLANG_MODULE_CACHE_PATH=/private/tmp/bearwave-clang-cache swift run --disable-index-store BearWaveChecks`
|
|
||||||
- The generated app bundle lives in:
|
|
||||||
`./dist/BearWave.app`
|
|
||||||
- The run script stages SwiftPM resource bundles and localization directories manually into the app bundle
|
|
||||||
|
|
||||||
## Playback and Metadata Notes
|
## Project Layout
|
||||||
|
|
||||||
- Audio playback uses `AVPlayer`
|
- `Package.swift`
|
||||||
- Stream metadata is read through `AVPlayerItemMetadataOutput`
|
SwiftPM package definition
|
||||||
- `PlaybackController` exposes explicit playback states instead of a simple play/pause boolean
|
- `Sources/BearWaveApp`
|
||||||
- Some radio streams provide current-song metadata; many do not
|
app entrypoint and scene wiring
|
||||||
- `MediaPlayer` is imported with `@preconcurrency` because the app updates `MPNowPlayingInfoCenter`
|
- `Sources/BearWaveCore`
|
||||||
- `MPMediaItemArtwork` is created from a stable `CGImage` request handler
|
shared app logic, models, stores, services, views, and resources
|
||||||
- ATS is explicitly opened for media and `http://` streams in the generated app `Info.plist`, otherwise many radio streams do not play
|
- `Tests/BearWaveChecks`
|
||||||
|
lightweight verification executable
|
||||||
|
- `script/build_and_run.sh`
|
||||||
|
local build, bundle, and launch script
|
||||||
|
- `screens/`
|
||||||
|
README screenshots
|
||||||
|
|
||||||
## Persistence
|
## Persistence
|
||||||
|
|
||||||
Data is stored under native macOS locations:
|
BearWave stores data under native macOS locations:
|
||||||
|
|
||||||
- `Application Support/BearWave/`
|
- `Application Support/BearWave/`
|
||||||
- `favorites.json`
|
- `favorites.json`
|
||||||
- `manual-stations.json`
|
- `manual-stations.json`
|
||||||
- `groups.json`
|
- `groups.json`
|
||||||
- `state.json`
|
- `state.json`
|
||||||
|
|
||||||
- `Caches/BearWave/`
|
- `Caches/BearWave/`
|
||||||
- `api_cache/`
|
- `api_cache/`
|
||||||
- artwork cache files
|
- artwork cache files
|
||||||
|
|
||||||
The app also tries to import old Linux-style files on first run if present:
|
On first run it can also import older Linux-style BearWave files when present:
|
||||||
|
|
||||||
- `~/.config/bearwave/favorites.json`
|
- `~/.config/bearwave/favorites.json`
|
||||||
- `~/.config/bearwave/state.json`
|
- `~/.config/bearwave/state.json`
|
||||||
|
|
||||||
## Current UX Behavior
|
## Current Status
|
||||||
|
|
||||||
- Search is global against Radio Browser and independent from the current browse page
|
Implemented and working:
|
||||||
- Search results appear on a dedicated `Search Results` page
|
- radio browsing and global search
|
||||||
- Search ranking intentionally filters naive mid-word matches such as `slam` matching `Islamabad`
|
- station playback
|
||||||
- A right-side detail panel shows station metadata and current stream metadata when available
|
- playback status reporting
|
||||||
- German localization is active across the app
|
- metadata display
|
||||||
|
- favorites, recents, manual stations
|
||||||
|
- station folders
|
||||||
|
- menu bar controls
|
||||||
|
- mini player
|
||||||
|
|
||||||
## Known Technical Edges
|
Still pragmatic rather than release-ready:
|
||||||
|
- SwiftPM-staged `.app` bundle
|
||||||
|
- debug-oriented signing and packaging
|
||||||
|
- custom app-bundle staging script
|
||||||
|
|
||||||
- The app is currently a SwiftPM-staged `.app`, not an Xcode-managed release app
|
## Roadmap
|
||||||
- Debug signing and sandbox behavior are intentionally pragmatic, not release-ready
|
|
||||||
- Resource handling is functional but still tied to the custom staging script
|
|
||||||
|
|
||||||
## Suggested Next Work
|
- improve release packaging, signing, and notarization
|
||||||
|
- expand playback diagnostics
|
||||||
- Improve packaging, signing, and notarization
|
- strengthen tests around playback state and search ranking
|
||||||
- Add more targeted playback diagnostics per stream failure mode
|
- refine cache management
|
||||||
- Expand tests around playback-state transitions and search ranking
|
- keep station folders lightweight and clearly radio-focused
|
||||||
- Add cache eviction for memory and disk caches
|
|
||||||
- Keep station folders lightweight and radio-focused
|
|
||||||
|
|||||||
BIN
screens/screen1.png
Normal file
BIN
screens/screen1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 413 KiB |
BIN
screens/screen2.png
Normal file
BIN
screens/screen2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 321 KiB |
BIN
screens/screen3.png
Normal file
BIN
screens/screen3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 330 KiB |
Reference in New Issue
Block a user