diff --git a/packages/addons/addon-depends/librespot-depends/pyalsaaudio/package.mk b/packages/addons/addon-depends/librespot-depends/pyalsaaudio/package.mk new file mode 100644 index 0000000000..c0d21f1dd6 --- /dev/null +++ b/packages/addons/addon-depends/librespot-depends/pyalsaaudio/package.mk @@ -0,0 +1,38 @@ +################################################################################ +# This file is part of LibreELEC - https://libreelec.tv +# Copyright (C) 2017-present Team LibreELEC +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +PKG_NAME="pyalsaaudio" +PKG_VERSION="0.8.4" +PKG_LICENSE="PSF" +PKG_SITE="http://larsimmisch.github.io/pyalsaaudio/" +PKG_URL="https://files.pythonhosted.org/packages/source/${PKG_NAME:0:1}/$PKG_NAME/$PKG_NAME-$PKG_VERSION.tar.gz" +PKG_DEPENDS_TARGET="toolchain Python distutilscross:host alsa-lib" +PKG_LONGDESC="ALSA bindings" + +make_target() { + export LDSHARED="$CC -shared" + export PYTHONXCPREFIX="$SYSROOT_PREFIX/usr" + python setup.py build --cross-compile +} + +makeinstall_target() { + python setup.py install --root=$INSTALL --prefix=/usr + find $INSTALL/usr/lib -name "*.py" -exec rm -rf "{}" ";" + rm -rf $INSTALL/usr/lib/python*/site-packages/*.egg-info \ + $INSTALL/usr/lib/python*/site-packages/*/tests +} diff --git a/packages/addons/addon-depends/librespot-depends/rust/package.mk b/packages/addons/addon-depends/librespot-depends/rust/package.mk new file mode 100644 index 0000000000..aad308aca1 --- /dev/null +++ b/packages/addons/addon-depends/librespot-depends/rust/package.mk @@ -0,0 +1,81 @@ +################################################################################ +# This file is part of LibreELEC - https://libreelec.tv +# Copyright (C) 2017-present Team LibreELEC +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +PKG_NAME="rust" +PKG_VERSION="1.18.0" +PKG_ARCH="any" +PKG_LICENSE="MIT" +PKG_SITE="https://www.rust-lang.org" +PKG_URL="" +PKG_DEPENDS="toolchain" +PKG_SECTION="devel" +PKG_LONGDESC="Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety." +PKG_IS_ADDON="no" + +PKG_AUTORECONF="no" + +unpack() { + : +} + +configure_target() { + : +} + +make_target() { + export CARGO_HOME="$TOOLCHAIN/.cargo" + export RUSTUP_HOME="$CARGO_HOME" + export PATH="$CARGO_HOME/bin:$PATH" + rm -rf "$CARGO_HOME" + curl https://sh.rustup.rs -sSf | sh -s -- --no-modify-path -y + rustup default "$PKG_VERSION" + case "$TARGET_ARCH" in + aarch64) + RUST_TRIPLE="aarch64-unknown-linux-gnu" + ;; + arm) + RUST_TRIPLE="arm-unknown-linux-gnueabihf" + ;; + x86_64) + RUST_TRIPLE="x86_64-unknown-linux-gnu" + ;; + esac + if [ "$TARGET_ARCH" != "x86_64" ]; then + rustup target add "$RUST_TRIPLE" + fi + + cat <"$CARGO_HOME/config" +[target.$RUST_TRIPLE] +linker = "$CC" +EOF + + cat <<'EOF' >"$CARGO_HOME/env" +export CARGO_HOME="$TOOLCHAIN/.cargo" +export CARGO_TARGET_DIR="$PKG_BUILD/.$TARGET_NAME" +export PATH="$CARGO_HOME/bin:$PATH" +export RUSTUP_HOME="$CARGO_HOME" +mkdir -p "$CARGO_TARGET_DIR" +EOF + + echo "CARGO_BUILD=\"cargo build --release --target $RUST_TRIPLE\"" \ + >>"$CARGO_HOME/env" +} + +makeinstall_target() { + : +} diff --git a/packages/addons/service/librespot/changelog.txt b/packages/addons/service/librespot/changelog.txt new file mode 100644 index 0000000000..ffbebe8438 --- /dev/null +++ b/packages/addons/service/librespot/changelog.txt @@ -0,0 +1,2 @@ +100 +- Initial addon diff --git a/packages/addons/service/librespot/icon/icon.png b/packages/addons/service/librespot/icon/icon.png new file mode 100644 index 0000000000..1b9e5e8400 Binary files /dev/null and b/packages/addons/service/librespot/icon/icon.png differ diff --git a/packages/addons/service/librespot/package.mk b/packages/addons/service/librespot/package.mk new file mode 100644 index 0000000000..d954fe6880 --- /dev/null +++ b/packages/addons/service/librespot/package.mk @@ -0,0 +1,64 @@ +################################################################################ +# This file is part of LibreELEC - https://libreelec.tv +# Copyright (C) 2017-present Team LibreELEC +# Copyright (C) 2017 Shane Meagher (shanemeagher) +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +PKG_NAME="librespot" +PKG_VERSION="2259188" +PKG_REV="100" +PKG_ARCH="any" +PKG_LICENSE="prop." +PKG_SITE="https://github.com/plietar/$PKG_NAME/" +PKG_URL="https://github.com/plietar/$PKG_NAME/archive/$PKG_VERSION.zip" +PKG_DEPENDS_TARGET="toolchain avahi libvorbis pyalsaaudio rust" +PKG_SECTION="service" +PKG_LONGDESC="Librespot ($PKG_VERSION) plays Spotify through LibreELEC using the opensource librespot library using a Spotify app as a remote." +PKG_AUTORECONF="no" + +PKG_IS_ADDON="yes" +PKG_ADDON_NAME="Librespot" +PKG_ADDON_TYPE="xbmc.service" +PKG_MAINTAINER="Anton Voyl (awiouy)" + +configure_target() { + . "$TOOLCHAIN/.cargo/env" + export PKG_CONFIG_ALLOW_CROSS=0 + strip_lto +} + +make_target() { + cd src + $CARGO_BUILD --no-default-features --features "alsa-backend with-avahi" +} + +makeinstall_target() { + : +} + +addon() { + mkdir -p "$ADDON_BUILD/$PKG_ADDON_ID/bin" + cp "$PKG_BUILD/.$TARGET_NAME"/*/release/librespot \ + "$ADDON_BUILD/$PKG_ADDON_ID/bin" + + mkdir -p "$ADDON_BUILD/$PKG_ADDON_ID/lib" + cp "$(get_build_dir avahi)/avahi-compat-libdns_sd/.libs/libdns_sd.so.1" \ + "$ADDON_BUILD/$PKG_ADDON_ID/lib" + + mkdir -p "$ADDON_BUILD/$PKG_ADDON_ID/wizard" + cp "$(get_build_dir pyalsaaudio)/.install_pkg/usr/lib/python2.7/site-packages/alsaaudio.so" \ + "$ADDON_BUILD/$PKG_ADDON_ID/wizard/" +} diff --git a/packages/addons/service/librespot/patches/librespot-01_avahi.patch b/packages/addons/service/librespot/patches/librespot-01_avahi.patch new file mode 100644 index 0000000000..36d0ba66fb --- /dev/null +++ b/packages/addons/service/librespot/patches/librespot-01_avahi.patch @@ -0,0 +1,222 @@ +From a825f84d9d00b196232fcccc5b5e441654c4e5a0 Mon Sep 17 00:00:00 2001 +From: shanemeagher +Date: Fri, 9 Jun 2017 22:43:54 +0800 +Subject: [PATCH] Build librespot with avahi support for Discovery + +rust-mdns is still the default and can be specified explicitly with --with-rust-mdns switch. +Added --with-avahi switch to build librespot to use avahi for discovery using dns-sd package. +--- + Cargo.lock | 10 ++++++++++ + Cargo.toml | 7 +++++-- + contrib/Dockerfile | 3 +++ + contrib/docker-build-avahi.sh | 24 ++++++++++++++++++++++++ + src/authentication/discovery.rs | 27 ++++++++++++++++++++++++++- + src/lib.rs | 6 +++++- + 6 files changed, 73 insertions(+), 4 deletions(-) + create mode 100755 contrib/docker-build-avahi.sh + +diff --git a/Cargo.lock b/Cargo.lock +index 30fafca..eff0925 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -6,6 +6,7 @@ dependencies = [ + "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ++ "dns-sd 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +@@ -144,6 +145,15 @@ dependencies = [ + ] + + [[package]] ++name = "dns-sd" ++version = "0.1.3" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++dependencies = [ ++ "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ++ "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ++] ++ ++[[package]] + name = "dtoa" + version = "0.4.1" + source = "registry+https://github.com/rust-lang/crates.io-index" +diff --git a/Cargo.toml b/Cargo.toml +index 5d64719..c543e92 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -52,7 +52,8 @@ alsa = { git = "https://github.com/plietar/rust-alsa", optional = tru + portaudio-rs = { version = "0.3.0", optional = true } + libpulse-sys = { git = "https://github.com/astro/libpulse-sys", optional = true } + +-mdns = { git = "https://github.com/plietar/rust-mdns" } ++mdns = { git = "https://github.com/plietar/rust-mdns", optional = true } ++dns-sd = { version = "~0.1.3", optional = true } + + error-chain = { version = "0.9.0", default_features = false } + futures = "0.1.8" +@@ -71,8 +72,10 @@ portaudio-backend = ["portaudio-rs"] + pulseaudio-backend = ["libpulse-sys"] + + with-tremor = ["tremor"] ++with-rust-mdns = ["mdns"] ++with-avahi = ["dns-sd"] + +-default = ["portaudio-backend"] ++default = ["portaudio-backend","with-rust-mdns"] + + [package.metadata.deb] + maintainer = "nobody" +diff --git a/contrib/Dockerfile b/contrib/Dockerfile +index 68a39b7..f6aec14 100644 +--- a/contrib/Dockerfile ++++ b/contrib/Dockerfile +@@ -4,6 +4,8 @@ + # + # The resulting image can be used to build librespot for linux x86_64, armhf and armel. + # $ docker run -v /tmp/librespot-build:/build librespot-cross ++# To build librespot with avahi support ++# $ docker run -v /tmp/librespot-build:/build librespot-cross /src/contrib/docker-build-avahi.sh + # + # The compiled binaries will be located in /tmp/librespot-build + # +@@ -23,6 +25,7 @@ RUN apt-get update + + RUN apt-get install -y curl git build-essential crossbuild-essential-arm64 crossbuild-essential-armel crossbuild-essential-armhf crossbuild-essential-mipsel + RUN apt-get install -y libasound2-dev libasound2-dev:arm64 libasound2-dev:armel libasound2-dev:armhf libasound2-dev:mipsel ++RUN apt-get install -y libavahi-compat-libdnssd-dev libavahi-compat-libdnssd-dev:arm64 libavahi-compat-libdnssd-dev:armel libavahi-compat-libdnssd-dev:armhf libavahi-compat-libdnssd-dev:mipsel + + RUN curl https://sh.rustup.rs -sSf | sh -s -- -y + ENV PATH="/root/.cargo/bin/:${PATH}" +diff --git a/contrib/docker-build-avahi.sh b/contrib/docker-build-avahi.sh +new file mode 100755 +index 0000000..c25b248 +--- /dev/null ++++ b/contrib/docker-build-avahi.sh +@@ -0,0 +1,24 @@ ++#!/usr/bin/env bash ++set -eux ++ ++cargo build --release --no-default-features --features "alsa-backend with-avahi" ++cp /usr/lib/x86_64-linux-gnu/libdns_sd.so.1 /build/release ++ ++export PKG_CONFIG_ALLOW_CROSS=0 ++ ++export PKG_CONFIG_PATH=/usr/lib/aarch64-unknown-linux-gnu/pkgconfig ++cargo build --release --target aarch64-unknown-linux-gnu --no-default-features --features "alsa-backend with-avahi" ++cp /usr/lib/aarch64-linux-gnu/libdns_sd.so.1 /build/aarch64-unknown-linux-gnu/release ++ ++export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabi/pkgconfig ++cargo build --release --target arm-unknown-linux-gnueabi --no-default-features --features "alsa-backend with-avahi" ++cp /usr/lib/arm-linux-gnueabi/libdns_sd.so.1 /build/arm-unknown-linux-gnueabi/release ++ ++export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig ++cargo build --release --target arm-unknown-linux-gnueabihf --no-default-features --features "alsa-backend with-avahi" ++cp /usr/lib/arm-linux-gnueabihf/libdns_sd.so.1 /build/arm-unknown-linux-gnueabihf/release ++ ++export PKG_CONFIG_PATH=/usr/lib/mipsel-linux-gnu/pkgconfig ++cargo build --release --target mipsel-unknown-linux-gnu --no-default-features --features "alsa-backend with-avahi" ++cp /usr/libmipsel-linux-gnu/libdns_sd.so.1 /build/mipsel-unknown-linux-gnu/release ++ +diff --git a/src/authentication/discovery.rs b/src/authentication/discovery.rs +index 8c5b005..d385294 100644 +--- a/src/authentication/discovery.rs ++++ b/src/authentication/discovery.rs +@@ -7,7 +7,6 @@ use futures::sync::mpsc; + use futures::{Future, Stream, BoxFuture, Poll, Async}; + use hyper::server::{Service, NewService, Request, Response, Http}; + use hyper::{self, Get, Post, StatusCode}; +-use mdns; + use num_bigint::BigUint; + use rand; + use std::collections::BTreeMap; +@@ -20,6 +19,12 @@ use url; + use authentication::Credentials; + use util; + ++#[cfg(feature = "with-rust-mdns")] ++use mdns; ++ ++#[cfg(feature = "with-avahi")] ++use dns_sd::DNSService; ++ + #[derive(Clone)] + struct Discovery(Arc); + struct DiscoveryInner { +@@ -202,7 +207,10 @@ impl NewService for Discovery { + + pub struct DiscoveryStream { + credentials: mpsc::UnboundedReceiver, ++ #[cfg(feature = "with-rust-mdns")] + _svc: mdns::Service, ++ #[cfg(feature = "with-avahi")] ++ _svc: DNSService, + task: Box>, + } + +@@ -212,8 +220,13 @@ pub fn discovery(handle: &Handle, device_name: String, device_id: String) + let (discovery, creds_rx) = Discovery::new(device_name.clone(), device_id); + + let listener = TcpListener::bind(&"0.0.0.0:0".parse().unwrap(), handle)?; ++ ++ #[cfg(feature = "with-rust-mdns")] + let addr = listener.local_addr()?; + ++ #[cfg(feature = "with-avahi")] ++ let port = listener.local_addr().unwrap().port(); ++ + let http = Http::new(); + let handle_ = handle.clone(); + let task = Box::new(listener.incoming().for_each(move |(socket, addr)| { +@@ -221,13 +234,25 @@ pub fn discovery(handle: &Handle, device_name: String, device_id: String) + Ok(()) + })); + ++ #[cfg(feature = "with-rust-mdns")] + let responder = mdns::Responder::spawn(&handle)?; ++ ++ #[cfg(feature = "with-rust-mdns")] + let svc = responder.register( + "_spotify-connect._tcp".to_owned(), + device_name, + addr.port(), + &["VERSION=1.0", "CPath=/"]); + ++ #[cfg(feature = "with-avahi")] ++ let svc = DNSService::register(Some(&*device_name), ++ "_spotify-connect._tcp", ++ None, ++ None, ++ port, ++ &["VERSION=1.0", "CPath=/"]) ++ .unwrap(); ++ + Ok(DiscoveryStream { + credentials: creds_rx, + _svc: svc, +diff --git a/src/lib.rs b/src/lib.rs +index 2a50249..b1b77ef 100644 +--- a/src/lib.rs ++++ b/src/lib.rs +@@ -19,7 +19,6 @@ extern crate crypto; + extern crate getopts; + extern crate hyper; + extern crate linear_map; +-extern crate mdns; + extern crate num_bigint; + extern crate num_integer; + extern crate num_traits; +@@ -50,6 +49,11 @@ extern crate portaudio_rs; + #[cfg(feature = "libpulse-sys")] + extern crate libpulse_sys; + ++#[cfg(feature = "with-rust-mdns")] ++extern crate mdns; ++ ++#[cfg(feature = "with-avahi")] ++extern crate dns_sd; + + #[macro_use] mod component; + pub mod album_cover; diff --git a/packages/addons/service/librespot/patches/librespot-02_disable_audio_cache.patch b/packages/addons/service/librespot/patches/librespot-02_disable_audio_cache.patch new file mode 100644 index 0000000000..42502b0df3 --- /dev/null +++ b/packages/addons/service/librespot/patches/librespot-02_disable_audio_cache.patch @@ -0,0 +1,87 @@ +From 031cc0a420db9d3ae8dd3543d07ff8503bdc508d Mon Sep 17 00:00:00 2001 +From: Michael Herger +Date: Tue, 20 Jun 2017 12:31:55 +0200 +Subject: [PATCH] Add --disable-audio-cache startup parameter + +Disable caching of downloaded audio files at runtime. Comes in handy when running librespot on a small device with SD card or other small storage. +--- + src/audio_file.rs | 24 +++++++++++++----------- + src/main.rs | 2 ++ + src/session.rs | 2 ++ + 3 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/src/audio_file.rs b/src/audio_file.rs +index 369d5ca..d014ba2 100644 +--- a/src/audio_file.rs ++++ b/src/audio_file.rs +@@ -151,17 +151,19 @@ impl AudioFileManager { + complete_tx: Some(complete_tx), + }; + +- let session = self.session(); +- self.session().spawn(move |_| { +- complete_rx.map(move |mut file| { +- if let Some(cache) = session.cache() { +- cache.save_file(file_id, &mut file); +- debug!("File {} complete, saving to cache", file_id); +- } else { +- debug!("File {} complete", file_id); +- } +- }).or_else(|oneshot::Canceled| Ok(())) +- }); ++ if self.session().config().use_audio_cache { ++ let session = self.session(); ++ self.session().spawn(move |_| { ++ complete_rx.map(move |mut file| { ++ if let Some(cache) = session.cache() { ++ cache.save_file(file_id, &mut file); ++ debug!("File {} complete, saving to cache", file_id); ++ } else { ++ debug!("File {} complete", file_id); ++ } ++ }).or_else(|oneshot::Canceled| Ok(())) ++ }); ++ } + + AudioFileOpen::Streaming(open) + } +diff --git a/src/main.rs b/src/main.rs +index 38c57fd..8a31a44 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -86,6 +86,7 @@ struct Setup { + fn setup(args: &[String]) -> Setup { + let mut opts = getopts::Options::new(); + opts.optopt("c", "cache", "Path to a directory where files will be cached.", "CACHE") ++ .optflag("", "disable-audio-cache", "Disable caching of the audio data.") + .reqopt("n", "name", "Device name", "NAME") + .optopt("b", "bitrate", "Bitrate (96, 160 or 320). Defaults to 160", "BITRATE") + .optopt("", "onstart", "Run PROGRAM when playback is about to begin.", "PROGRAM") +@@ -152,6 +153,7 @@ fn setup(args: &[String]) -> Setup { + bitrate: bitrate, + onstart: matches.opt_str("onstart"), + onstop: matches.opt_str("onstop"), ++ use_audio_cache: !matches.opt_present("disable-audio-cache"), + }; + + let device = matches.opt_str("device"); +diff --git a/src/session.rs b/src/session.rs +index 86162bd..a5d397e 100644 +--- a/src/session.rs ++++ b/src/session.rs +@@ -49,6 +49,7 @@ pub struct Config { + pub bitrate: Bitrate, + pub onstart: Option, + pub onstop: Option, ++ pub use_audio_cache: bool, + } + + impl Default for Config { +@@ -60,6 +61,7 @@ impl Default for Config { + bitrate: Bitrate::Bitrate160, + onstart: None, + onstop: None, ++ use_audio_cache: true, + } + } + } diff --git a/packages/addons/service/librespot/source/bin/librespot.start b/packages/addons/service/librespot/source/bin/librespot.start new file mode 100755 index 0000000000..0d5aaed6b4 --- /dev/null +++ b/packages/addons/service/librespot/source/bin/librespot.start @@ -0,0 +1,100 @@ +#!/bin/sh +################################################################################ +# This file is part of LibreELEC - https://libreelec.tv +# Copyright (C) 2017-present Team LibreELEC +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +. /etc/os-release +. /etc/profile +oe_setup_addon service.librespot + +activate_card() { + if [ -e "/proc/asound/$1" ]; then + return + fi + case "$LIBREELEC_ARCH" in + RPi*.arm) + if [ "$1" = "ALSA" ]; then + dtparam audio=on + sleep 1 + fi + ;; + *) + echo "Unable to activate card $1 on $LIBREELEC_ARCH" + exit + ;; + esac +} + +if [ ! "$(cat /proc/asound/pcm 2> /dev/null)" ]; then + case "$LIBREELEC_ARCH" in + RPi*.arm) + activate_card "ALSA" + ;; + *) + echo "Unable to activate an audio interface on $LIBREELEC_ARCH" + exit + ;; + esac +fi + +case "$ls_o" in + *:CARD=*) + card="${ls_o##*:CARD=}" + card="${card%%,*}" + activate_card "$card" + index="$(readlink /proc/asound/$card)" + index="${index##*card}" + ;; + hw:*,*) + echo "The hw:d,s specification is unreliable, use device:CARD=card instead" + index="${ls_o##hw:}" + index="${index%%,*}" + card="card$index" + activate_card "$card" + ;; + *) + if [ -n "$ls_o" ]; then + echo "Unknown playback device specification $ls_o" + fi + ;; +esac + +if [ -n "$ls_b" -a "$ls_b" != "-" ]; then + bitrate="--bitrate $ls_b" +fi + +if [ -n "$ls_o" ]; then + device="--device $ls_o" +fi + +if [ -n "$ls_p" -a -n "$ls_u" ]; then + discovery="--disable-discovery --password $ls_p --username $ls_u" +fi + +case "$LIBREELEC_ARCH" in + RPi*.arm) + [ "$(readlink /proc/asound/ALSA)" == "card$index" ] && [ "$pcm_3" ] && + amixer -c "$index" cset name="PCM Playback Route" "$pcm_3" + ;; +esac + +librespot $bitrate \ + --cache "$ADDON_HOME/cache" \ + $device \ + --disable-audio-cache \ + $discovery \ + --name "Librespot@$HOSTNAME" diff --git a/packages/addons/service/librespot/source/default.py b/packages/addons/service/librespot/source/default.py new file mode 100644 index 0000000000..1388ab8636 --- /dev/null +++ b/packages/addons/service/librespot/source/default.py @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of LibreELEC - https://libreelec.tv +# Copyright (C) 2017-present Team LibreELEC +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +import subprocess +import xbmc +import xbmcaddon + + +class Monitor(xbmc.Monitor): + + def __init__(self, *args, **kwargs): + xbmc.Monitor.__init__(self) + self.id = xbmcaddon.Addon().getAddonInfo('id') + + def onSettingsChanged(self): + subprocess.call(['systemctl', 'restart', self.id]) + + +if __name__ == '__main__': + Monitor().waitForAbort() diff --git a/packages/addons/service/librespot/source/resources/language/English/strings.po b/packages/addons/service/librespot/source/resources/language/English/strings.po new file mode 100644 index 0000000000..02ec26527d --- /dev/null +++ b/packages/addons/service/librespot/source/resources/language/English/strings.po @@ -0,0 +1,72 @@ +# Kodi Media Center language file +# Addon Name: librespot +msgid "" +msgstr "" + +msgctxt "#30100" +msgid "Configuration" +msgstr "" + +msgctxt "#30101" +msgid "ALSA" +msgstr "" + +msgctxt "#30102" +msgid "Configuration wizard" +msgstr "" + +msgctxt "#30103" +msgid "Playback device" +msgstr "" + +msgctxt "#30104" +msgid "Playback route" +msgstr "" + +msgctxt "#30105" +msgid "auto detect" +msgstr "" + +msgctxt "#30106" +msgid "headphone jack" +msgstr "" + +msgctxt "#30107" +msgid "HDMI" +msgstr "" + +msgctxt "#30108" +msgid "Spotify" +msgstr "" + +msgctxt "#30109" +msgid "Username" +msgstr "" + +msgctxt "#30110" +msgid "Password" +msgstr "" + +msgctxt "#30111" +msgid "Discovery mode (set username and password to disable)" +msgstr "" + +msgctxt "#30112" +msgid "Bit rate" +msgstr "" + +msgctxt "#30113" +msgid "-" +msgstr "" + +msgctxt "#30114" +msgid "90" +msgstr "" + +msgctxt "#30115" +msgid "160" +msgstr "" + +msgctxt "#30116" +msgid "320" +msgstr "" diff --git a/packages/addons/service/librespot/source/resources/settings.xml b/packages/addons/service/librespot/source/resources/settings.xml new file mode 100644 index 0000000000..7292787476 --- /dev/null +++ b/packages/addons/service/librespot/source/resources/settings.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/addons/service/librespot/source/system.d/service.librespot.service b/packages/addons/service/librespot/source/system.d/service.librespot.service new file mode 100644 index 0000000000..3d34f79bc5 --- /dev/null +++ b/packages/addons/service/librespot/source/system.d/service.librespot.service @@ -0,0 +1,11 @@ +[Unit] +Description=librespot +After=network-online.target +Requires=network-online.target + +[Service] +ExecStart=/bin/sh /storage/.kodi/addons/service.librespot/bin/librespot.start +Restart=on-failure + +[Install] +WantedBy=kodi.target diff --git a/packages/addons/service/librespot/source/wizard/wizard.py b/packages/addons/service/librespot/source/wizard/wizard.py new file mode 100644 index 0000000000..585a4b92dc --- /dev/null +++ b/packages/addons/service/librespot/source/wizard/wizard.py @@ -0,0 +1,39 @@ +################################################################################ +# This file is part of LibreELEC - https://libreelec.tv +# Copyright (C) 2017-present Team LibreELEC +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +import alsaaudio as alsa +import xbmcaddon +import xbmcgui + +if __name__ == '__main__': + + addon = xbmcaddon.Addon('service.librespot') + dialog = xbmcgui.Dialog() + strings = addon.getLocalizedString + + while True: + pcms = alsa.pcms()[1:] + if len(pcms) == 0: + dialog.ok(strings(30211), strings(30212)) + break + pcmx = dialog.select(strings(30113), pcms) + if pcmx == -1: + break + pcm = pcms[pcmx] + addon.setSetting('ls_o', pcm) + break diff --git a/packages/audio/libvorbis/package.mk b/packages/audio/libvorbis/package.mk index 13be9c254c..91fb98aeb3 100644 --- a/packages/audio/libvorbis/package.mk +++ b/packages/audio/libvorbis/package.mk @@ -36,3 +36,7 @@ PKG_CONFIGURE_OPTS_TARGET="--enable-static --disable-shared \ --disable-oggtest \ --disable-docs \ --disable-examples" + +pre_configure_target() { + export CFLAGS="$CFLAGS -fPIC" +} diff --git a/packages/network/avahi/package.mk b/packages/network/avahi/package.mk index 9ee6d38b52..d66b8e1b34 100644 --- a/packages/network/avahi/package.mk +++ b/packages/network/avahi/package.mk @@ -67,7 +67,7 @@ PKG_CONFIGURE_OPTS_TARGET="py_cv_mod_gtk_=yes \ --disable-manpages \ --disable-xmltoman \ --disable-tests \ - --disable-compat-libdns_sd \ + --enable-compat-libdns_sd \ --disable-compat-howl \ --with-xml=expat \ --with-avahi-user=avahi \ @@ -101,6 +101,7 @@ post_makeinstall_target() { rm -f $INSTALL/usr/bin/avahi-bookmarks rm -f $INSTALL/usr/bin/avahi-publish* rm -f $INSTALL/usr/bin/avahi-resolve* + rm -f $INSTALL/usr/lib/libdns_sd* mkdir -p $INSTALL/usr/share/services cp -P $PKG_DIR/default.d/*.conf $INSTALL/usr/share/services