Bose SoundTouch Toolkit

Documentation for controlling and preserving Bose SoundTouch devices

View the Project on GitHub gesellix/Bose-SoundTouch

Technical Proposal: External Service Provider Abstraction

This document outlines a strategy to refactor the SoundTouch Service’s content handling into a modular provider-based system.

1. Problem Statement

Currently, content handling for BMX (Bose Media Exchange) services like TuneIn or RadioBrowser is deeply intertwined with the HTTP handlers and XML models. Adding a new content provider (e.g., Local Media, Podcast RSS) requires modifying several files and duplicating boilerplate code for HTTP requests and error handling.

2. Proposed Architecture

2.1 The Provider Interface

We define a generic ContentProvider interface that abstracts away the source-specific logic (API calls, data parsing).

package provider

import "github.com/gesellix/bose-soundtouch/pkg/models"

type ContentProvider interface {
    // ID returns the unique identifier for this provider (e.g. "RADIO_BROWSER")
    ID() string

    // Resolve returns playback details for a given content identifier
    Resolve(id string) (*models.BmxPlaybackResponse, error)

    // Search allows finding content within this provider
    Search(query string) ([]models.ContentItem, error)
}

2.2 Provider Registry

A central registry in soundtouch-service manages the lifecycle and selection of providers.

type Registry struct {
    providers map[string]ContentProvider
}

func (r *Registry) Register(p ContentProvider) { ... }
func (r *Registry) Get(id string) ContentProvider { ... }

3. Implementation Plan

3.1 Phase 1: Modularize RadioBrowser

  1. Extract Logic: Move current RadioBrowser logic from bmx.go into a new package pkg/service/providers/radiobrowser.
  2. Add Failover: Implement the API Failover logic inspired by OpenCloudTouch.
    • Maintain a list of active RadioBrowser mirrors (e.g., de1.api.radio-browser.info, nl1.api.radio-browser.info).
    • Implement a round-robin or health-based selection strategy.
  3. Implements Interface: Ensure the new package satisfies the ContentProvider interface.

3.2 Phase 2: Refactor BMX Handlers

3.3 Phase 3: Dynamic Service Advertising

4. Benefits

5. Next Steps

  1. Refine the ContentProvider interface to include metadata (icons, user-friendly names).
  2. Create a prototype for the radiobrowser provider with failover support.