Merge pull request #1704 from awiouy/librespot-8

librespot: initial add-on
This commit is contained in:
Christian Hewitt 2017-06-23 12:00:25 +04:00 committed by GitHub
commit b3a5f43ce6
15 changed files with 771 additions and 1 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
################################################################################
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
}

View File

@ -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 <http://www.gnu.org/licenses/>.
################################################################################
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 <<EOF >"$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() {
:
}

View File

@ -0,0 +1,2 @@
100
- Initial addon

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -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 <http://www.gnu.org/licenses/>.
################################################################################
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/"
}

View File

@ -0,0 +1,222 @@
From a825f84d9d00b196232fcccc5b5e441654c4e5a0 Mon Sep 17 00:00:00 2001
From: shanemeagher <shanemeagher@outlook.com>
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<DiscoveryInner>);
struct DiscoveryInner {
@@ -202,7 +207,10 @@ impl NewService for Discovery {
pub struct DiscoveryStream {
credentials: mpsc::UnboundedReceiver<Credentials>,
+ #[cfg(feature = "with-rust-mdns")]
_svc: mdns::Service,
+ #[cfg(feature = "with-avahi")]
+ _svc: DNSService,
task: Box<Future<Item=(), Error=io::Error>>,
}
@@ -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;

View File

@ -0,0 +1,87 @@
From 031cc0a420db9d3ae8dd3543d07ff8503bdc508d Mon Sep 17 00:00:00 2001
From: Michael Herger <michael@herger.net>
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<String>,
pub onstop: Option<String>,
+ 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,
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
################################################################################
. /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"

View File

@ -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 <http://www.gnu.org/licenses/>.
################################################################################
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()

View File

@ -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 ""

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<settings>
<category label="30100" >
<setting label="30101" type="lsep" />
<setting label="30102" type="action" action="RunScript(/storage/.kodi/addons/service.librespot/wizard/wizard.py)" />
<setting label="30103" type="text" id="ls_o" default="" />
<setting label="30104" type="enum" id="pcm_3" lvalues="30105|30106|30107" visible="eq(-1,default:CARD=ALSA)|eq(-1,sysdefault:CARD=ALSA)" />
<setting label="30108" type="lsep" />
<setting label="30109" type="text" id="ls_u" />
<setting label="30110" type="text" id="ls_p" option="hidden" visible="!eq(-1,)" />
<setting label="30111" type="bool" id="ls_d" default="true" enable="false" visible="eq(-1,)|eq(-2,)" />
<setting label="30112" type="labelenum" id="ls_b" lvalues="30113|30114|30115|30116" />
</category>
</settings>

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>.
################################################################################
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

View File

@ -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"
}

View File

@ -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