Based on the descriptions at - https://gist.github.com/rody64/98a59990ff60ea962cac72cbe93edf56 - https://github.com/thlucas1/homeassistantcomponent_soundtouchplus/discussions/37 Example usage: ``` go run ./cmd/soundtouch-cli --host 192.... source custom-radio --url https://stream.antenne.de/chillout/stream/aacp --service-url http://soundtouch.local:8000 Selecting custom radio stream from 192....:8090... URL: https://stream.antenne.de/chillout/stream/aacp Proxy: http://soundtouch.local:8000/bmx/custom/v1/playback/aHR0cHM6Ly9zdHJlYW0uYW50ZW5uZS5kZS9jaGlsbG91dC9zdHJlYW0vYWFjcA== ✓ Custom radio stream selected ``` Relates to https://github.com/gesellix/Bose-SoundTouch/issues/94
8.9 KiB
Content Selection Implementation Summary
This document summarizes the implementation of advanced content selection features for the Bose SoundTouch Go client, including full support for the LOCAL_INTERNET_RADIO streamUrl format and LOCAL_MUSIC/STORED_MUSIC content selection.
✅ Implementation Status: COMPLETE
All content selection features from the SoundTouch WebServices API Wiki are now fully implemented with comprehensive API methods, CLI commands, tests, and documentation.
🎯 Features Implemented
1. Core API Methods
SelectContentItem(contentItem *models.ContentItem) error
- Purpose: Generic method for selecting any content using a ContentItem directly
- Use Case: Maximum flexibility for complex content selection scenarios
- Validation: Ensures ContentItem is not nil and has a valid source
SelectLocalInternetRadio(location, sourceAccount, itemName, containerArt string) error
- Purpose: Select LOCAL_INTERNET_RADIO content with streamUrl format support
- Features:
- Direct stream URLs (e.g.,
https://stream.example.com/radio) - streamUrl proxy format (e.g.,
http://contentapi.gmuth.de/station.php?name=Station&streamUrl=ActualStream) - Automatic defaults for missing parameters
- Direct stream URLs (e.g.,
- Use Cases: Internet radio streams, proxy-based radio services
SelectLocalInternetRadio(location, ...) via soundtouch-service
- Purpose: Select custom radio stream via local
soundtouch-serviceproxy - Features:
- Flexible stream URL encoding (Base64 or URL-escaped)
- Dynamic generation of Bose-compatible playback JSON
- Seamless integration with existing
LOCAL_INTERNET_RADIOsource
- Use Case: Playing any internet radio URL without external proxy dependencies
SelectLocalMusic(location, sourceAccount, itemName, containerArt string) error
- Purpose: Select LOCAL_MUSIC content from SoundTouch App Media Server
- Requirements: SoundTouch App Media Server running on a computer
- Content Types: Albums, tracks, artists, playlists
- Validation: Requires both location and sourceAccount
SelectStoredMusic(location, sourceAccount, itemName, containerArt string) error
- Purpose: Select STORED_MUSIC content from UPnP/DLNA media servers
- Requirements: UPnP/DLNA media server (Windows Media Player, NAS, etc.)
- Content Types: NAS libraries, network music collections
- Validation: Requires both location and sourceAccount
2. CLI Commands
All API methods are exposed through comprehensive CLI commands:
soundtouch-cli source internet-radio
soundtouch-cli --host <device> source internet-radio \
--location "http://contentapi.gmuth.de/station.php?name=MyStation&streamUrl=https://stream.example.com/radio" \
--name "My Station" \
--artwork "https://example.com/art.png"
soundtouch-cli source custom-radio
soundtouch-cli --host <device> source custom-radio \
--url "https://stream.example.com/radio" \
--name "My Station" \
--artwork "https://example.com/art.png" \
--service-url "http://localhost:8080"
soundtouch-cli source local-music
soundtouch-cli --host <device> source local-music \
--location "album:983" \
--account "3f205110-4a57-4e91-810a-123456789012" \
--name "Welcome to the New"
soundtouch-cli source stored-music
soundtouch-cli --host <device> source stored-music \
--location "6_a2874b5d_4f83d999" \
--account "d09708a1-5953-44bc-a413-123456789012/0" \
--name "Christmas Album"
soundtouch-cli source content (Advanced)
soundtouch-cli --host <device> source content \
--source LOCAL_INTERNET_RADIO \
--location "https://stream.example.com/radio" \
--name "My Stream" \
--type stationurl \
--presetable
🧪 Test Coverage
Comprehensive test suites implemented for all new functionality:
Unit Tests
- TestClient_SelectContentItem: 5 test cases covering valid/invalid inputs
- TestClient_SelectLocalInternetRadio: 4 test cases including streamUrl format
- TestClient_SelectLocalMusic: 4 test cases with validation
- TestClient_SelectStoredMusic: 4 test cases with error handling
Test Coverage Summary
- ✅ Valid content selection scenarios
- ✅ streamUrl format validation
- ✅ Parameter validation and error handling
- ✅ Default value assignment
- ✅ HTTP request formatting verification
📚 Documentation
Updated Documentation
- CLI-REFERENCE.md: Added comprehensive CLI command examples
- Content Selection Example: New
/examples/content-selection/with working code - README Updates: Added streamUrl format examples
- API Documentation: Inline Go documentation for all methods
Example Code
Complete working example demonstrating:
- LOCAL_INTERNET_RADIO with streamUrl proxy format
- LOCAL_INTERNET_RADIO with direct streams
- LOCAL_MUSIC content selection
- STORED_MUSIC content selection
- Generic ContentItem usage
🔍 streamUrl Format Support
What is the streamUrl Format?
The streamUrl format uses a proxy server that accepts the actual stream URL as a parameter:
http://contentapi.gmuth.de/station.php?name=StationName&streamUrl=ActualStreamURL
Implementation Details
- Full Support: All streamUrl format URLs work seamlessly
- Example from Wiki: Exact implementation matches the wiki specification
- ContentItem Structure:
contentItem := &models.ContentItem{ Source: "LOCAL_INTERNET_RADIO", Type: "stationurl", Location: "http://contentapi.gmuth.de/station.php?name=Antenne%20Chillout&streamUrl=https://stream.antenne.de/chillout/stream/aacp", IsPresetable: false, ItemName: "Antenne Chillout", ContainerArt: "https://www.radio.net/300/antennechillout.png", }
🏗️ Architecture
Design Principles
- Consistency: All methods follow the same parameter patterns
- Flexibility:
SelectContentItem()allows maximum control - Convenience: Specific methods (
SelectLocalInternetRadio(), etc.) provide simpler interfaces - Validation: Comprehensive input validation with clear error messages
- Defaults: Sensible defaults when optional parameters are empty
ContentItem Construction
All convenience methods create properly structured ContentItem objects:
- Automatic
Typeassignment based on source IsPresetabledefaults totrue- Default
ItemNamewhen not provided - Proper source-specific validation
🎵 Related Features
Sibling Features (Also Implemented)
Based on the wiki structure, these related features are also supported:
- LOCAL_MUSIC: ✅ Fully implemented
- STORED_MUSIC: ✅ Fully implemented
- SPOTIFY: ✅ Previously implemented
- TUNEIN: ✅ Previously implemented
- BLUETOOTH: ✅ Previously implemented
- AIRPLAY: ✅ Previously implemented
📋 Usage Examples
API Usage
// streamUrl format
location := "http://contentapi.gmuth.de/station.php?name=MyStation&streamUrl=https://stream.example.com/radio"
err := client.SelectLocalInternetRadio(location, "", "My Station", "")
// Direct ContentItem
contentItem := &models.ContentItem{
Source: "LOCAL_INTERNET_RADIO",
Type: "stationurl",
Location: location,
ItemName: "My Station",
IsPresetable: true,
}
err := client.SelectContentItem(contentItem)
CLI Usage
# streamUrl format
soundtouch-cli --host 192.168.1.100 source internet-radio \
--location "http://contentapi.gmuth.de/station.php?name=MyStation&streamUrl=https://stream.example.com/radio" \
--name "My Station"
# Direct stream
soundtouch-cli --host 192.168.1.100 source internet-radio \
--location "https://stream.example.com/radio" \
--name "Direct Stream"
🔗 References
- SoundTouch WebServices API Wiki
- LOCAL_INTERNET_RADIO - streamUrl format
- LOCAL_MUSIC
- Content Selection Example
- CLI Reference
- Content Selection Example (Direct)
✅ Verification
This implementation has been verified to:
- ✅ Support exact wiki specification for streamUrl format
- ✅ Handle all LOCAL_INTERNET_RADIO, LOCAL_MUSIC, and STORED_MUSIC scenarios
- ✅ Pass comprehensive test suite
- ✅ Work with CLI commands
- ✅ Include complete documentation and examples
- ✅ Maintain backward compatibility
Status: 🎉 COMPLETE - All requested content selection features are fully implemented and ready for use!