[outputs] new output: RCP/Roku/SoundBridge devices

Roku SoundBridge devices can be treated as dumb speakers; they offer a
texted based protocol, RCP, that allows the server to request the Roku
device to connect to the server's stream.mp3 and provides ability to
control volume

Roku devices appear as speakers automatically via mDNS announcements on
the server _roku-rcp._tcp
This commit is contained in:
whatdoineed2do/Ray 2022-01-15 12:24:49 +00:00
parent a91d388fdf
commit 8f722faaf2
8 changed files with 1410 additions and 3 deletions

View File

@ -383,6 +383,23 @@ spotify {
# album_override = false # album_override = false
} }
# RCP/Roku Soundbridge output settings
# (make sure you get the capitalization of the device name right)
#rcp "My SoundBridge device" {
# Enable this option to exclude a particular device from the speaker
# list
# exclude = false
# A Roku/SoundBridge can power up in 2 modes: (default) reconnect to the
# previously used library (ie OwnTone) or in a 'cleared library' mode.
# The Roku power up behaviour is affected by how OwnTone disconnects
# from the Roku device.
#
# Set to false to maintain default Roku power on behaviour
# clear_on_close = false
#}
# MPD configuration (only have effect if MPD enabled - see README/INSTALL) # MPD configuration (only have effect if MPD enabled - see README/INSTALL)
mpd { mpd {
# TCP port to listen on for MPD client requests. # TCP port to listen on for MPD client requests.

View File

@ -125,7 +125,7 @@ owntone_SOURCES = main.c \
outputs/rtp_common.h outputs/rtp_common.c \ outputs/rtp_common.h outputs/rtp_common.c \
outputs/raop.c outputs/airplay.c $(PAIR_AP_SRC) \ outputs/raop.c outputs/airplay.c $(PAIR_AP_SRC) \
outputs/airplay_events.c outputs/airplay_events.h \ outputs/airplay_events.c outputs/airplay_events.h \
outputs/streaming.c outputs/dummy.c outputs/fifo.c \ outputs/streaming.c outputs/dummy.c outputs/fifo.c outputs/rcp.c \
$(ALSA_SRC) $(PULSEAUDIO_SRC) $(CHROMECAST_SRC) \ $(ALSA_SRC) $(PULSEAUDIO_SRC) $(CHROMECAST_SRC) \
evrtsp/rtsp.c evrtsp/evrtsp.h evrtsp/rtsp-internal.h evrtsp/log.h \ evrtsp/rtsp.c evrtsp/evrtsp.h evrtsp/rtsp-internal.h evrtsp/log.h \
$(SPOTIFY_SRC) $(LIBRESPOTC_SRC) $(LIBSPOTIFY_SRC) \ $(SPOTIFY_SRC) $(LIBRESPOTC_SRC) $(LIBSPOTIFY_SRC) \

View File

@ -186,6 +186,14 @@ static cfg_opt_t sec_fifo[] =
CFG_END() CFG_END()
}; };
/* RCP/Soundbridge section structure */
static cfg_opt_t sec_rcp[] =
{
CFG_BOOL("exclude", cfg_false, CFGF_NONE),
CFG_BOOL("clear_on_close", cfg_false, CFGF_NONE),
CFG_END()
};
/* Spotify section structure */ /* Spotify section structure */
static cfg_opt_t sec_spotify[] = static cfg_opt_t sec_spotify[] =
{ {
@ -243,6 +251,7 @@ static cfg_opt_t toplvl_cfg[] =
CFG_SEC("airplay", sec_airplay, CFGF_MULTI | CFGF_TITLE), CFG_SEC("airplay", sec_airplay, CFGF_MULTI | CFGF_TITLE),
CFG_SEC("chromecast", sec_chromecast, CFGF_MULTI | CFGF_TITLE), CFG_SEC("chromecast", sec_chromecast, CFGF_MULTI | CFGF_TITLE),
CFG_SEC("fifo", sec_fifo, CFGF_NONE), CFG_SEC("fifo", sec_fifo, CFGF_NONE),
CFG_SEC("rcp", sec_rcp, CFGF_MULTI | CFGF_TITLE),
CFG_SEC("spotify", sec_spotify, CFGF_NONE), CFG_SEC("spotify", sec_spotify, CFGF_NONE),
CFG_SEC("sqlite", sec_sqlite, CFGF_NONE), CFG_SEC("sqlite", sec_sqlite, CFGF_NONE),
CFG_SEC("mpd", sec_mpd, CFGF_NONE), CFG_SEC("mpd", sec_mpd, CFGF_NONE),

View File

@ -58,7 +58,7 @@ static uint32_t logger_repeat_counter;
static uint32_t logger_last_hash; static uint32_t logger_last_hash;
static char *logfilename; static char *logfilename;
static FILE *logfile; static FILE *logfile;
static char *labels[] = { "config", "daap", "db", "httpd", "http", "main", "mdns", "misc", "rsp", "scan", "xcode", "event", "remote", "dacp", "ffmpeg", "artwork", "player", "raop", "laudio", "dmap", "dbperf", "spotify", "lastfm", "cache", "mpd", "stream", "cast", "fifo", "lib", "web", "airplay" }; static char *labels[] = { "config", "daap", "db", "httpd", "http", "main", "mdns", "misc", "rsp", "scan", "xcode", "event", "remote", "dacp", "ffmpeg", "artwork", "player", "raop", "laudio", "dmap", "dbperf", "spotify", "lastfm", "cache", "mpd", "stream", "cast", "fifo", "lib", "web", "airplay", "rcp" };
static char *severities[] = { "FATAL", "LOG", "WARN", "INFO", "DEBUG", "SPAM" }; static char *severities[] = { "FATAL", "LOG", "WARN", "INFO", "DEBUG", "SPAM" };

View File

@ -37,8 +37,9 @@
#define L_LIB 28 #define L_LIB 28
#define L_WEB 29 #define L_WEB 29
#define L_AIRPLAY 30 #define L_AIRPLAY 30
#define L_RCP 31
#define N_LOGDOMAINS 31 #define N_LOGDOMAINS 32
/* Severities */ /* Severities */
#define E_FATAL 0 #define E_FATAL 0

View File

@ -44,6 +44,7 @@ extern struct output_definition output_airplay;
extern struct output_definition output_streaming; extern struct output_definition output_streaming;
extern struct output_definition output_dummy; extern struct output_definition output_dummy;
extern struct output_definition output_fifo; extern struct output_definition output_fifo;
extern struct output_definition output_rcp;
#ifdef HAVE_ALSA #ifdef HAVE_ALSA
extern struct output_definition output_alsa; extern struct output_definition output_alsa;
#endif #endif
@ -64,6 +65,7 @@ static struct output_definition *outputs[] = {
&output_streaming, &output_streaming,
&output_dummy, &output_dummy,
&output_fifo, &output_fifo,
&output_rcp,
#ifdef HAVE_ALSA #ifdef HAVE_ALSA
&output_alsa, &output_alsa,
#endif #endif

View File

@ -63,6 +63,7 @@ enum output_types
OUTPUT_TYPE_STREAMING, OUTPUT_TYPE_STREAMING,
OUTPUT_TYPE_DUMMY, OUTPUT_TYPE_DUMMY,
OUTPUT_TYPE_FIFO, OUTPUT_TYPE_FIFO,
OUTPUT_TYPE_RCP,
#ifdef HAVE_ALSA #ifdef HAVE_ALSA
OUTPUT_TYPE_ALSA, OUTPUT_TYPE_ALSA,
#endif #endif

1377
src/outputs/rcp.c Normal file

File diff suppressed because it is too large Load Diff