mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
Merge pull request #1622 from awiouy/librespot
librespot: initial addon
This commit is contained in:
commit
97fa217f54
@ -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
|
||||
}
|
@ -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="$ROOT/$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="$ROOT/$TOOLCHAIN/.cargo"
|
||||
export CARGO_TARGET_DIR="$ROOT/$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() {
|
||||
:
|
||||
}
|
2
packages/addons/service/librespot/changelog.txt
Normal file
2
packages/addons/service/librespot/changelog.txt
Normal file
@ -0,0 +1,2 @@
|
||||
100
|
||||
- Initial addon
|
BIN
packages/addons/service/librespot/icon/icon.png
Normal file
BIN
packages/addons/service/librespot/icon/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
64
packages/addons/service/librespot/package.mk
Normal file
64
packages/addons/service/librespot/package.mk
Normal 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 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() {
|
||||
. "$ROOT/$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/"
|
||||
}
|
@ -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;
|
@ -0,0 +1,48 @@
|
||||
diff -Naur librespot/src/audio_file.rs librespot.nocache/src/audio_file.rs
|
||||
--- librespot/src/audio_file.rs 2017-06-14 00:14:21.000000000 +0200
|
||||
+++ librespot.nocache/src/audio_file.rs 2017-06-20 00:35:14.060020000 +0200
|
||||
@@ -3,7 +3,7 @@
|
||||
use futures::Stream;
|
||||
use futures::sync::{oneshot, mpsc};
|
||||
use futures::{Poll, Async, Future};
|
||||
-use futures::future::{self, FutureResult};
|
||||
+use futures::future::FutureResult;
|
||||
use std::cmp::min;
|
||||
use std::fs;
|
||||
use std::io::{self, Read, Write, Seek, SeekFrom};
|
||||
@@ -129,15 +129,9 @@
|
||||
|
||||
impl AudioFileManager {
|
||||
pub fn open(&self, file_id: FileId) -> AudioFileOpen {
|
||||
- let cache = self.session().cache().cloned();
|
||||
-
|
||||
- if let Some(file) = cache.as_ref().and_then(|cache| cache.file(file_id)) {
|
||||
- debug!("File {} already in cache", file_id);
|
||||
- return AudioFileOpen::Cached(future::ok(file));
|
||||
- }
|
||||
-
|
||||
debug!("Downloading file {}", file_id);
|
||||
|
||||
+ #[allow(unused_variables)]
|
||||
let (complete_tx, complete_rx) = oneshot::channel();
|
||||
let (headers, data) = request_chunk(&self.session(), file_id, 0).split();
|
||||
|
||||
@@ -151,18 +145,6 @@
|
||||
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(()))
|
||||
- });
|
||||
-
|
||||
AudioFileOpen::Streaming(open)
|
||||
}
|
||||
}
|
99
packages/addons/service/librespot/source/bin/librespot.start
Executable file
99
packages/addons/service/librespot/source/bin/librespot.start
Executable file
@ -0,0 +1,99 @@
|
||||
#!/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 \
|
||||
$discovery \
|
||||
--name "Librespot@$HOSTNAME"
|
35
packages/addons/service/librespot/source/default.py
Normal file
35
packages/addons/service/librespot/source/default.py
Normal 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()
|
@ -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 ""
|
@ -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>
|
@ -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
|
39
packages/addons/service/librespot/source/wizard/wizard.py
Normal file
39
packages/addons/service/librespot/source/wizard/wizard.py
Normal 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
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user