mirror of
https://github.com/LibreELEC/LibreELEC.tv
synced 2025-09-24 19:46:01 +07:00
Compare commits
343 Commits
a59b1b1600
...
9.1.002
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d676a82920 | ||
|
|
434b5dcd20 | ||
|
|
af21cb6650 | ||
|
|
e5204380fa | ||
|
|
a2c343813a | ||
|
|
6a0e35e8c4 | ||
|
|
838b7587c4 | ||
|
|
a5480b6fbb | ||
|
|
089293d1b1 | ||
|
|
60c0025939 | ||
|
|
d40e6da679 | ||
|
|
02781b9cbf | ||
|
|
2ae4537216 | ||
|
|
43e58805d7 | ||
|
|
212c181de6 | ||
|
|
f2340cbcc9 | ||
|
|
e25aee7b70 | ||
|
|
3d3548216e | ||
|
|
9a21fc75d9 | ||
|
|
66d3241701 | ||
|
|
224bbd25a8 | ||
|
|
0ebb14559d | ||
|
|
7b0de5b7f6 | ||
|
|
161b7d7942 | ||
|
|
1ebce4e7eb | ||
|
|
5a6715c5aa | ||
|
|
d93bd49a02 | ||
|
|
426ff4cb1f | ||
|
|
8fc217337c | ||
|
|
82f70d28c9 | ||
|
|
eaf81e7277 | ||
|
|
fc97f456dc | ||
|
|
8380877cf5 | ||
|
|
ff8c463b31 | ||
|
|
7d84fbe6fa | ||
|
|
cff7ea1ab8 | ||
|
|
e0dc24ea42 | ||
|
|
79b31b45fd | ||
|
|
341aa35c3c | ||
|
|
02601a2500 | ||
|
|
adbe82298a | ||
|
|
365faa110f | ||
|
|
f1614bbac7 | ||
|
|
e89045361a | ||
|
|
ff813fca35 | ||
|
|
3e1563cb68 | ||
|
|
b50aa11e7d | ||
|
|
05a8e96592 | ||
|
|
2caa3e3b8b | ||
|
|
ff815836c5 | ||
|
|
39a81f5182 | ||
|
|
e826e18033 | ||
|
|
a6bc84ddd3 | ||
|
|
f04ec17bed | ||
|
|
357615473e | ||
|
|
96d92948a7 | ||
|
|
28b122f38b | ||
|
|
1e68ced1fb | ||
|
|
8dbe022c96 | ||
|
|
c2a626cdb6 | ||
|
|
266954d8b0 | ||
|
|
94aa4aebf6 | ||
|
|
6536414a46 | ||
|
|
a4a45cb3ba | ||
|
|
8c216956fd | ||
|
|
2b95120495 | ||
|
|
e44dd201a7 | ||
|
|
69e818ad25 | ||
|
|
bf06da5c6b | ||
|
|
973b437725 | ||
|
|
5fd83ea792 | ||
|
|
78e9965676 | ||
|
|
8aad391e89 | ||
|
|
fd1a20ede9 | ||
|
|
5ae38dba9d | ||
|
|
1fb4d27773 | ||
|
|
84e70210df | ||
|
|
664cadb820 | ||
|
|
237ed098f2 | ||
|
|
f1ef2f099c | ||
|
|
8bf41b5646 | ||
|
|
285ff64f93 | ||
|
|
f51e242eb6 | ||
|
|
5f4af38bda | ||
|
|
15cf6edcda | ||
|
|
fad82f0e52 | ||
|
|
f999f5818e | ||
|
|
60541fc7a4 | ||
|
|
1da93cec4f | ||
|
|
5c211cf5d1 | ||
|
|
965be3346f | ||
|
|
d46852e00c | ||
|
|
8fc25d9216 | ||
|
|
bb6cb4a18c | ||
|
|
75104714e1 | ||
|
|
788419c782 | ||
|
|
30f1e06c23 | ||
|
|
5cd2c6e4c9 | ||
|
|
aba8d19930 | ||
|
|
27130e8aa1 | ||
|
|
c29f446179 | ||
|
|
87eb94dc15 | ||
|
|
e76f0a39c0 | ||
|
|
b26a38279d | ||
|
|
0644052754 | ||
|
|
7678359759 | ||
|
|
5a5768aa60 | ||
|
|
eb8a4720ae | ||
|
|
541d29df36 | ||
|
|
f8ebb2f97a | ||
|
|
bd95afbae4 | ||
|
|
4ba7e76c64 | ||
|
|
d7c2207b8a | ||
|
|
c4b17555e1 | ||
|
|
7562b1f433 | ||
|
|
1aebc8cbf5 | ||
|
|
6f8b63acfe | ||
|
|
331d203edf | ||
|
|
f63b7fba07 | ||
|
|
60e06a17a3 | ||
|
|
2a9c4bb5be | ||
|
|
3cf175b0b2 | ||
|
|
a4b0706441 | ||
|
|
240d6f7917 | ||
|
|
e8a8df3f00 | ||
|
|
92e234cb70 | ||
|
|
a5bdc03af1 | ||
|
|
8f3af234a2 | ||
|
|
e7e91da91c | ||
|
|
6a01a9db3b | ||
|
|
243ca122d3 | ||
|
|
e910fb0626 | ||
|
|
d64d3819b0 | ||
|
|
10050ae75e | ||
|
|
ca4b9da4c6 | ||
|
|
d41d3b9cc6 | ||
|
|
ab0021b78f | ||
|
|
a7004681fa | ||
|
|
c3cc72fe3c | ||
|
|
c7babb3620 | ||
|
|
fc72e5d751 | ||
|
|
68570a6588 | ||
|
|
3adcb6ca9b | ||
|
|
ba818a4e9c | ||
|
|
c010cd4852 | ||
|
|
06a4a58835 | ||
|
|
3365ab2af7 | ||
|
|
818afbc013 | ||
|
|
a8cffb1142 | ||
|
|
bdd90f6c23 | ||
|
|
4c7e6a19d2 | ||
|
|
67de716210 | ||
|
|
bde8334d50 | ||
|
|
edf491d1c1 | ||
|
|
40b068464b | ||
|
|
d7ca15cce3 | ||
|
|
1f64a8165d | ||
|
|
9917b60837 | ||
|
|
a94ed02bac | ||
|
|
12169b7387 | ||
|
|
23c75ecd68 | ||
|
|
4d65280e66 | ||
|
|
439d3ff31e | ||
|
|
5e495a2bd2 | ||
|
|
26b2b6317c | ||
|
|
df47b8be68 | ||
|
|
ce7b145f29 | ||
|
|
2d400f1239 | ||
|
|
8a7f1edad0 | ||
|
|
b6027210f5 | ||
|
|
113b2829ab | ||
|
|
0e2b1c616b | ||
|
|
0ef9bd02e5 | ||
|
|
b63c7cfe41 | ||
|
|
b4a9b00c60 | ||
|
|
5225394e95 | ||
|
|
8daa6cd4a2 | ||
|
|
bd66701ec9 | ||
|
|
1279115624 | ||
|
|
2d418f67cc | ||
|
|
934cb939f3 | ||
|
|
a032fbd82e | ||
|
|
2f3ef07ca5 | ||
|
|
dc44c45496 | ||
|
|
97c44d6185 | ||
|
|
8cb1faf75a | ||
|
|
1d18803bd6 | ||
|
|
0f9583da99 | ||
|
|
e748d109b4 | ||
|
|
95422fadf0 | ||
|
|
d7e956544a | ||
|
|
267a536c16 | ||
|
|
987f53ca59 | ||
|
|
a3f6e5a14a | ||
|
|
91594773df | ||
|
|
0019bbb7db | ||
|
|
1f360da59f | ||
|
|
42d2f83366 | ||
|
|
3c36022773 | ||
|
|
7bd39a17c5 | ||
|
|
f0b6c134bc | ||
|
|
68a053bf5d | ||
|
|
61e8300e84 | ||
|
|
a01d717b01 | ||
|
|
ef00cbec7a | ||
|
|
ba4d163046 | ||
|
|
d44512f065 | ||
|
|
644437a35c | ||
|
|
86a09910c8 | ||
|
|
324c9b9e91 | ||
|
|
18835008d7 | ||
|
|
424156e8c2 | ||
|
|
58652ed54f | ||
|
|
7fe797c21d | ||
|
|
8a44aff0ae | ||
|
|
b350409a87 | ||
|
|
02c26cf74c | ||
|
|
10ceab95eb | ||
|
|
19eab3c0b4 | ||
|
|
1de4183ac9 | ||
|
|
8468cb546d | ||
|
|
1ef9d61701 | ||
|
|
8b74db943e | ||
|
|
a25d0284bb | ||
|
|
6c35c7744d | ||
|
|
d015207763 | ||
|
|
309c06aa95 | ||
|
|
48454e8f09 | ||
|
|
dce3e3d9b2 | ||
|
|
bf92570214 | ||
|
|
f308199746 | ||
|
|
33a9e93a8b | ||
|
|
7e8d54b030 | ||
|
|
44e5a963ec | ||
|
|
84b141fb03 | ||
|
|
549631cc92 | ||
|
|
79faa669af | ||
|
|
ef314ac176 | ||
|
|
1994796f5f | ||
|
|
c5c03e9217 | ||
|
|
ae802aa241 | ||
|
|
45b4a7eaf9 | ||
|
|
2e82cb8bfe | ||
|
|
a8f0af8f9f | ||
|
|
b01294dfbd | ||
|
|
075cd80895 | ||
|
|
17402b185f | ||
|
|
ecfc4182fb | ||
|
|
997b403b4c | ||
|
|
b66f07ff23 | ||
|
|
3c407df2fc | ||
|
|
65b88d4550 | ||
|
|
5224281992 | ||
|
|
ed3f230d16 | ||
|
|
37fb055954 | ||
|
|
531c4785ec | ||
|
|
5897e8155e | ||
|
|
61ad04c423 | ||
|
|
10e8774143 | ||
|
|
0423b4c8b6 | ||
|
|
c01f524e80 | ||
|
|
89c4916d11 | ||
|
|
f25a4c7159 | ||
|
|
48bda22cbc | ||
|
|
43df7485f8 | ||
|
|
2c5d302d8e | ||
|
|
02cca7dc25 | ||
|
|
0127603ce4 | ||
|
|
78cb67eebf | ||
|
|
d7d0f551e2 | ||
|
|
6027f4759b | ||
|
|
076d6c901a | ||
|
|
a48dc02c2e | ||
|
|
2ab4c72852 | ||
|
|
b1ace294eb | ||
|
|
1e505759d7 | ||
|
|
2082afff78 | ||
|
|
fb0007845a | ||
|
|
d7fc0eb6f0 | ||
|
|
8bfb08e555 | ||
|
|
abc9d658a2 | ||
|
|
0e5401939e | ||
|
|
6e69cd582f | ||
|
|
54072e33c8 | ||
|
|
08c38cb59a | ||
|
|
235fb0c12b | ||
|
|
8ac3106fb6 | ||
|
|
5b5284cd6a | ||
|
|
08565fa0e3 | ||
|
|
0bd4793492 | ||
|
|
04b8036e32 | ||
|
|
0eb36d786b | ||
|
|
195c206669 | ||
|
|
fbf0c54b71 | ||
|
|
9a24528e3f | ||
|
|
775df5da16 | ||
|
|
7604df2686 | ||
|
|
17ab4518fd | ||
|
|
bb9f7fa623 | ||
|
|
c3e674ed7d | ||
|
|
5f777dcbe8 | ||
|
|
6400a8cb7e | ||
|
|
7aabe781cb | ||
|
|
5cdbdf0303 | ||
|
|
9d6a971612 | ||
|
|
dc1d83925e | ||
|
|
f8ec58745e | ||
|
|
85cb44de99 | ||
|
|
c10e761b0d | ||
|
|
6c8ab49eec | ||
|
|
9e9e6befb3 | ||
|
|
f470d833b7 | ||
|
|
06f48133bb | ||
|
|
8ebda35e84 | ||
|
|
4fb34fc66a | ||
|
|
26e3588d79 | ||
|
|
e50834fd82 | ||
|
|
0b13c7b6fe | ||
|
|
b96e205f14 | ||
|
|
7ae3eb5b10 | ||
|
|
9e39ce6f1c | ||
|
|
1122893a50 | ||
|
|
ffdd6878a3 | ||
|
|
4ef5e73ae6 | ||
|
|
69f3db483e | ||
|
|
2fb1df6623 | ||
|
|
6202251a6c | ||
|
|
caaf067615 | ||
|
|
18d9847829 | ||
|
|
505ccecbc8 | ||
|
|
50fc3b5569 | ||
|
|
8f4bdc77cc | ||
|
|
902f198d46 | ||
|
|
3d10ea2d16 | ||
|
|
0f73329ce0 | ||
|
|
1fd115b699 | ||
|
|
58fc3e7ea9 | ||
|
|
c0ed05c6f6 | ||
|
|
ca952e8937 | ||
|
|
08c06b05cf | ||
|
|
284432cf4f | ||
|
|
c502b14ce6 | ||
|
|
707655ced2 |
19
Makefile
19
Makefile
@@ -14,25 +14,6 @@ image:
|
|||||||
noobs:
|
noobs:
|
||||||
./scripts/image noobs
|
./scripts/image noobs
|
||||||
|
|
||||||
amlpkg:
|
|
||||||
./scripts/image amlpkg
|
|
||||||
|
|
||||||
# legacy sequential build targets
|
|
||||||
system-st:
|
|
||||||
./scripts/image_st
|
|
||||||
|
|
||||||
release-st:
|
|
||||||
./scripts/image_st release
|
|
||||||
|
|
||||||
image-st:
|
|
||||||
./scripts/image_st mkimage
|
|
||||||
|
|
||||||
noobs-st:
|
|
||||||
./scripts/image_st noobs
|
|
||||||
|
|
||||||
amlpkg-st:
|
|
||||||
./scripts/image_st amlpkg
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIRS)/* $(BUILD_DIRS)/.stamps
|
rm -rf $(BUILD_DIRS)/* $(BUILD_DIRS)/.stamps
|
||||||
|
|
||||||
|
|||||||
@@ -357,11 +357,9 @@ setup_toolchain() {
|
|||||||
create_meson_conf() {
|
create_meson_conf() {
|
||||||
local endian root properties
|
local endian root properties
|
||||||
case "$1" in
|
case "$1" in
|
||||||
target|init) endian="little"
|
target|init) root="$SYSROOT_PREFIX/usr"
|
||||||
root="$SYSROOT_PREFIX/usr"
|
|
||||||
;;
|
;;
|
||||||
host|bootstrap) endian="big"
|
host|bootstrap) root="$TOOLCHAIN"
|
||||||
root="$TOOLCHAIN"
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -380,12 +378,14 @@ llvm-config = '$SYSROOT_PREFIX/usr/bin/llvm-config-host'
|
|||||||
system = 'linux'
|
system = 'linux'
|
||||||
cpu_family = '$TARGET_ARCH'
|
cpu_family = '$TARGET_ARCH'
|
||||||
cpu = '$TARGET_SUBARCH'
|
cpu = '$TARGET_SUBARCH'
|
||||||
endian = '$endian'
|
endian = 'little'
|
||||||
|
|
||||||
[properties]
|
[properties]
|
||||||
root = '$root'
|
root = '$root'
|
||||||
$(python -c "import os; print('c_args = {}'.format([x for x in os.getenv('CFLAGS').split()]))")
|
$(python -c "import os; print('c_args = {}'.format([x for x in os.getenv('CFLAGS').split()]))")
|
||||||
$(python -c "import os; print('c_link_args = {}'.format([x for x in os.getenv('LDFLAGS').split()]))")
|
$(python -c "import os; print('c_link_args = {}'.format([x for x in os.getenv('LDFLAGS').split()]))")
|
||||||
|
$(python -c "import os; print('cpp_args = {}'.format([x for x in os.getenv('CXXFLAGS').split()]))")
|
||||||
|
$(python -c "import os; print('cpp_link_args = {}'.format([x for x in os.getenv('LDFLAGS').split()]))")
|
||||||
${!properties}
|
${!properties}
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
@@ -714,7 +714,7 @@ get_pkg_variable() {
|
|||||||
|
|
||||||
# get package's build dir
|
# get package's build dir
|
||||||
get_build_dir() {
|
get_build_dir() {
|
||||||
local _PKG_NAME="$(get_pkg_variable "$1" PKG_NAME)" _PKG_VERSION="$(get_pkg_version "$1")"
|
local _PKG_NAME="${1%:*}" _PKG_VERSION="$(get_pkg_version "$1")"
|
||||||
if [ -n "$_PKG_NAME" -a -n "$_PKG_VERSION" ]; then
|
if [ -n "$_PKG_NAME" -a -n "$_PKG_VERSION" ]; then
|
||||||
echo $BUILD/${_PKG_NAME}-${_PKG_VERSION}
|
echo $BUILD/${_PKG_NAME}-${_PKG_VERSION}
|
||||||
fi
|
fi
|
||||||
@@ -989,8 +989,10 @@ kernel_config_path() {
|
|||||||
$pkg_linux_dir/config/$config_name \
|
$pkg_linux_dir/config/$config_name \
|
||||||
; do
|
; do
|
||||||
[[ $cfg =~ /devices//linux/ ]] && continue
|
[[ $cfg =~ /devices//linux/ ]] && continue
|
||||||
[ -f "$cfg" ] && echo "$cfg" && break
|
[ -f "$cfg" ] && echo "$cfg" && return
|
||||||
done
|
done
|
||||||
|
|
||||||
|
die "ERROR: Unable to locate kernel config for ${LINUX} - looking for ${config_name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
kernel_make() {
|
kernel_make() {
|
||||||
@@ -1155,6 +1157,8 @@ done
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_addon_files() {
|
install_addon_files() {
|
||||||
|
mkdir -p "$1"
|
||||||
|
|
||||||
install_addon_source "$1"
|
install_addon_source "$1"
|
||||||
install_addon_images "$1"
|
install_addon_images "$1"
|
||||||
create_addon_xml "$1"
|
create_addon_xml "$1"
|
||||||
@@ -1190,7 +1194,7 @@ add_user() {
|
|||||||
|
|
||||||
mkdir -p ${INSTALL}/usr/cache
|
mkdir -p ${INSTALL}/usr/cache
|
||||||
touch ${INSTALL}/usr/cache/shadow
|
touch ${INSTALL}/usr/cache/shadow
|
||||||
ln -sf /storage/.cache/shadow ${INSTALL}/etc/shadow
|
ln -sf /storage/.cache/shadow ${INSTALL}/etc/shadow 2>/dev/null || true
|
||||||
|
|
||||||
PASSWORD="$2"
|
PASSWORD="$2"
|
||||||
if [ "$PASSWORD" = "x" ]; then
|
if [ "$PASSWORD" = "x" ]; then
|
||||||
@@ -1235,6 +1239,8 @@ enable_service() {
|
|||||||
|
|
||||||
|
|
||||||
### MULTI-THREADED FUNCTION HELPERS ###
|
### MULTI-THREADED FUNCTION HELPERS ###
|
||||||
|
# Test MTWITHLOCKS so that these functions are a no-op during non-multithreaded builds.
|
||||||
|
|
||||||
# Prevent concurrent modifications to a package (unpack) or
|
# Prevent concurrent modifications to a package (unpack) or
|
||||||
# package:target (install/build).
|
# package:target (install/build).
|
||||||
#
|
#
|
||||||
@@ -1262,7 +1268,7 @@ pkg_lock() {
|
|||||||
|
|
||||||
# As we now have the lock, if .failed still exists then a previous process must have failed
|
# As we now have the lock, if .failed still exists then a previous process must have failed
|
||||||
if [ -f "${THREAD_CONTROL}/locks/${pkg}.${task}.failed" ]; then
|
if [ -f "${THREAD_CONTROL}/locks/${pkg}.${task}.failed" ]; then
|
||||||
fail_seq="$(cat "${THREAD_CONTROL}/locks/${pkg}.${task}.failed")"
|
fail_seq="$(< "${THREAD_CONTROL}/locks/${pkg}.${task}.failed")"
|
||||||
print_color CLR_ERROR "FAILURE: ${pkg}.${task}.failed exists, a previous dependency process has failed (seq: ${fail_seq})\n"
|
print_color CLR_ERROR "FAILURE: ${pkg}.${task}.failed exists, a previous dependency process has failed (seq: ${fail_seq})\n"
|
||||||
if [ -d "${THREAD_CONTROL}/logs" ]; then
|
if [ -d "${THREAD_CONTROL}/logs" ]; then
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
@@ -1289,7 +1295,7 @@ pkg_lock_status() {
|
|||||||
(
|
(
|
||||||
flock --exclusive 94
|
flock --exclusive 94
|
||||||
|
|
||||||
printf -v line "%s: <%05d> [%02d/%0*d] %-7s %-7s %-35s" \
|
printf -v line "%s: <%06d> [%02d/%0*d] %-7s %-7s %-35s" \
|
||||||
"$(date +%Y-%m-%d\ %H:%M:%S.%N)" $$ ${this_job} ${#MTMAXJOBS} ${PARALLEL_SEQ:-0} "${status}" "${task}" "${pkg}"
|
"$(date +%Y-%m-%d\ %H:%M:%S.%N)" $$ ${this_job} ${#MTMAXJOBS} ${PARALLEL_SEQ:-0} "${status}" "${task}" "${pkg}"
|
||||||
[ -n "${msg}" ] && line+=" (${msg})"
|
[ -n "${msg}" ] && line+=" (${msg})"
|
||||||
|
|
||||||
@@ -1320,15 +1326,19 @@ update_dashboard() {
|
|||||||
|
|
||||||
sedline=$((MTJOBID + 2))
|
sedline=$((MTJOBID + 2))
|
||||||
|
|
||||||
num=$(cat "${THREAD_CONTROL}/status" | wc -l)
|
num=$(< "${THREAD_CONTROL}/status.max")
|
||||||
while [ ${num} -lt ${sedline} ]; do echo "" >>"${THREAD_CONTROL}/status"; num=$((num + 1)); done
|
if [ ${num} -lt ${sedline} ]; then
|
||||||
|
echo ${sedline} >"${THREAD_CONTROL}/status.max"
|
||||||
|
for i in $(seq $((num + 1)) ${sedline}); do echo "" >>"${THREAD_CONTROL}/status"; done
|
||||||
|
fi
|
||||||
|
|
||||||
num=$(($(cat "${THREAD_CONTROL}/progress.prev") + 1))
|
num=$(< "${THREAD_CONTROL}/progress.prev")
|
||||||
projdevarch="${PROJECT}/"
|
projdevarch="${PROJECT}/"
|
||||||
[ -n "${DEVICE}" ] && projdevarch+="${DEVICE}/"
|
[ -n "${DEVICE}" ] && projdevarch+="${DEVICE}/"
|
||||||
projdevarch+="${TARGET_ARCH}"
|
projdevarch+="${TARGET_ARCH}"
|
||||||
|
[ -n "${BUILD_SUFFIX}" ] && projdevarch+=", ${BUILD_SUFFIX}"
|
||||||
TZ=UTC0 printf -v elapsed "%(%H:%M:%S)T" $(($(date +%s) - MTBUILDSTART))
|
TZ=UTC0 printf -v elapsed "%(%H:%M:%S)T" $(($(date +%s) - MTBUILDSTART))
|
||||||
printf -v preamble "%s Dashboard (%s) - %d of %d jobs completed, %s elapsed" "${DISTRONAME}" "${projdevarch}" ${num} ${MTMAXJOBS} "${elapsed}"
|
printf -v preamble "%s Dashboard (%s) - %d of %d jobs completed, %s elapsed" "${DISTRONAME}" "${projdevarch}" $((num + 1)) ${MTMAXJOBS} "${elapsed}"
|
||||||
printf -v preamble "%b%-105s %s" "\e[2J\e[0;0H" "${preamble//\//\\/}" "$(date "+%Y-%m-%d %H:%M:%S")"
|
printf -v preamble "%b%-105s %s" "\e[2J\e[0;0H" "${preamble//\//\\/}" "$(date "+%Y-%m-%d %H:%M:%S")"
|
||||||
|
|
||||||
if [ "${DISABLE_COLORS}" != "yes" ]; then
|
if [ "${DISABLE_COLORS}" != "yes" ]; then
|
||||||
@@ -1355,7 +1365,6 @@ update_dashboard() {
|
|||||||
|
|
||||||
# Thread concurrency helpers to avoid concurrency issues with some code,
|
# Thread concurrency helpers to avoid concurrency issues with some code,
|
||||||
# eg. when Python installs directly into $TOOLCHAIN.
|
# eg. when Python installs directly into $TOOLCHAIN.
|
||||||
# Test MTJOBID so that these functions are a no-op during non-multithreaded builds.
|
|
||||||
acquire_exclusive_lock() {
|
acquire_exclusive_lock() {
|
||||||
[ "${MTWITHLOCKS}" != "yes" ] && return 0
|
[ "${MTWITHLOCKS}" != "yes" ] && return 0
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ get_graphicdrivers() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if listcontains "${GRAPHIC_DRIVERS}" "vc4"; then
|
if listcontains "${GRAPHIC_DRIVERS}" "vc4"; then
|
||||||
GALLIUM_DRIVERS+=" vc4"
|
GALLIUM_DRIVERS+=" vc4 v3d kmsro"
|
||||||
V4L2_SUPPORT="yes"
|
V4L2_SUPPORT="yes"
|
||||||
VAAPI_SUPPORT="no"
|
VAAPI_SUPPORT="no"
|
||||||
VDPAU_SUPPORT="no"
|
VDPAU_SUPPORT="no"
|
||||||
|
|||||||
@@ -107,8 +107,9 @@ package_worker() {
|
|||||||
(
|
(
|
||||||
flock --exclusive 95
|
flock --exclusive 95
|
||||||
[ ${result} -eq 0 ] && status="DONE" || status="FAIL"
|
[ ${result} -eq 0 ] && status="DONE" || status="FAIL"
|
||||||
num=$(($(cat "${THREAD_CONTROL}/progress") + 1))
|
num=$(< "${THREAD_CONTROL}/progress")
|
||||||
mv "${THREAD_CONTROL}/progress" "${THREAD_CONTROL}/progress.prev"
|
mv "${THREAD_CONTROL}/progress" "${THREAD_CONTROL}/progress.prev"
|
||||||
|
num=$((num + 1))
|
||||||
echo ${num} >"${THREAD_CONTROL}/progress"
|
echo ${num} >"${THREAD_CONTROL}/progress"
|
||||||
printf "[%0*d/%0*d] [%-4s] %-7s %s\n" ${#jobs} ${num} ${#jobs} ${jobs} "${status}" "${task}" "${pkgname}" >&2
|
printf "[%0*d/%0*d] [%-4s] %-7s %s\n" ${#jobs} ${num} ${#jobs} ${jobs} "${status}" "${task}" "${pkgname}" >&2
|
||||||
) 95>"${THREAD_CONTROL}/locks/.progress"
|
) 95>"${THREAD_CONTROL}/locks/.progress"
|
||||||
@@ -143,12 +144,13 @@ start_multithread_build() {
|
|||||||
mkdir -p "${THREAD_CONTROL}/locks"
|
mkdir -p "${THREAD_CONTROL}/locks"
|
||||||
echo -1 >"${THREAD_CONTROL}/progress.prev"
|
echo -1 >"${THREAD_CONTROL}/progress.prev"
|
||||||
echo 0 >"${THREAD_CONTROL}/progress"
|
echo 0 >"${THREAD_CONTROL}/progress"
|
||||||
|
echo 0 >"${THREAD_CONTROL}/status.max"
|
||||||
touch "${THREAD_CONTROL}/status"
|
touch "${THREAD_CONTROL}/status"
|
||||||
|
|
||||||
[ "${THREADCOUNT}" = "0" ] && THREADCOUNT=1
|
[ "${THREADCOUNT}" = "0" ] && THREADCOUNT=1
|
||||||
|
|
||||||
# Bootstrap GNU parallel
|
# Bootstrap GNU parallel
|
||||||
$SCRIPTS/build parallel:host 2>&1 || die "Unable to bootstrap parallel package"
|
MTWITHLOCKS=no $SCRIPTS/build parallel:host 2>&1 || die "Unable to bootstrap parallel package"
|
||||||
|
|
||||||
# if number of detected slots is 1 then don't bother using inter-process locks as this is a sequential build
|
# if number of detected slots is 1 then don't bother using inter-process locks as this is a sequential build
|
||||||
[ $(seq 1 32 | ${TOOLCHAIN}/bin/parallel --plain --no-notice --max-procs ${THREADCOUNT} echo {%} | sort -n | tail -1) -eq 1 ] && singlethread=yes || singlethread=no
|
[ $(seq 1 32 | ${TOOLCHAIN}/bin/parallel --plain --no-notice --max-procs ${THREADCOUNT} echo {%} | sort -n | tail -1) -eq 1 ] && singlethread=yes || singlethread=no
|
||||||
|
|||||||
@@ -6,6 +6,6 @@
|
|||||||
"description": "@DESCRIPTION@",
|
"description": "@DESCRIPTION@",
|
||||||
"username": "root",
|
"username": "root",
|
||||||
"password": "@ROOT_PASSWORD@",
|
"password": "@ROOT_PASSWORD@",
|
||||||
"supported_models": [@NOOBS_SUPPORTED_MODELS@],
|
"supported_hex_revisions": "@NOOBS_HEX@",
|
||||||
"supported_hex_revisions": "@NOOBS_HEX@"
|
"supported_models": [@NOOBS_SUPPORTED_MODELS@]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ show_config() {
|
|||||||
config_message="$config_message\n $dashes$dashes"
|
config_message="$config_message\n $dashes$dashes"
|
||||||
|
|
||||||
config_message="$config_message\n - Remote support:\t\t\t $REMOTE_SUPPORT"
|
config_message="$config_message\n - Remote support:\t\t\t $REMOTE_SUPPORT"
|
||||||
config_message="$config_message\n - ATV Remote support:\t\t\t $ATVCLIENT_SUPPORT"
|
|
||||||
config_message="$config_message\n - CEC Adapter support:\t\t\t $CEC_SUPPORT"
|
config_message="$config_message\n - CEC Adapter support:\t\t\t $CEC_SUPPORT"
|
||||||
config_message="$config_message\n - CEC Framework support:\t\t $CEC_FRAMEWORK_SUPPORT"
|
config_message="$config_message\n - CEC Framework support:\t\t $CEC_FRAMEWORK_SUPPORT"
|
||||||
config_message="$config_message\n - Kodi Joystick support:\t\t $JOYSTICK_SUPPORT"
|
config_message="$config_message\n - Kodi Joystick support:\t\t $JOYSTICK_SUPPORT"
|
||||||
@@ -105,10 +104,6 @@ show_config() {
|
|||||||
config_message="$config_message\n - OEM Support:\t\t\t\t $OEM_SUPPORT"
|
config_message="$config_message\n - OEM Support:\t\t\t\t $OEM_SUPPORT"
|
||||||
config_message="$config_message\n - Default ROOT Password:\t\t $ROOT_PASSWORD"
|
config_message="$config_message\n - Default ROOT Password:\t\t $ROOT_PASSWORD"
|
||||||
config_message="$config_message\n - Bootloader:\t\t\t\t $BOOTLOADER"
|
config_message="$config_message\n - Bootloader:\t\t\t\t $BOOTLOADER"
|
||||||
if [ "$BOOTLOADER" = "u-boot" ]; then
|
|
||||||
config_message="$config_message\n - U-Boot configuration:\t\t $UBOOT_CONFIG"
|
|
||||||
config_message="$config_message\n - U-Boot config file:\t\t $UBOOT_CONFIGFILE"
|
|
||||||
fi
|
|
||||||
config_message="$config_message\n - UDevil support:\t\t\t $UDEVIL"
|
config_message="$config_message\n - UDevil support:\t\t\t $UDEVIL"
|
||||||
config_message="$config_message\n - Installer support:\t\t\t $INSTALLER_SUPPORT"
|
config_message="$config_message\n - Installer support:\t\t\t $INSTALLER_SUPPORT"
|
||||||
for config_package in $ADDITIONAL_PACKAGES; do
|
for config_package in $ADDITIONAL_PACKAGES; do
|
||||||
|
|||||||
@@ -140,9 +140,6 @@
|
|||||||
# build and install remote support (yes / no)
|
# build and install remote support (yes / no)
|
||||||
REMOTE_SUPPORT="yes"
|
REMOTE_SUPPORT="yes"
|
||||||
|
|
||||||
# build and install ATV IR remote support (yes / no)
|
|
||||||
ATVCLIENT_SUPPORT="yes"
|
|
||||||
|
|
||||||
# build and install Joystick support (yes / no)
|
# build and install Joystick support (yes / no)
|
||||||
JOYSTICK_SUPPORT="yes"
|
JOYSTICK_SUPPORT="yes"
|
||||||
|
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
OS_VERSION="9.1"
|
OS_VERSION="9.1"
|
||||||
|
|
||||||
# ADDON_VERSION: Addon version
|
# ADDON_VERSION: Addon version
|
||||||
ADDON_VERSION="9.1"
|
ADDON_VERSION="9.1.901"
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="containerd"
|
PKG_NAME="containerd"
|
||||||
PKG_VERSION="1.2.6"
|
PKG_VERSION="1.2.7"
|
||||||
PKG_SHA256="f2d578b743fb9faa5b3477b7cf4b33d00501087043a53b27754f14bbe741f891"
|
PKG_SHA256="7179c709a0d187708a1eeddcbdecd7206b2c642dc4413bcdb049cd6b38d06801"
|
||||||
PKG_LICENSE="APL"
|
PKG_LICENSE="APL"
|
||||||
PKG_SITE="https://containerd.tools/"
|
PKG_SITE="https://containerd.tools/"
|
||||||
PKG_URL="https://github.com/containerd/containerd/archive/v$PKG_VERSION.tar.gz"
|
PKG_URL="https://github.com/containerd/containerd/archive/v$PKG_VERSION.tar.gz"
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="krb5"
|
PKG_NAME="krb5"
|
||||||
PKG_VERSION="1.16.2-final"
|
PKG_VERSION="1.17-final"
|
||||||
PKG_SHA256="92f62e5a54404d22aa2a7eee9fba64d1be8d10d8dd3aa052e1799993208acce4"
|
PKG_SHA256="bd170f6aadea5d753cc9a93a3a915a5bde07bd3d294a00651ed647dcf964e867"
|
||||||
PKG_LICENSE="MIT"
|
PKG_LICENSE="MIT"
|
||||||
PKG_SITE="http://web.mit.edu/kerberos/"
|
PKG_SITE="http://web.mit.edu/kerberos/"
|
||||||
PKG_URL="https://github.com/krb5/krb5/archive/krb5-$PKG_VERSION.tar.gz"
|
PKG_URL="https://github.com/krb5/krb5/archive/krb5-$PKG_VERSION.tar.gz"
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="lttng-ust"
|
PKG_NAME="lttng-ust"
|
||||||
PKG_VERSION="2.10.2"
|
PKG_VERSION="2.10.4"
|
||||||
PKG_SHA256="015452be6f94e4468315d0478cd5a4d01d9e52672bcea122b4ff7426198d5803"
|
PKG_SHA256="9df458fbfeac5a380672751decbd9b57356075acbfe106cb8820e803a94a0d96"
|
||||||
PKG_LICENSE="LGPLv2.1"
|
PKG_LICENSE="LGPLv2.1"
|
||||||
PKG_SITE="https://lttng.org/"
|
PKG_SITE="https://lttng.org/"
|
||||||
PKG_URL="https://github.com/lttng/lttng-ust/archive/v$PKG_VERSION.tar.gz"
|
PKG_URL="https://github.com/lttng/lttng-ust/archive/v$PKG_VERSION.tar.gz"
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="userspace-rcu"
|
PKG_NAME="userspace-rcu"
|
||||||
PKG_VERSION="0.10.1"
|
PKG_VERSION="0.11.1"
|
||||||
PKG_SHA256="4ddbca9927b459b7a295dec612cf43df5886d398161d50c59d0097995e368a3b"
|
PKG_SHA256="a0ed8995edfbeac5f5eb2f152a8f3654040ecfc99a746bfe3da3bccf435b7d5d"
|
||||||
PKG_LICENSE="LGPLv2.1"
|
PKG_LICENSE="LGPLv2.1"
|
||||||
PKG_SITE="http://liburcu.org"
|
PKG_SITE="http://liburcu.org"
|
||||||
PKG_URL="https://github.com/urcu/userspace-rcu/archive/v$PKG_VERSION.tar.gz"
|
PKG_URL="https://github.com/urcu/userspace-rcu/archive/v$PKG_VERSION.tar.gz"
|
||||||
|
|||||||
@@ -10,14 +10,6 @@ PKG_URL="https://github.com/mighty-p/t2scan/archive/$PKG_VERSION.tar.gz"
|
|||||||
PKG_DEPENDS_TARGET="toolchain"
|
PKG_DEPENDS_TARGET="toolchain"
|
||||||
PKG_LONGDESC="A small channel scan tool which generates DVB-T/T2 channels.conf files."
|
PKG_LONGDESC="A small channel scan tool which generates DVB-T/T2 channels.conf files."
|
||||||
|
|
||||||
# aml 3.14 hack
|
|
||||||
pre_configure_target() {
|
|
||||||
if [ "$LINUX" = "amlogic-3.14" -o "$LINUX" = "amlogic-3.10" ]; then
|
|
||||||
sed -i 's/DVB_HEADER=0/DVB_HEADER=1/g' $PKG_BUILD/configure*
|
|
||||||
sed -i 's/HAS_DVB_API5=0/HAS_DVB_API5=1/g' $PKG_BUILD/configure*
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
makeinstall_target() {
|
makeinstall_target() {
|
||||||
:
|
:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,14 +11,6 @@ PKG_DEPENDS_TARGET="toolchain"
|
|||||||
PKG_LONGDESC="A channel scan tool which generates ATSC, DVB-C, DVB-S/S2 and DVB-T channels.conf files."
|
PKG_LONGDESC="A channel scan tool which generates ATSC, DVB-C, DVB-S/S2 and DVB-T channels.conf files."
|
||||||
PKG_TOOLCHAIN="autotools"
|
PKG_TOOLCHAIN="autotools"
|
||||||
|
|
||||||
# aml 3.14 hack
|
|
||||||
pre_configure_target() {
|
|
||||||
if [ "$LINUX" = "amlogic-3.14" -o "$LINUX" = "amlogic-3.10" ]; then
|
|
||||||
sed -i 's/DVB_HEADER=0/DVB_HEADER=1/g' $PKG_BUILD/configure*
|
|
||||||
sed -i 's/HAS_DVB_API5=0/HAS_DVB_API5=1/g' $PKG_BUILD/configure*
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
makeinstall_target() {
|
makeinstall_target() {
|
||||||
:
|
:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="imagemagick"
|
PKG_NAME="imagemagick"
|
||||||
PKG_VERSION="7.0.8-11"
|
PKG_VERSION="7.0.8-53"
|
||||||
PKG_SHA256="95e4da5fa109bc8b59b5e7a54cdfcf1af3230067c95adf608ff21c08eca1de20"
|
PKG_SHA256="b8c35e03fc4bd2bf66bddfe232a34473e7df68c3716c831ba76dc30520e7b490"
|
||||||
PKG_LICENSE="http://www.imagemagick.org/script/license.php"
|
PKG_LICENSE="http://www.imagemagick.org/script/license.php"
|
||||||
PKG_SITE="http://www.imagemagick.org/"
|
PKG_SITE="http://www.imagemagick.org/"
|
||||||
PKG_URL="https://github.com/ImageMagick/ImageMagick/archive/$PKG_VERSION.tar.gz"
|
PKG_URL="https://github.com/ImageMagick/ImageMagick/archive/$PKG_VERSION.tar.gz"
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="go"
|
PKG_NAME="go"
|
||||||
PKG_VERSION="1.12.3"
|
PKG_VERSION="1.12.6"
|
||||||
PKG_SHA256="b710a65982e9001ef99a167cf6e8636e46ec36a10e487e7c1c7384cdcd6fcd7c"
|
PKG_SHA256="d61ff8fa5685b911653c8153de6e6501728ec3aee26a9d5a56880bab3120426b"
|
||||||
PKG_LICENSE="BSD"
|
PKG_LICENSE="BSD"
|
||||||
PKG_SITE="https://golang.org"
|
PKG_SITE="https://golang.org"
|
||||||
PKG_URL="https://github.com/golang/go/archive/${PKG_NAME}${PKG_VERSION}.tar.gz"
|
PKG_URL="https://github.com/golang/go/archive/${PKG_NAME}${PKG_VERSION}.tar.gz"
|
||||||
|
|||||||
@@ -26,16 +26,14 @@ pre_configure_target() {
|
|||||||
export ac_cv_path_LIBUSB_CONFIG=$SYSROOT_PREFIX/usr/bin/libusb-config
|
export ac_cv_path_LIBUSB_CONFIG=$SYSROOT_PREFIX/usr/bin/libusb-config
|
||||||
}
|
}
|
||||||
|
|
||||||
post_make_target() {
|
makeinstall_target() {
|
||||||
# copy necessary libs and headers to build serdisplib support
|
# copy necessary libs and headers to build serdisplib support
|
||||||
# into the driver glcd from lcdproc
|
# into the driver glcd from lcdproc
|
||||||
mkdir -p $SYSROOT_PREFIX/usr/include/serdisplib
|
mkdir -p $SYSROOT_PREFIX/usr/include/serdisplib
|
||||||
cp include/serdisplib/*.h $SYSROOT_PREFIX/usr/include/serdisplib
|
cp include/serdisplib/*.h $SYSROOT_PREFIX/usr/include/serdisplib
|
||||||
mkdir -p $SYSROOT_PREFIX/usr/lib
|
mkdir -p $SYSROOT_PREFIX/usr/lib
|
||||||
cp lib/libserdisp.so* $SYSROOT_PREFIX/usr/lib
|
cp lib/libserdisp.so* $SYSROOT_PREFIX/usr/lib
|
||||||
}
|
|
||||||
|
|
||||||
makeinstall_target() {
|
|
||||||
mkdir -p $INSTALL/usr/lib
|
mkdir -p $INSTALL/usr/lib
|
||||||
cp lib/libserdisp.so* $INSTALL/usr/lib
|
cp lib/libserdisp.so* $INSTALL/usr/lib
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="libnetwork"
|
PKG_NAME="libnetwork"
|
||||||
PKG_VERSION="4725f2163fb214a6312f3beae5991f838ec36326"
|
PKG_VERSION="e7933d41e7b206756115aa9df5e0599fc5169742"
|
||||||
PKG_SHA256="049bddc1e584f30c29e0fed8716b3c7023d4bb31789d7c3aa48d17b979f1522b"
|
PKG_SHA256="b9695c4d7711487543b2eff8ca74cc2deb9828f7f4582196324d39d20eab3855"
|
||||||
PKG_LICENSE="APL"
|
PKG_LICENSE="APL"
|
||||||
PKG_SITE="https://github.com/docker/libnetwork"
|
PKG_SITE="https://github.com/docker/libnetwork"
|
||||||
PKG_URL="https://github.com/docker/libnetwork/archive/${PKG_VERSION}.tar.gz"
|
PKG_URL="https://github.com/docker/libnetwork/archive/${PKG_VERSION}.tar.gz"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="rust"
|
PKG_NAME="rust"
|
||||||
PKG_VERSION="1.31.1"
|
PKG_VERSION="1.36.0"
|
||||||
PKG_LICENSE="MIT"
|
PKG_LICENSE="MIT"
|
||||||
PKG_SITE="https://www.rust-lang.org"
|
PKG_SITE="https://www.rust-lang.org"
|
||||||
PKG_DEPENDS_TARGET="toolchain rustup.rs"
|
PKG_DEPENDS_TARGET="toolchain rustup.rs"
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="rustup.rs"
|
PKG_NAME="rustup.rs"
|
||||||
PKG_VERSION="1.16.0"
|
PKG_VERSION="1.18.3"
|
||||||
PKG_SHA256="8c4ffeda2088dbdd5ea2eac8acef5ddd57dfcfe1f06a503e3da790f93161e1a6"
|
PKG_SHA256="9a2ae2c85bbbfc838b25d86d049bc677532950d78765725beabb8a61df1c2710"
|
||||||
PKG_LICENSE="MIT"
|
PKG_LICENSE="MIT"
|
||||||
PKG_SITE="https://www.rust-lang.org"
|
PKG_SITE="https://www.rust-lang.org"
|
||||||
PKG_URL="https://github.com/rust-lang-nursery/rustup.rs/archive/$PKG_VERSION.tar.gz"
|
PKG_URL="https://github.com/rust-lang-nursery/rustup.rs/archive/$PKG_VERSION.tar.gz"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ PKG_SHA256="6c1337aee2e4bf993299851c70b7db11faec785303cfca3a5c3eb5f329ba7023"
|
|||||||
PKG_LICENSE="LGPLv2"
|
PKG_LICENSE="LGPLv2"
|
||||||
PKG_SITE="http://www.mpg123.org/"
|
PKG_SITE="http://www.mpg123.org/"
|
||||||
PKG_URL="http://downloads.sourceforge.net/sourceforge/mpg123/mpg123-$PKG_VERSION.tar.bz2"
|
PKG_URL="http://downloads.sourceforge.net/sourceforge/mpg123/mpg123-$PKG_VERSION.tar.bz2"
|
||||||
PKG_DEPENDS_TARGET="toolchain alsa-lib SDL2"
|
PKG_DEPENDS_TARGET="toolchain alsa-lib"
|
||||||
PKG_LONGDESC="A console based real time MPEG Audio Player for Layer 1, 2 and 3."
|
PKG_LONGDESC="A console based real time MPEG Audio Player for Layer 1, 2 and 3."
|
||||||
|
|
||||||
PKG_CONFIGURE_OPTS_TARGET="--disable-shared \
|
PKG_CONFIGURE_OPTS_TARGET="--disable-shared \
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ PKG_SHA256="4ebc271e9e5cea84a683375a0f7e91086e5dac90c5d51bb3f169f75386107a62"
|
|||||||
PKG_LICENSE="GPLv3"
|
PKG_LICENSE="GPLv3"
|
||||||
PKG_SITE="http://lftp.yar.ru/"
|
PKG_SITE="http://lftp.yar.ru/"
|
||||||
PKG_URL="http://lftp.yar.ru/ftp/${PKG_NAME}-${PKG_VERSION}.tar.xz"
|
PKG_URL="http://lftp.yar.ru/ftp/${PKG_NAME}-${PKG_VERSION}.tar.xz"
|
||||||
PKG_DEPENDS_TARGET="toolchain readline openssl zlib"
|
PKG_DEPENDS_TARGET="toolchain readline openssl zlib libidn2"
|
||||||
PKG_LONGDESC="A sophisticated ftp/http client, and a file transfer program supporting a number of network protocols."
|
PKG_LONGDESC="A sophisticated ftp/http client, and a file transfer program supporting a number of network protocols."
|
||||||
|
|
||||||
PKG_CONFIGURE_OPTS_TARGET="--disable-nls \
|
PKG_CONFIGURE_OPTS_TARGET="--disable-nls \
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ PKG_URL="http://www.udpxy.com/download/1_23/${PKG_NAME}.${PKG_VERSION}-prod.tar.
|
|||||||
PKG_DEPENDS_TARGET="toolchain"
|
PKG_DEPENDS_TARGET="toolchain"
|
||||||
PKG_LONGDESC="A UDP-to-HTTP multicast traffic relay daemon."
|
PKG_LONGDESC="A UDP-to-HTTP multicast traffic relay daemon."
|
||||||
|
|
||||||
|
configure_target() {
|
||||||
|
export CFLAGS+=" -Wno-stringop-truncation"
|
||||||
|
}
|
||||||
|
|
||||||
makeinstall_target() {
|
makeinstall_target() {
|
||||||
:
|
:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="runc"
|
PKG_NAME="runc"
|
||||||
PKG_VERSION="v1.0.0-rc7"
|
PKG_VERSION="v1.0.0-rc8"
|
||||||
PKG_SHA256="e8388b812d93a8a131a2a2fdd851847295c8e341721002940dadd2999fb81b51"
|
PKG_SHA256="efe4ff9bbe49b19074346d65c914d809c0a3e90d062ea9619fe240f931f0b700"
|
||||||
PKG_LICENSE="APL"
|
PKG_LICENSE="APL"
|
||||||
PKG_SITE="https://github.com/opencontainers/runc"
|
PKG_SITE="https://github.com/opencontainers/runc"
|
||||||
PKG_URL="https://github.com/opencontainers/runc/archive/${PKG_VERSION}.tar.gz"
|
PKG_URL="https://github.com/opencontainers/runc/archive/${PKG_VERSION}.tar.gz"
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
From c4c59790f3191c1a233fc1a61f8fedad85de1aeb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Fink <pfink@christ-es.de>
|
||||||
|
Date: Wed, 8 Feb 2017 14:04:45 +0100
|
||||||
|
Subject: [PATCH] fbutils: Fix x64 execution. Call malloc not with a hardcoded
|
||||||
|
sizeof(__u32). This caused the application to crash with segfaults on x64
|
||||||
|
machines.
|
||||||
|
|
||||||
|
---
|
||||||
|
tests/fbutils.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tests/fbutils.c b/tests/fbutils.c
|
||||||
|
index 8ee494bc..fd7fbfe9 100644
|
||||||
|
--- a/tests/fbutils.c
|
||||||
|
+++ b/tests/fbutils.c
|
||||||
|
@@ -138,7 +138,7 @@ int open_framebuffer(void)
|
||||||
|
memset(fbuffer,0,fix.smem_len);
|
||||||
|
|
||||||
|
bytes_per_pixel = (var.bits_per_pixel + 7) / 8;
|
||||||
|
- line_addr = malloc (sizeof (__u32) * var.yres_virtual);
|
||||||
|
+ line_addr = malloc (sizeof (line_addr) * var.yres_virtual);
|
||||||
|
addr = 0;
|
||||||
|
for (y = 0; y < var.yres_virtual; y++, addr += fix.line_length)
|
||||||
|
line_addr [y] = fbuffer + addr;
|
||||||
@@ -5,7 +5,6 @@ PKG_NAME="repository.linuxserver.docker"
|
|||||||
PKG_VERSION="9.0"
|
PKG_VERSION="9.0"
|
||||||
PKG_REV="102"
|
PKG_REV="102"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_ADDON_PROJECTS="any !WeTek_Core !WeTek_Play"
|
|
||||||
PKG_LICENSE="GPL"
|
PKG_LICENSE="GPL"
|
||||||
PKG_SITE="https://linuxserver.io"
|
PKG_SITE="https://linuxserver.io"
|
||||||
PKG_URL=""
|
PKG_URL=""
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ addon() {
|
|||||||
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/bin
|
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/bin
|
||||||
cp -P $PKG_BUILD/.$TARGET_NAME/src/boblightd $ADDON_BUILD/$PKG_ADDON_ID/bin
|
cp -P $PKG_BUILD/.$TARGET_NAME/src/boblightd $ADDON_BUILD/$PKG_ADDON_ID/bin
|
||||||
cp -P $PKG_BUILD/.$TARGET_NAME/src/boblight-constant $ADDON_BUILD/$PKG_ADDON_ID/bin
|
cp -P $PKG_BUILD/.$TARGET_NAME/src/boblight-constant $ADDON_BUILD/$PKG_ADDON_ID/bin
|
||||||
cp -P $PKG_BUILD/.$TARGET_NAME/src/boblight-aml $ADDON_BUILD/$PKG_ADDON_ID/bin
|
|
||||||
if [ "$DISPLAYSERVER" = "x11" ] ; then
|
if [ "$DISPLAYSERVER" = "x11" ] ; then
|
||||||
cp -P $PKG_BUILD/.$TARGET_NAME/src/boblight-X11 $ADDON_BUILD/$PKG_ADDON_ID/bin
|
cp -P $PKG_BUILD/.$TARGET_NAME/src/boblight-X11 $ADDON_BUILD/$PKG_ADDON_ID/bin
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,632 +0,0 @@
|
|||||||
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
||||||
index 9ba5381..c5a4dc6 100644
|
|
||||||
--- a/src/Makefile.am
|
|
||||||
+++ b/src/Makefile.am
|
|
||||||
@@ -7,6 +7,7 @@ AM_CFLAGS =\
|
|
||||||
-g
|
|
||||||
|
|
||||||
bin_PROGRAMS = boblightd \
|
|
||||||
+ boblight-aml \
|
|
||||||
boblight-constant
|
|
||||||
|
|
||||||
|
|
||||||
@@ -19,6 +20,11 @@ endif
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
+boblight_aml_SOURCES = clients/boblight-aml/boblight-aml.cpp
|
|
||||||
+boblight_aml_SOURCES += clients/boblight-aml/flagmanager-aml.cpp
|
|
||||||
+boblight_aml_SOURCES += clients/flagmanager.cpp
|
|
||||||
+boblight_aml_SOURCES += util/misc.cpp
|
|
||||||
+
|
|
||||||
boblight_v4l_SOURCES = \
|
|
||||||
clients/boblight-v4l/boblight-v4l.cpp \
|
|
||||||
clients/boblight-v4l/flagmanager-v4l.cpp \
|
|
||||||
diff -urPp src/clients/boblight-aml.cpp src/clients/boblight-aml/boblight-aml.cpp
|
|
||||||
--- /dev/null Thu Jan 1 00:00:00 1970
|
|
||||||
+++ b/src/clients/boblight-aml/boblight-aml.cpp Thu Jan 15 10:24:16 2015
|
|
||||||
@@ -0,0 +1,491 @@
|
|
||||||
+/*
|
|
||||||
+ * boblight
|
|
||||||
+ * Copyright (C) Bob 2009
|
|
||||||
+ *
|
|
||||||
+ * boblight 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 3 of the License, or
|
|
||||||
+ * (at your option) any later version.
|
|
||||||
+ *
|
|
||||||
+ * boblight 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#define BOBLIGHT_DLOPEN
|
|
||||||
+#include "lib/boblight.h"
|
|
||||||
+
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <signal.h>
|
|
||||||
+#include <algorithm>
|
|
||||||
+
|
|
||||||
+#include <fcntl.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
+#include <sys/stat.h>
|
|
||||||
+#include <sys/poll.h>
|
|
||||||
+#include <sys/types.h>
|
|
||||||
+#include <sys/time.h>
|
|
||||||
+#include <sys/ioctl.h>
|
|
||||||
+
|
|
||||||
+#include "config.h"
|
|
||||||
+#include "util/misc.h"
|
|
||||||
+#include "util/timeutils.h"
|
|
||||||
+#include "flagmanager-aml.h"
|
|
||||||
+
|
|
||||||
+using namespace std;
|
|
||||||
+
|
|
||||||
+//from linux/amlogic/amports/amvideocap.h
|
|
||||||
+#define AMVIDEOCAP_IOC_MAGIC 'V'
|
|
||||||
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH _IOW(AMVIDEOCAP_IOC_MAGIC, 0x02, int)
|
|
||||||
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x03, int)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+// helper class - tries to load the "movie" settings from the script.xbmc.boblight addon
|
|
||||||
+// and pass them to the boblight-aml client
|
|
||||||
+class CBoblightAddonSettings
|
|
||||||
+{
|
|
||||||
+ public:
|
|
||||||
+ CBoblightAddonSettings() : m_bobdisable(false), m_settingsLoaded(false)
|
|
||||||
+ {
|
|
||||||
+ m_settingsLoaded = loadBoblightAddonSettings();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ std::string getBoblightClientCmdLine()
|
|
||||||
+ {
|
|
||||||
+ std::string cmdLine = "";
|
|
||||||
+ //convert bool string to lowercase
|
|
||||||
+ transform(m_interpolation.begin(), m_interpolation.end(), m_interpolation.begin(), ::tolower);
|
|
||||||
+
|
|
||||||
+ cmdLine += "-s " + m_ip + ":" + m_port;
|
|
||||||
+ cmdLine += " -o autospeed=" + m_autospeed;
|
|
||||||
+ cmdLine += " -o interpolation=" + m_interpolation;
|
|
||||||
+ cmdLine += " -o saturation=" + m_saturation;
|
|
||||||
+ cmdLine += " -o speed=" + m_speed;
|
|
||||||
+ cmdLine += " -o threshold=" + m_threshold;
|
|
||||||
+ cmdLine += " -o value=" + m_value;
|
|
||||||
+ return cmdLine;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ bool m_bobdisable;
|
|
||||||
+ bool m_settingsLoaded;
|
|
||||||
+ std::string m_ip;
|
|
||||||
+ std::string m_port;
|
|
||||||
+ std::string m_autospeed;
|
|
||||||
+ std::string m_interpolation;
|
|
||||||
+ std::string m_saturation;
|
|
||||||
+ std::string m_speed;
|
|
||||||
+ std::string m_threshold;
|
|
||||||
+ std::string m_value;
|
|
||||||
+
|
|
||||||
+ private:
|
|
||||||
+ #define SETTINGS_ATTR_BOBDISABLE "bobdisable"
|
|
||||||
+ #define SETTINGS_ATTR_IP "hostip"
|
|
||||||
+ #define SETTINGS_ATTR_PORT "hostport"
|
|
||||||
+ #define SETTINGS_ATTR_AUTOSPEED "movie_autospeed"
|
|
||||||
+ #define SETTINGS_ATTR_INTERPOLATION "movie_interpolation"
|
|
||||||
+ #define SETTINGS_ATTR_SATURATION "movie_saturation"
|
|
||||||
+ #define SETTINGS_ATTR_SPEED "movie_speed"
|
|
||||||
+ #define SETTINGS_ATTR_THRESHOLD "movie_threshold"
|
|
||||||
+ #define SETTINGS_ATTR_VALUE "movie_value"
|
|
||||||
+ #define KODI_HOME_ENV_VAR "HOME"
|
|
||||||
+
|
|
||||||
+ bool loadBoblightAddonSettings()
|
|
||||||
+ {
|
|
||||||
+ bool ret = false;
|
|
||||||
+ char *kodiHome = getenv(KODI_HOME_ENV_VAR);
|
|
||||||
+ //fallback to custom settings file in case boblight addon is not installed
|
|
||||||
+ std::string settingsFile = "/storage/boblight-aml.xml";
|
|
||||||
+
|
|
||||||
+ if (kodiHome != NULL)
|
|
||||||
+ {
|
|
||||||
+ settingsFile = std::string(kodiHome) + "/.kodi/userdata/addon_data/script.xbmc.boblight/settings.xml";
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ FILE *fd = fopen(settingsFile.c_str(), "r");
|
|
||||||
+
|
|
||||||
+ if (fd != NULL)
|
|
||||||
+ {
|
|
||||||
+ fseek(fd, 0, SEEK_END);
|
|
||||||
+ size_t fileSize = ftell(fd);
|
|
||||||
+ fseek(fd, 0, SEEK_SET);
|
|
||||||
+ if (fileSize > 0)
|
|
||||||
+ {
|
|
||||||
+ if (fileSize > 32000)//read 16k max - there shouldn't be a bigger settings.xml from boblight [tm]
|
|
||||||
+ fileSize = 32000;
|
|
||||||
+ char *xmlBuffer = new char[fileSize];
|
|
||||||
+ size_t readCount = fread(xmlBuffer, fileSize, 1, fd);
|
|
||||||
+ fclose(fd);
|
|
||||||
+
|
|
||||||
+ if (readCount == 1)
|
|
||||||
+ {
|
|
||||||
+ parseBoblightSettings(std::string(xmlBuffer));
|
|
||||||
+ ret = true;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ fprintf(stderr, "Failed reading boblight addon settings.xml");
|
|
||||||
+ }
|
|
||||||
+ delete[] xmlBuffer;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ void parseBoblightSettings(std::string xmlBuffer)
|
|
||||||
+ {
|
|
||||||
+ std::string settings_bobdisable_str;
|
|
||||||
+ settings_bobdisable_str = getValueFromXmlBuffer(xmlBuffer, SETTINGS_ATTR_BOBDISABLE);
|
|
||||||
+ if (settings_bobdisable_str == "true" || settings_bobdisable_str == "True")
|
|
||||||
+ m_bobdisable = true;
|
|
||||||
+
|
|
||||||
+ m_ip = getValueFromXmlBuffer(xmlBuffer, SETTINGS_ATTR_IP);
|
|
||||||
+ m_port = getValueFromXmlBuffer(xmlBuffer, SETTINGS_ATTR_PORT);
|
|
||||||
+ m_autospeed = getValueFromXmlBuffer(xmlBuffer, SETTINGS_ATTR_AUTOSPEED);
|
|
||||||
+ m_interpolation = getValueFromXmlBuffer(xmlBuffer, SETTINGS_ATTR_INTERPOLATION);
|
|
||||||
+ m_saturation = getValueFromXmlBuffer(xmlBuffer, SETTINGS_ATTR_SATURATION);
|
|
||||||
+ m_speed = getValueFromXmlBuffer(xmlBuffer, SETTINGS_ATTR_SPEED);
|
|
||||||
+ m_threshold = getValueFromXmlBuffer(xmlBuffer, SETTINGS_ATTR_THRESHOLD);
|
|
||||||
+ m_value = getValueFromXmlBuffer(xmlBuffer, SETTINGS_ATTR_VALUE);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ std::string getValueFromXmlBuffer(const std::string &xmlBuffer, const char* xmlAttribute)
|
|
||||||
+ {
|
|
||||||
+ size_t strPos = 0;
|
|
||||||
+ std::string valueStr;
|
|
||||||
+
|
|
||||||
+ // each line in the xml looks like this:
|
|
||||||
+ // <setting id="movie_value" value="1.000006" />
|
|
||||||
+ // find the attribute
|
|
||||||
+ if ((strPos = xmlBuffer.find(xmlAttribute)) != std::string::npos)
|
|
||||||
+ {
|
|
||||||
+ size_t strPos2 = 0;
|
|
||||||
+ // from movie_value" value="1.000006" /> look for "value"
|
|
||||||
+ if ((strPos2 = xmlBuffer.find("value", strPos)) != std::string::npos)
|
|
||||||
+ {
|
|
||||||
+ size_t strPos3 = 0;
|
|
||||||
+ // from value="1.000006" /> look for "="
|
|
||||||
+ if ((strPos3 = xmlBuffer.find("=", strPos2)) != std::string::npos)
|
|
||||||
+ {
|
|
||||||
+ //extract the value - strPos3 points to ="1.000006"
|
|
||||||
+ int valueOffset = 1; //skip the "="
|
|
||||||
+ if (xmlBuffer[strPos3 + valueOffset] == '"')
|
|
||||||
+ valueOffset++;//skip " if needed
|
|
||||||
+ int strLen = 0;
|
|
||||||
+ do
|
|
||||||
+ {
|
|
||||||
+ // value stops with " or space
|
|
||||||
+ if (xmlBuffer[strPos3 + valueOffset + strLen] == '"' ||
|
|
||||||
+ xmlBuffer[strPos3 + valueOffset + strLen] == ' ')
|
|
||||||
+ break;
|
|
||||||
+ strLen++;
|
|
||||||
+ } while (strLen < 20);// no insane xml garbage ...
|
|
||||||
+
|
|
||||||
+ valueStr = xmlBuffer.substr(strPos3 + valueOffset, strLen);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return valueStr;
|
|
||||||
+ }
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+struct aml_snapshot_t {
|
|
||||||
+ unsigned int dst_width;
|
|
||||||
+ unsigned int dst_height;
|
|
||||||
+ unsigned int dst_stride;
|
|
||||||
+ unsigned int dst_size;
|
|
||||||
+ void *dst_vaddr;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+volatile bool g_stop = false;
|
|
||||||
+CFlagManagerAML g_flagmanager;
|
|
||||||
+/*********************************************************
|
|
||||||
+ *********************************************************/
|
|
||||||
+static void SignalHandler(int signum)
|
|
||||||
+{
|
|
||||||
+ if (signum == SIGTERM)
|
|
||||||
+ {
|
|
||||||
+ fprintf(stderr, "caught SIGTERM\n");
|
|
||||||
+ g_stop = true;
|
|
||||||
+ }
|
|
||||||
+ else if (signum == SIGINT)
|
|
||||||
+ {
|
|
||||||
+ fprintf(stderr, "caught SIGTERM\n");
|
|
||||||
+ g_stop = true;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#define VIDEO_PATH "/dev/amvideo"
|
|
||||||
+#define AMSTREAM_IOC_MAGIC 'S'
|
|
||||||
+#define AMSTREAM_IOC_GET_VIDEO_DISABLE _IOR(AMSTREAM_IOC_MAGIC, 0x48, unsigned long)
|
|
||||||
+static int amvideo_utils_video_playing()
|
|
||||||
+{
|
|
||||||
+ int video_fd;
|
|
||||||
+ int video_disable;
|
|
||||||
+
|
|
||||||
+ video_fd = open(VIDEO_PATH, O_RDWR);
|
|
||||||
+ if (video_fd < 0) {
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ioctl(video_fd, AMSTREAM_IOC_GET_VIDEO_DISABLE, &video_disable);
|
|
||||||
+ if (video_disable)
|
|
||||||
+ {
|
|
||||||
+ close(video_fd);
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ close(video_fd);
|
|
||||||
+
|
|
||||||
+// fprintf(stderr, "pos x %d y %d w %d h %d\n",snapshot.src_x, snapshot.src_y,snapshot.src_width,snapshot.src_height);
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int capture_frame(int fd, aml_snapshot_t &snapshot)
|
|
||||||
+{
|
|
||||||
+ int ret = 0;
|
|
||||||
+
|
|
||||||
+ ssize_t readResult = pread(fd, snapshot.dst_vaddr, snapshot.dst_size, 0);
|
|
||||||
+
|
|
||||||
+ if (readResult < snapshot.dst_size)
|
|
||||||
+ {
|
|
||||||
+ fprintf(stderr, "frame read returned %d\n", readResult);
|
|
||||||
+ }
|
|
||||||
+ //fprintf(stderr, "requ: %d read %d \n", snapshot.dst_size, readResult);
|
|
||||||
+ fprintf(stderr, ".");
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int configure_capture(int fd, aml_snapshot_t &snapshot)
|
|
||||||
+{
|
|
||||||
+ int ret = 0;
|
|
||||||
+ int ioctlret = 0;
|
|
||||||
+
|
|
||||||
+ if ((ioctlret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH, snapshot.dst_width)) != 0)
|
|
||||||
+ {
|
|
||||||
+ ret = 2;
|
|
||||||
+ fprintf(stderr, "Error setting frame width (ret: %d errno: %d)\n", ioctlret, errno);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ if ((ioctlret = ioctl(fd, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, snapshot.dst_height)) != 0)
|
|
||||||
+ {
|
|
||||||
+ ret = 3;
|
|
||||||
+ fprintf(stderr, "Error setting frame height (ret: %d errno: %d)\n", ioctlret, errno);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void frameToboblight(void *boblight, uint8_t* outputptr, int w, int h, int stride)
|
|
||||||
+{
|
|
||||||
+ if (!boblight)
|
|
||||||
+ {
|
|
||||||
+ fprintf(stderr, "no boblight\n");
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ if (!outputptr)
|
|
||||||
+ {
|
|
||||||
+ fprintf(stderr, "no outputptr\n");
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ //read out pixels and hand them to libboblight
|
|
||||||
+ uint8_t* buffptr;
|
|
||||||
+ for (int y = h; y > 0; y--) {
|
|
||||||
+ buffptr = outputptr + stride * y;
|
|
||||||
+ for (int x = 0; x < w; x++) {
|
|
||||||
+ int rgb[3];
|
|
||||||
+ rgb[2] = *(buffptr++);
|
|
||||||
+ rgb[1] = *(buffptr++);
|
|
||||||
+ rgb[0] = *(buffptr++);
|
|
||||||
+
|
|
||||||
+ //fprintf(stdout, "frameToboblight: x(%d), y(%d)\n", x, y);
|
|
||||||
+
|
|
||||||
+ boblight_addpixelxy(boblight, x, y, rgb);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int Run(void* boblight)
|
|
||||||
+{
|
|
||||||
+ int snapshot_fd = -1;
|
|
||||||
+ aml_snapshot_t aml_snapshot = {0};
|
|
||||||
+ int lastPriority = 255;
|
|
||||||
+
|
|
||||||
+ aml_snapshot.dst_width = 160;
|
|
||||||
+ aml_snapshot.dst_height = 160;
|
|
||||||
+
|
|
||||||
+ // calc stride, size and alloc mem
|
|
||||||
+ aml_snapshot.dst_stride = aml_snapshot.dst_width * 3;
|
|
||||||
+ aml_snapshot.dst_size = aml_snapshot.dst_stride * aml_snapshot.dst_height;
|
|
||||||
+ aml_snapshot.dst_vaddr = calloc(aml_snapshot.dst_size, 1);
|
|
||||||
+
|
|
||||||
+ fprintf(stdout, "Connection to boblightd config: width(%d), height(%d)\n",
|
|
||||||
+ aml_snapshot.dst_width, aml_snapshot.dst_height);
|
|
||||||
+ //tell libboblight how big our image is
|
|
||||||
+ boblight_setscanrange(boblight, (int)aml_snapshot.dst_width, (int)aml_snapshot.dst_height);
|
|
||||||
+
|
|
||||||
+ while(!g_stop)
|
|
||||||
+ {
|
|
||||||
+ int64_t bgn = GetTimeUs();
|
|
||||||
+
|
|
||||||
+ if (snapshot_fd == -1) {
|
|
||||||
+ snapshot_fd = open(g_flagmanager.m_device.c_str(), O_RDWR, 0);
|
|
||||||
+
|
|
||||||
+ if (snapshot_fd == -1) {
|
|
||||||
+ sleep(1);
|
|
||||||
+ continue;
|
|
||||||
+ } else {
|
|
||||||
+ fprintf(stdout, "snapshot_fd(%d) \n", snapshot_fd);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // match source ratio if possible
|
|
||||||
+ if (amvideo_utils_video_playing() != 0) {
|
|
||||||
+ if ( lastPriority != 255)
|
|
||||||
+ {
|
|
||||||
+ boblight_setpriority(boblight, 255);
|
|
||||||
+ lastPriority = 255;
|
|
||||||
+ }
|
|
||||||
+ sleep(1);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (configure_capture(snapshot_fd, aml_snapshot) == 0)
|
|
||||||
+ {
|
|
||||||
+ if (capture_frame(snapshot_fd, aml_snapshot) == 0)
|
|
||||||
+ {
|
|
||||||
+ // image to boblight convert.
|
|
||||||
+ frameToboblight(boblight, (uint8_t*)aml_snapshot.dst_vaddr,
|
|
||||||
+ aml_snapshot.dst_width, aml_snapshot.dst_height, aml_snapshot.dst_stride);
|
|
||||||
+
|
|
||||||
+ if (lastPriority != g_flagmanager.m_priority)
|
|
||||||
+ {
|
|
||||||
+ boblight_setpriority(boblight, g_flagmanager.m_priority);
|
|
||||||
+ lastPriority = g_flagmanager.m_priority;
|
|
||||||
+ }
|
|
||||||
+ if (!boblight_sendrgb(boblight, 1, NULL))
|
|
||||||
+ {
|
|
||||||
+ // some error happened, probably connection broken, so bitch and try again
|
|
||||||
+ PrintError(boblight_geterror(boblight));
|
|
||||||
+ boblight_destroy(boblight);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ fprintf(stdout, "nap time\n");
|
|
||||||
+ sleep(1);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ int64_t end = GetTimeUs();
|
|
||||||
+ float calc_time_ms = (float)(end - bgn) / 1000.0;
|
|
||||||
+ // throttle to 100ms max cycle rate
|
|
||||||
+ calc_time_ms -= 100.0;
|
|
||||||
+ if ((int)calc_time_ms < 0)
|
|
||||||
+ usleep((int)(-calc_time_ms * 1000));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // last image is black
|
|
||||||
+ boblight_setpriority(boblight, 255);
|
|
||||||
+ boblight_destroy(boblight);
|
|
||||||
+ close(snapshot_fd);
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*********************************************************
|
|
||||||
+ *********************************************************/
|
|
||||||
+int main(int argc, char *argv[])
|
|
||||||
+{
|
|
||||||
+ //load the boblight lib, if it fails we get a char* from dlerror()
|
|
||||||
+ const char* boblight_error = boblight_loadlibrary(NULL);
|
|
||||||
+ if (boblight_error)
|
|
||||||
+ {
|
|
||||||
+ PrintError(boblight_error);
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ //try to parse the flags and bitch to stderr if there's an error
|
|
||||||
+ try {
|
|
||||||
+ g_flagmanager.ParseFlags(argc, argv);
|
|
||||||
+ }
|
|
||||||
+ catch (string error) {
|
|
||||||
+ PrintError(error);
|
|
||||||
+ g_flagmanager.PrintHelpMessage();
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (g_flagmanager.m_printhelp) {
|
|
||||||
+ g_flagmanager.PrintHelpMessage();
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (g_flagmanager.m_printboblightoptions) {
|
|
||||||
+ g_flagmanager.PrintBoblightOptions();
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // check if we only should generate a cmdline based
|
|
||||||
+ // on settings from possible found boblight addon
|
|
||||||
+ if (g_flagmanager.generateCmdLine)
|
|
||||||
+ {
|
|
||||||
+ CBoblightAddonSettings settings;
|
|
||||||
+ string cmdLine = "-p 100"; //default cmdline just contains priority 100
|
|
||||||
+
|
|
||||||
+ if (settings.m_settingsLoaded)
|
|
||||||
+ cmdLine += " " + settings.getBoblightClientCmdLine();
|
|
||||||
+ fprintf(stdout, "%s", cmdLine.c_str());
|
|
||||||
+ return 0;//exit
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ fprintf(stderr, "Using device: %s \n", g_flagmanager.m_device.c_str());
|
|
||||||
+
|
|
||||||
+ //set up signal handlers
|
|
||||||
+ signal(SIGINT, SignalHandler);
|
|
||||||
+ signal(SIGTERM, SignalHandler);
|
|
||||||
+
|
|
||||||
+ //keep running until we want to quit
|
|
||||||
+ while(!g_stop) {
|
|
||||||
+ //init boblight
|
|
||||||
+ void* boblight = boblight_init();
|
|
||||||
+
|
|
||||||
+ fprintf(stdout, "Connecting to boblightd(%p)\n", boblight);
|
|
||||||
+
|
|
||||||
+ //try to connect, if we can't then bitch to stderr and destroy boblight
|
|
||||||
+ if (!boblight_connect(boblight, g_flagmanager.m_address, g_flagmanager.m_port, 5000000) ||
|
|
||||||
+ !boblight_setpriority(boblight, 255)) {
|
|
||||||
+ PrintError(boblight_geterror(boblight));
|
|
||||||
+ fprintf(stdout, "Waiting 10 seconds before trying again\n");
|
|
||||||
+ boblight_destroy(boblight);
|
|
||||||
+ sleep(2);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ fprintf(stdout, "Connection to boblightd opened\n");
|
|
||||||
+
|
|
||||||
+ //try to parse the boblight flags and bitch to stderr if we can't
|
|
||||||
+ try {
|
|
||||||
+ g_flagmanager.ParseBoblightOptions(boblight);
|
|
||||||
+ }
|
|
||||||
+ catch (string error) {
|
|
||||||
+ PrintError(error);
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ try {
|
|
||||||
+ Run(boblight);
|
|
||||||
+ }
|
|
||||||
+ catch (string error) {
|
|
||||||
+ PrintError(error);
|
|
||||||
+ boblight_destroy(boblight);
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ fprintf(stdout, "Exiting\n");
|
|
||||||
+}
|
|
||||||
diff -urPp src/clients/flagmanager-aml.cpp src/clients/boblight-aml/flagmanager-aml.cpp
|
|
||||||
--- /dev/null Thu Jan 1 00:00:00 1970
|
|
||||||
+++ b/src/clients/boblight-aml/flagmanager-aml.cpp Thu Jan 15 10:21:40 2015
|
|
||||||
@@ -0,0 +1,68 @@
|
|
||||||
+/*
|
|
||||||
+ * boblight
|
|
||||||
+ * Copyright (C) Bob 2009
|
|
||||||
+ *
|
|
||||||
+ * boblight 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 3 of the License, or
|
|
||||||
+ * (at your option) any later version.
|
|
||||||
+ *
|
|
||||||
+ * boblight 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include <iostream>
|
|
||||||
+
|
|
||||||
+#include "flagmanager-aml.h"
|
|
||||||
+#include "util/misc.h"
|
|
||||||
+#include "config.h"
|
|
||||||
+
|
|
||||||
+#define DEFAULT_CAPTURE_DEVICE "/dev/amvideocap0"
|
|
||||||
+
|
|
||||||
+using namespace std;
|
|
||||||
+
|
|
||||||
+CFlagManagerAML::CFlagManagerAML()
|
|
||||||
+{
|
|
||||||
+ // extend the flags -d -> device
|
|
||||||
+ // -g -> only generate cmdline from possible found boblight addon settings.xml
|
|
||||||
+ m_flags += "d:g";
|
|
||||||
+ m_device = DEFAULT_CAPTURE_DEVICE;
|
|
||||||
+ generateCmdLine = false;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void CFlagManagerAML::ParseFlagsExtended(int& argc, char**& argv, int& c, char*& optarg)
|
|
||||||
+{
|
|
||||||
+ if (c == 'd') //devicename
|
|
||||||
+ {
|
|
||||||
+ if (optarg) //optional device
|
|
||||||
+ {
|
|
||||||
+ m_device = optarg;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (c == 'g') //generate cmdline
|
|
||||||
+ {
|
|
||||||
+ generateCmdLine = true;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void CFlagManagerAML::PrintHelpMessage()
|
|
||||||
+{
|
|
||||||
+ cout << "Usage: boblight-aml\n";
|
|
||||||
+ cout << "\n";
|
|
||||||
+ cout << " options:\n";
|
|
||||||
+ cout << "\n";
|
|
||||||
+ cout << " -p priority, from 0 to 255, default is 128\n";
|
|
||||||
+ cout << " -s address[:port], set the address and optional port to connect to\n";
|
|
||||||
+ cout << " -o add libboblight option, syntax: [light:]option=value\n";
|
|
||||||
+ cout << " -l list libboblight options\n";
|
|
||||||
+ cout << " -f fork\n";
|
|
||||||
+ cout << " -d <device> (defaults to " << m_device << ")\n";
|
|
||||||
+ cout << " -g try to find the settings.xml file from boblight addon and return the cmdline to use its options\n";
|
|
||||||
+ cout << "\n";
|
|
||||||
+}
|
|
||||||
diff -urPp src/clients/flagmanager-aml.h src/clients/boblight-aml/flagmanager-aml.h
|
|
||||||
--- /dev/null Thu Jan 1 00:00:00 1970
|
|
||||||
+++ b/src/clients/boblight-aml/flagmanager-aml.h Thu Jan 15 10:20:15 2015
|
|
||||||
@@ -0,0 +1,36 @@
|
|
||||||
+/*
|
|
||||||
+ * boblight
|
|
||||||
+ * Copyright (C) Bob 2009
|
|
||||||
+ *
|
|
||||||
+ * boblight 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 3 of the License, or
|
|
||||||
+ * (at your option) any later version.
|
|
||||||
+ *
|
|
||||||
+ * boblight 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef FLAGMANAGERAML
|
|
||||||
+#define FLAGMANAGERAML
|
|
||||||
+
|
|
||||||
+#include "clients/flagmanager.h"
|
|
||||||
+
|
|
||||||
+class CFlagManagerAML : public CFlagManager
|
|
||||||
+{
|
|
||||||
+ public:
|
|
||||||
+ CFlagManagerAML();
|
|
||||||
+ void ParseFlagsExtended(int& argc, char**& argv, int& c, char*& optarg);
|
|
||||||
+
|
|
||||||
+ void PrintHelpMessage();
|
|
||||||
+ std::string m_device; //device to open for amvideocap
|
|
||||||
+ bool generateCmdLine;
|
|
||||||
+
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+#endif //FLAGMANAGERAML
|
|
||||||
\ No newline at end of file
|
|
||||||
@@ -18,10 +18,4 @@ if [ -x $ADDON_DIR/bin/boblight-X11 -a -e $ADDON_HOME/boblight.X11 ] ; then
|
|||||||
boblight-X11 -f >/dev/null 2>&1
|
boblight-X11 -f >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -x $ADDON_DIR/bin/boblight-aml -a -e /dev/amvideocap0 ] ; then
|
|
||||||
#generates cmdline from boblight addon settings
|
|
||||||
CMDLINE=`boblight-aml -g`
|
|
||||||
boblight-aml $CMDLINE >/dev/null 2>&1 &
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec boblightd -c $ADDON_HOME/boblight.conf > $ADDON_LOG_FILE 2>&1
|
exec boblightd -c $ADDON_HOME/boblight.conf > $ADDON_LOG_FILE 2>&1
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
126
|
||||||
|
- Update to docker 18.09.7
|
||||||
|
|
||||||
125
|
125
|
||||||
- Update to docker 18.09.5
|
- Update to docker 18.09.5
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,10 @@
|
|||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="docker"
|
PKG_NAME="docker"
|
||||||
PKG_VERSION="18.09.5"
|
PKG_VERSION="18.09.7"
|
||||||
PKG_SHA256="57f2a5d3374d86a8eb680c91df4351f5cb648351b9b32520c6fd2d66e7e97fd5"
|
PKG_SHA256="f05dc15f5c11635472534c3aaf759c39c1bba842dd1ac23059431c2fd1ae1795"
|
||||||
PKG_REV="125"
|
PKG_REV="126"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_ADDON_PROJECTS="any !WeTek_Core !WeTek_Play"
|
|
||||||
PKG_LICENSE="ASL"
|
PKG_LICENSE="ASL"
|
||||||
PKG_SITE="http://www.docker.com/"
|
PKG_SITE="http://www.docker.com/"
|
||||||
PKG_URL="https://github.com/docker/docker-ce/archive/v${PKG_VERSION}.tar.gz"
|
PKG_URL="https://github.com/docker/docker-ce/archive/v${PKG_VERSION}.tar.gz"
|
||||||
|
|||||||
@@ -1,8 +1,25 @@
|
|||||||
From 9979cbaa4d0108da552fd452294788a042766995 Mon Sep 17 00:00:00 2001
|
From de25daa9281709a90e4dc23b4c27cbcdcef32fd3 Mon Sep 17 00:00:00 2001
|
||||||
From: 5schatten <supervisedthinking@gmail.com>
|
From: 5schatten <supervisedthinking@gmail.com>
|
||||||
Date: Wed, 7 Nov 2018 12:22:23 +0100
|
Date: Sat, 29 Jun 2019 17:58:09 +0200
|
||||||
Subject: [PATCH] use Kodi addon storage location
|
Subject: [PATCH] use Kodi addon storage location
|
||||||
|
|
||||||
|
---
|
||||||
|
.../github.com/docker/docker/registry/config_unix.go | 2 +-
|
||||||
|
.../github.com/docker/docker/registry/endpoint_v1.go | 2 +-
|
||||||
|
components/engine/cmd/dockerd/daemon_unix.go | 4 ++--
|
||||||
|
components/engine/daemon/config/config_test.go | 2 +-
|
||||||
|
.../engine/integration-cli/docker_cli_daemon_test.go | 12 ++++++------
|
||||||
|
.../docker_cli_external_volume_driver_unix_test.go | 8 ++++----
|
||||||
|
.../integration-cli/docker_cli_network_unix_test.go | 8 ++++----
|
||||||
|
.../engine/integration-cli/docker_cli_swarm_test.go | 8 ++++----
|
||||||
|
.../integration/plugin/authz/authz_plugin_test.go | 6 +++---
|
||||||
|
.../integration/plugin/graphdriver/external_test.go | 6 +++---
|
||||||
|
components/engine/pkg/plugins/discovery_unix.go | 2 +-
|
||||||
|
components/engine/pkg/plugins/plugins.go | 2 +-
|
||||||
|
components/engine/registry/config_unix.go | 2 +-
|
||||||
|
components/engine/registry/endpoint_v1.go | 2 +-
|
||||||
|
14 files changed, 33 insertions(+), 33 deletions(-)
|
||||||
|
|
||||||
diff --git a/components/cli/vendor/github.com/docker/docker/registry/config_unix.go b/components/cli/vendor/github.com/docker/docker/registry/config_unix.go
|
diff --git a/components/cli/vendor/github.com/docker/docker/registry/config_unix.go b/components/cli/vendor/github.com/docker/docker/registry/config_unix.go
|
||||||
index 20fb47bcae..a023df7895 100644
|
index 20fb47bcae..a023df7895 100644
|
||||||
--- a/components/cli/vendor/github.com/docker/docker/registry/config_unix.go
|
--- a/components/cli/vendor/github.com/docker/docker/registry/config_unix.go
|
||||||
@@ -65,7 +82,7 @@ index 6998ed3312..c255b62146 100644
|
|||||||
flags.String("config-file", configFile, "")
|
flags.String("config-file", configFile, "")
|
||||||
err := Reload(configFile, flags, func(c *Config) {
|
err := Reload(configFile, flags, func(c *Config) {
|
||||||
diff --git a/components/engine/integration-cli/docker_cli_daemon_test.go b/components/engine/integration-cli/docker_cli_daemon_test.go
|
diff --git a/components/engine/integration-cli/docker_cli_daemon_test.go b/components/engine/integration-cli/docker_cli_daemon_test.go
|
||||||
index 986cc27530..7a0c2805cd 100644
|
index d3cd5f1676..b5e504489d 100644
|
||||||
--- a/components/engine/integration-cli/docker_cli_daemon_test.go
|
--- a/components/engine/integration-cli/docker_cli_daemon_test.go
|
||||||
+++ b/components/engine/integration-cli/docker_cli_daemon_test.go
|
+++ b/components/engine/integration-cli/docker_cli_daemon_test.go
|
||||||
@@ -546,11 +546,11 @@ func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *check.C) {
|
@@ -546,11 +546,11 @@ func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *check.C) {
|
||||||
@@ -121,11 +138,11 @@ index da8bb7e011..605a162e79 100644
|
|||||||
|
|
||||||
- err := os.MkdirAll("/etc/docker/plugins", 0755)
|
- err := os.MkdirAll("/etc/docker/plugins", 0755)
|
||||||
+ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755)
|
+ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755)
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
|
|
||||||
- err = ioutil.WriteFile("/etc/docker/plugins/"+name+".spec", []byte(s.Server.URL), 0644)
|
- err = ioutil.WriteFile("/etc/docker/plugins/"+name+".spec", []byte(s.Server.URL), 0644)
|
||||||
+ err = ioutil.WriteFile("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/"+name+".spec", []byte(s.Server.URL), 0644)
|
+ err = ioutil.WriteFile("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/"+name+".spec", []byte(s.Server.URL), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@@ -278,7 +278,7 @@ func newVolumePlugin(c *check.C, name string) *volumePlugin {
|
@@ -278,7 +278,7 @@ func newVolumePlugin(c *check.C, name string) *volumePlugin {
|
||||||
@@ -134,7 +151,7 @@ index da8bb7e011..605a162e79 100644
|
|||||||
|
|
||||||
- err := os.RemoveAll("/etc/docker/plugins")
|
- err := os.RemoveAll("/etc/docker/plugins")
|
||||||
+ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins")
|
+ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins")
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +371,7 @@ func hostVolumePath(name string) string {
|
@@ -371,7 +371,7 @@ func hostVolumePath(name string) string {
|
||||||
@@ -156,17 +173,17 @@ index d3d6256a75..a0f0ae973d 100644
|
|||||||
|
|
||||||
- err := os.MkdirAll("/etc/docker/plugins", 0755)
|
- err := os.MkdirAll("/etc/docker/plugins", 0755)
|
||||||
+ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755)
|
+ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755)
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
|
|
||||||
- fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv)
|
- fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv)
|
||||||
+ fileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", netDrv)
|
+ fileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", netDrv)
|
||||||
err = ioutil.WriteFile(fileName, []byte(url), 0644)
|
err = ioutil.WriteFile(fileName, []byte(url), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
|
|
||||||
- ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv)
|
- ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv)
|
||||||
+ ipamFileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", ipamDrv)
|
+ ipamFileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", ipamDrv)
|
||||||
err = ioutil.WriteFile(ipamFileName, []byte(url), 0644)
|
err = ioutil.WriteFile(ipamFileName, []byte(url), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ func (s *DockerNetworkSuite) TearDownSuite(c *check.C) {
|
@@ -227,7 +227,7 @@ func (s *DockerNetworkSuite) TearDownSuite(c *check.C) {
|
||||||
|
|
||||||
@@ -174,11 +191,11 @@ index d3d6256a75..a0f0ae973d 100644
|
|||||||
|
|
||||||
- err := os.RemoveAll("/etc/docker/plugins")
|
- err := os.RemoveAll("/etc/docker/plugins")
|
||||||
+ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins")
|
+ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins")
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/components/engine/integration-cli/docker_cli_swarm_test.go b/components/engine/integration-cli/docker_cli_swarm_test.go
|
diff --git a/components/engine/integration-cli/docker_cli_swarm_test.go b/components/engine/integration-cli/docker_cli_swarm_test.go
|
||||||
index 9f99d0c849..2d9a4b088e 100644
|
index f6fadcf995..5d0b5256c1 100644
|
||||||
--- a/components/engine/integration-cli/docker_cli_swarm_test.go
|
--- a/components/engine/integration-cli/docker_cli_swarm_test.go
|
||||||
+++ b/components/engine/integration-cli/docker_cli_swarm_test.go
|
+++ b/components/engine/integration-cli/docker_cli_swarm_test.go
|
||||||
@@ -783,14 +783,14 @@ func setupRemoteGlobalNetworkPlugin(c *check.C, mux *http.ServeMux, url, netDrv,
|
@@ -783,14 +783,14 @@ func setupRemoteGlobalNetworkPlugin(c *check.C, mux *http.ServeMux, url, netDrv,
|
||||||
@@ -187,17 +204,17 @@ index 9f99d0c849..2d9a4b088e 100644
|
|||||||
|
|
||||||
- err := os.MkdirAll("/etc/docker/plugins", 0755)
|
- err := os.MkdirAll("/etc/docker/plugins", 0755)
|
||||||
+ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755)
|
+ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755)
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
|
|
||||||
- fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv)
|
- fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv)
|
||||||
+ fileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", netDrv)
|
+ fileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", netDrv)
|
||||||
err = ioutil.WriteFile(fileName, []byte(url), 0644)
|
err = ioutil.WriteFile(fileName, []byte(url), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
|
|
||||||
- ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv)
|
- ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv)
|
||||||
+ ipamFileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", ipamDrv)
|
+ ipamFileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", ipamDrv)
|
||||||
err = ioutil.WriteFile(ipamFileName, []byte(url), 0644)
|
err = ioutil.WriteFile(ipamFileName, []byte(url), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
}
|
}
|
||||||
@@ -802,7 +802,7 @@ func (s *DockerSwarmSuite) TestSwarmNetworkPlugin(c *check.C) {
|
@@ -802,7 +802,7 @@ func (s *DockerSwarmSuite) TestSwarmNetworkPlugin(c *check.C) {
|
||||||
setupRemoteGlobalNetworkPlugin(c, mux, s.server.URL, globalNetworkPlugin, globalIPAMPlugin)
|
setupRemoteGlobalNetworkPlugin(c, mux, s.server.URL, globalNetworkPlugin, globalIPAMPlugin)
|
||||||
@@ -205,11 +222,11 @@ index 9f99d0c849..2d9a4b088e 100644
|
|||||||
s.server.Close()
|
s.server.Close()
|
||||||
- err := os.RemoveAll("/etc/docker/plugins")
|
- err := os.RemoveAll("/etc/docker/plugins")
|
||||||
+ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins")
|
+ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins")
|
||||||
c.Assert(err, checker.IsNil)
|
assert.NilError(c, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
diff --git a/components/engine/integration/plugin/authz/authz_plugin_test.go b/components/engine/integration/plugin/authz/authz_plugin_test.go
|
diff --git a/components/engine/integration/plugin/authz/authz_plugin_test.go b/components/engine/integration/plugin/authz/authz_plugin_test.go
|
||||||
index d0f5d8a783..ba626c6310 100644
|
index 105affc1af..fa631a377a 100644
|
||||||
--- a/components/engine/integration/plugin/authz/authz_plugin_test.go
|
--- a/components/engine/integration/plugin/authz/authz_plugin_test.go
|
||||||
+++ b/components/engine/integration/plugin/authz/authz_plugin_test.go
|
+++ b/components/engine/integration/plugin/authz/authz_plugin_test.go
|
||||||
@@ -55,15 +55,15 @@ func setupTestV1(t *testing.T) func() {
|
@@ -55,15 +55,15 @@ func setupTestV1(t *testing.T) func() {
|
||||||
@@ -268,7 +285,7 @@ index 58058f2828..a7b449ca25 100644
|
|||||||
-var specsPaths = []string{"/etc/docker/plugins", "/usr/lib/docker/plugins"}
|
-var specsPaths = []string{"/etc/docker/plugins", "/usr/lib/docker/plugins"}
|
||||||
+var specsPaths = []string{"/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", "/usr/lib/docker/plugins"}
|
+var specsPaths = []string{"/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", "/usr/lib/docker/plugins"}
|
||||||
diff --git a/components/engine/pkg/plugins/plugins.go b/components/engine/pkg/plugins/plugins.go
|
diff --git a/components/engine/pkg/plugins/plugins.go b/components/engine/pkg/plugins/plugins.go
|
||||||
index 28c06ff693..c24cad2b63 100644
|
index 6962079df9..77b69265b1 100644
|
||||||
--- a/components/engine/pkg/plugins/plugins.go
|
--- a/components/engine/pkg/plugins/plugins.go
|
||||||
+++ b/components/engine/pkg/plugins/plugins.go
|
+++ b/components/engine/pkg/plugins/plugins.go
|
||||||
@@ -4,7 +4,7 @@
|
@@ -4,7 +4,7 @@
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
103
|
||||||
|
- Update to 4.1.1.0
|
||||||
|
|
||||||
102
|
102
|
||||||
- Update to 4.1.0.26
|
- Update to 4.1.0.26
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="emby4"
|
PKG_NAME="emby4"
|
||||||
PKG_VERSION="4.1.0.26"
|
PKG_VERSION="4.1.1.0"
|
||||||
PKG_SHA256="ccb9bb463e6ff5e084f731ccbb48119176cdc3592b3234796eefa09ec9e03e0f"
|
PKG_SHA256="f89f9b2b3355a0674101834b36aa328822918bea5d466525634c50da0093c241"
|
||||||
PKG_REV="102"
|
PKG_REV="103"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="prop."
|
PKG_LICENSE="prop."
|
||||||
PKG_SITE="http://emby.media"
|
PKG_SITE="http://emby.media"
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
110
|
|
||||||
- Rewrite add-on from scratch
|
|
||||||
- Add support for APPS, SETUP, CVBS (X92) and POWER (A1 Max) indicators.
|
|
||||||
- Add a configuration dialog:
|
|
||||||
* Adjust display brightness.
|
|
||||||
* Storage access indication.
|
|
||||||
* Advanced hardware configuration of the display.
|
|
||||||
- Fix crash if aml_fd628 module is not loaded (led_on, led_off files don't exist)
|
|
||||||
- Fix disable add-on from Kodi UI.
|
|
||||||
- Turn off indicators when add-on is disabled.
|
|
||||||
|
|
||||||
100
|
|
||||||
- Initial add-on
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 31 KiB |
@@ -1,30 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
PKG_NAME="fd628"
|
|
||||||
PKG_VERSION="1.1"
|
|
||||||
PKG_REV="100"
|
|
||||||
PKG_ARCH="any"
|
|
||||||
PKG_LICENSE="GPL"
|
|
||||||
PKG_SITE="https://libreelec.tv"
|
|
||||||
PKG_URL=""
|
|
||||||
PKG_DEPENDS_TARGET="toolchain"
|
|
||||||
PKG_SECTION="service"
|
|
||||||
PKG_SHORTDESC="fd628: Kodi service to light up additional icons on devices with FD628 display"
|
|
||||||
PKG_LONGDESC="fd628: Kodi service to light up additional icons on devices with FD628 display"
|
|
||||||
PKG_TOOLCHAIN="manual"
|
|
||||||
|
|
||||||
PKG_IS_ADDON="yes"
|
|
||||||
PKG_ADDON_NAME="service.fd628"
|
|
||||||
PKG_ADDON_PROJECTS="S905 S912"
|
|
||||||
PKG_ADDON_TYPE="xbmc.service"
|
|
||||||
|
|
||||||
make_target() {
|
|
||||||
sed -e "s|@PKG_VERSION@|$PKG_VERSION|g" \
|
|
||||||
-i addon.xml
|
|
||||||
}
|
|
||||||
|
|
||||||
addon() {
|
|
||||||
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID
|
|
||||||
cp -R $PKG_BUILD/* $ADDON_BUILD/$PKG_ADDON_ID
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<addon id="service.fd628"
|
|
||||||
name="FD628 Display"
|
|
||||||
version="@PKG_VERSION@"
|
|
||||||
provider-name="Team LibreELEC">
|
|
||||||
<requires>
|
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
|
||||||
</requires>
|
|
||||||
<extension point="xbmc.service"
|
|
||||||
library="resources/lib/service.py"
|
|
||||||
start="startup">
|
|
||||||
</extension>
|
|
||||||
<extension point="xbmc.addon.metadata">
|
|
||||||
<summary>Service for controlling FD628 VFD display icons</summary>
|
|
||||||
<description>Service for controlling FD628 VFD display icons, e.g. Ethernet/WiFi connection status and Time</description>
|
|
||||||
<platform>all</platform>
|
|
||||||
<assets>
|
|
||||||
<icon>resources/icon.png</icon>
|
|
||||||
</assets>
|
|
||||||
</extension>
|
|
||||||
</addon>
|
|
||||||
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
# Kodi Media Center language file
|
|
||||||
# Addon Name: FD628 Display
|
|
||||||
# Addon id: service.fd628
|
|
||||||
# Addon Provider: Team LibreELEC
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: XBMC-Addons\n"
|
|
||||||
"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
|
|
||||||
"POT-Creation-Date: 2018-02-12 17:48+0200\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
||||||
"Language-Team: LANGUAGE\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"Language: en_GB\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
|
||||||
|
|
||||||
# Kodi Settings
|
|
||||||
msgctxt "#30000"
|
|
||||||
msgid "General"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30001"
|
|
||||||
msgid "Turn on display"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30002"
|
|
||||||
msgid "Display brightness"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30003"
|
|
||||||
msgid "Advanced settings"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30004"
|
|
||||||
msgid "Display type"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30026"
|
|
||||||
msgid "Common anode display (transposed ram)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30013"
|
|
||||||
msgid "Enable storage access (RW) indicator"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30014"
|
|
||||||
msgid "Select which icon is to be used as the access indicator"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30028"
|
|
||||||
msgid "Clock colon (:) always on"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30015"
|
|
||||||
msgid "play"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30016"
|
|
||||||
msgid "pause"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30017"
|
|
||||||
msgid "hdmi"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30018"
|
|
||||||
msgid "cvbs"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30019"
|
|
||||||
msgid "eth"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30020"
|
|
||||||
msgid "wifi"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30021"
|
|
||||||
msgid "setup"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30022"
|
|
||||||
msgid "apps"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30023"
|
|
||||||
msgid "usb"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30024"
|
|
||||||
msgid "sd"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30025"
|
|
||||||
msgid "alarm"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30027"
|
|
||||||
msgid "power"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30012"
|
|
||||||
msgid "Reorder character indexes"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30005"
|
|
||||||
msgid "Index 0"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30006"
|
|
||||||
msgid "Index 1"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30007"
|
|
||||||
msgid "Index 2"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30008"
|
|
||||||
msgid "Index 3"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30009"
|
|
||||||
msgid "Index 4"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30010"
|
|
||||||
msgid "Index 5"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30011"
|
|
||||||
msgid "Index 6"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# Max index 30028
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import os
|
|
||||||
import struct
|
|
||||||
from fd628utils import *
|
|
||||||
|
|
||||||
_led_cmd = '/sys/class/leds/le-vfd/led_cmd'
|
|
||||||
|
|
||||||
class fd628Dev:
|
|
||||||
def __init__(self):
|
|
||||||
import ioctl
|
|
||||||
import ctypes
|
|
||||||
size = ctypes.sizeof(ctypes.c_int(0))
|
|
||||||
self._FD628_IOC_MAGIC = ord('M')
|
|
||||||
self._FD628_IOC_SMODE = ioctl.IOW(self._FD628_IOC_MAGIC, 1, size)
|
|
||||||
self._FD628_IOC_GMODE = ioctl.IOR(self._FD628_IOC_MAGIC, 2, size)
|
|
||||||
self._FD628_IOC_SBRIGHT = ioctl.IOW(self._FD628_IOC_MAGIC, 3, size)
|
|
||||||
self._FD628_IOC_GBRIGHT = ioctl.IOR(self._FD628_IOC_MAGIC, 4, size)
|
|
||||||
self._FD628_IOC_POWER = ioctl.IOW(self._FD628_IOC_MAGIC, 5, size)
|
|
||||||
self._FD628_IOC_GVER = ioctl.IOR(self._FD628_IOC_MAGIC, 6, size)
|
|
||||||
self._FD628_IOC_STATUS_LED = ioctl.IOW(self._FD628_IOC_MAGIC, 7, size)
|
|
||||||
self._FD628_IOC_GDISPLAY_TYPE = ioctl.IOR(self._FD628_IOC_MAGIC, 8, size)
|
|
||||||
self._FD628_IOC_SDISPLAY_TYPE = ioctl.IOW(self._FD628_IOC_MAGIC, 9, size)
|
|
||||||
self._FD628_IOC_SCHARS_ORDER = ioctl.IOW(self._FD628_IOC_MAGIC, 10, 7)
|
|
||||||
self._FD628_IOC_USE_DTB_CONFIG = ioctl.IOW(self._FD628_IOC_MAGIC, 11, size)
|
|
||||||
self._FD628_IOC_MAXNR = 12
|
|
||||||
|
|
||||||
def enableDisplay(self, value):
|
|
||||||
self.__writeFD628(self._FD628_IOC_POWER, int(value))
|
|
||||||
|
|
||||||
def getBrightness(self):
|
|
||||||
return self.__readFD628(self._FD628_IOC_GBRIGHT)
|
|
||||||
|
|
||||||
def setBrightness(self, value):
|
|
||||||
self.__writeFD628(self._FD628_IOC_SBRIGHT, value)
|
|
||||||
|
|
||||||
def getDisplayType(self):
|
|
||||||
return self.__readFD628(self._FD628_IOC_GDISPLAY_TYPE)
|
|
||||||
|
|
||||||
def setDisplayType(self, value):
|
|
||||||
self.__writeFD628(self._FD628_IOC_SDISPLAY_TYPE, value)
|
|
||||||
|
|
||||||
def setCharacterOrder(self, value):
|
|
||||||
pack = struct.pack('BBBBBBB', value[0], value[1], value[2], value[3], value[4], value[5], value[6])
|
|
||||||
self.__writeFD628(self._FD628_IOC_SCHARS_ORDER, pack, True)
|
|
||||||
|
|
||||||
def useDtbConfig(self):
|
|
||||||
self.__writeFD628(self._FD628_IOC_USE_DTB_CONFIG, 0)
|
|
||||||
|
|
||||||
def __readFD628(self, cmd, isBuf = False):
|
|
||||||
import ioctl
|
|
||||||
ret = None
|
|
||||||
if (ioctl.DIR(cmd) == ioctl.READ and self.__writeFD628(cmd, 0)):
|
|
||||||
with open(_led_cmd, "rb") as vfd:
|
|
||||||
ret = vfd.read()
|
|
||||||
if (ret == ''):
|
|
||||||
ret = None
|
|
||||||
if (not isBuf and ret != None):
|
|
||||||
ret = int(ret, 0)
|
|
||||||
kodiLog('fd628Dev.__readFD628: value = {0}'.format(str(ret)))
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __writeFD628(self, cmd, value, isBuf = False):
|
|
||||||
ret = False
|
|
||||||
if (os.path.isfile(_led_cmd)):
|
|
||||||
if isBuf:
|
|
||||||
value = ''.join([struct.pack('I', cmd), value])
|
|
||||||
else:
|
|
||||||
value = struct.pack('Ii', cmd, value)
|
|
||||||
kodiLog('fd628Dev.__writeFD628: value = {0}'.format(repr(value)))
|
|
||||||
try:
|
|
||||||
with open(_led_cmd, "wb") as vfd:
|
|
||||||
vfd.write(value)
|
|
||||||
ret = True
|
|
||||||
except Exception as inst:
|
|
||||||
kodiLogError(inst)
|
|
||||||
return ret
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmcaddon
|
|
||||||
|
|
||||||
addon = xbmcaddon.Addon(id='service.fd628')
|
|
||||||
|
|
||||||
def getSetting(id):
|
|
||||||
return addon.getSetting(id)
|
|
||||||
|
|
||||||
def getSettingBool(id):
|
|
||||||
value = getSetting(id).lower()
|
|
||||||
if (value == 'true'):
|
|
||||||
value = True
|
|
||||||
else:
|
|
||||||
value = False
|
|
||||||
return value
|
|
||||||
|
|
||||||
def getSettingInt(id):
|
|
||||||
return int(getSetting(id))
|
|
||||||
|
|
||||||
def getSettingNumber(id):
|
|
||||||
return float(getSetting(id))
|
|
||||||
|
|
||||||
class fd628Settings:
|
|
||||||
def __init__(self):
|
|
||||||
self.readValues()
|
|
||||||
|
|
||||||
def isDisplayOn(self):
|
|
||||||
return self._displayOn
|
|
||||||
|
|
||||||
def isAdvancedSettings(self):
|
|
||||||
return self._displayAdvanced
|
|
||||||
|
|
||||||
def getBrightness(self):
|
|
||||||
return self._displayBrightness
|
|
||||||
|
|
||||||
def getDisplayType(self):
|
|
||||||
return self._displayType
|
|
||||||
|
|
||||||
def isCommonAnode(self):
|
|
||||||
return self._commonAnode
|
|
||||||
|
|
||||||
def getDisplay(self):
|
|
||||||
value = self.getDisplayType()
|
|
||||||
if (self.isCommonAnode()):
|
|
||||||
value = value + (1 << 16)
|
|
||||||
return value
|
|
||||||
|
|
||||||
def getCharacterIndex(self, i):
|
|
||||||
return self._characterIndexes[i]
|
|
||||||
|
|
||||||
def getCharacterIndexes(self):
|
|
||||||
return self._characterIndexes
|
|
||||||
|
|
||||||
def isStorageIndicator(self):
|
|
||||||
return self._storageIndicator
|
|
||||||
|
|
||||||
def getStorageIndicatorIcon(self):
|
|
||||||
return self._storageIndicatorIcon
|
|
||||||
|
|
||||||
def isColonOn(self):
|
|
||||||
return self._colonOn
|
|
||||||
|
|
||||||
def readValues(self):
|
|
||||||
self._displayAdvanced = False
|
|
||||||
self._displayOn = getSettingBool('display.on')
|
|
||||||
if (self._displayOn):
|
|
||||||
self._displayBrightness = getSettingInt('display.brightness')
|
|
||||||
self._storageIndicator = getSettingBool('display.storage.indicator')
|
|
||||||
self._storageIndicatorIcon = getSetting('display.storage.indicator.icon')
|
|
||||||
self._colonOn = getSettingBool('display.colon.on')
|
|
||||||
self._displayAdvanced = getSettingBool('display.advanced')
|
|
||||||
if (self._displayAdvanced):
|
|
||||||
self._displayType = getSettingInt('display.type')
|
|
||||||
self._commonAnode = getSettingBool('display.common.anode')
|
|
||||||
self._characterIndexes = []
|
|
||||||
for i in range(7):
|
|
||||||
self._characterIndexes.append(getSettingInt('display.char.index{0}'.format(i)))
|
|
||||||
else:
|
|
||||||
self.__initDefaultValues()
|
|
||||||
else:
|
|
||||||
self.__initDefaultValues()
|
|
||||||
|
|
||||||
def __initDefaultValues(self):
|
|
||||||
if not (self._displayOn):
|
|
||||||
self._displayBrightness = 7
|
|
||||||
self._storageIndicator = False
|
|
||||||
self._storageIndicatorIcon = ''
|
|
||||||
self._colonOn = False
|
|
||||||
self._displayAdvanced = False
|
|
||||||
if not (self._displayAdvanced):
|
|
||||||
self._displayType = 0
|
|
||||||
self._commonAnode = False
|
|
||||||
self._characterIndexes = range(0, 7)
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmc
|
|
||||||
import os
|
|
||||||
from fd628utils import *
|
|
||||||
|
|
||||||
class fd628State(object):
|
|
||||||
def __init__(self, ledName):
|
|
||||||
self._value = False
|
|
||||||
self._hasChanged = False
|
|
||||||
self._ledName = ledName
|
|
||||||
|
|
||||||
def _getStr(self, className):
|
|
||||||
return '{0} ({1})'.format(className, self._ledName)
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def getValue(self):
|
|
||||||
return self._value
|
|
||||||
|
|
||||||
def hasChanged(self):
|
|
||||||
return self._hasChanged
|
|
||||||
|
|
||||||
def getLedName(self):
|
|
||||||
return self._ledName
|
|
||||||
|
|
||||||
def _update(self, value):
|
|
||||||
if (value != self._value):
|
|
||||||
self._hasChanged = True
|
|
||||||
self._value = value
|
|
||||||
else:
|
|
||||||
self._hasChanged = False
|
|
||||||
|
|
||||||
class fd628IconIndicator(fd628State):
|
|
||||||
def __init__(self, on, ledName):
|
|
||||||
super(fd628IconIndicator, self).__init__(ledName)
|
|
||||||
self._on = on
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628IconIndicator')
|
|
||||||
|
|
||||||
def turnOn(self):
|
|
||||||
self._on = True
|
|
||||||
|
|
||||||
def turnOff(self):
|
|
||||||
self._on = False
|
|
||||||
|
|
||||||
def toggle(self):
|
|
||||||
self._on = not self._on
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
self._update(self._on)
|
|
||||||
|
|
||||||
class fd628CondVisibility(fd628State):
|
|
||||||
def __init__(self, ledName, cmd):
|
|
||||||
super(fd628CondVisibility, self).__init__(ledName)
|
|
||||||
self._cmd = cmd
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628CondVisibility')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
value = xbmc.getCondVisibility(self._cmd)
|
|
||||||
self._update(value)
|
|
||||||
|
|
||||||
class fd628FileContains(fd628State):
|
|
||||||
def __init__(self, ledName, path, strings):
|
|
||||||
super(fd628FileContains, self).__init__(ledName)
|
|
||||||
self._path = path
|
|
||||||
self._strings = strings
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628FileContains')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
if (os.path.isfile(self._path)):
|
|
||||||
with open(self._path, 'rb') as state:
|
|
||||||
content = state.read()
|
|
||||||
value = self.__checkContent(content)
|
|
||||||
self._update(value)
|
|
||||||
else:
|
|
||||||
self._update(False)
|
|
||||||
|
|
||||||
def __checkContent(self, content):
|
|
||||||
ret = False
|
|
||||||
for s in self._strings:
|
|
||||||
if (s in content):
|
|
||||||
ret = True
|
|
||||||
break
|
|
||||||
return ret
|
|
||||||
|
|
||||||
class fd628WindowChecker(fd628State):
|
|
||||||
def __init__(self, ledName, windows):
|
|
||||||
super(fd628WindowChecker, self).__init__(ledName)
|
|
||||||
self._windows = windows
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628WindowChecker')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
value = False
|
|
||||||
for id in self._windows:
|
|
||||||
if (xbmc.getCondVisibility('Window.IsVisible({0})'.format(id))):
|
|
||||||
value = True
|
|
||||||
break
|
|
||||||
self._update(value)
|
|
||||||
|
|
||||||
class fd628ExtStorageChecker(fd628State):
|
|
||||||
def __init__(self, ledName, path):
|
|
||||||
super(fd628ExtStorageChecker, self).__init__(ledName)
|
|
||||||
self._path = path
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628ExtStorageChecker')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
value = False
|
|
||||||
for folder, subs, files in os.walk('/dev/disk/by-uuid'):
|
|
||||||
for filename in files:
|
|
||||||
path = os.path.realpath(os.path.join(folder, filename))
|
|
||||||
if (path.startswith(self._path)):
|
|
||||||
value = True
|
|
||||||
break
|
|
||||||
self._update(value)
|
|
||||||
|
|
||||||
class fd628ExtStorageCount(fd628State):
|
|
||||||
def __init__(self, ledName, drives, type):
|
|
||||||
super(fd628ExtStorageCount, self).__init__(ledName)
|
|
||||||
if (drives == None): # Monitor all drives
|
|
||||||
self._drives = None
|
|
||||||
drives = self.__getAllDrives()
|
|
||||||
else: # Monitor listed drives
|
|
||||||
self._drives = drives
|
|
||||||
drives = self.__getSelectedDrives()
|
|
||||||
self._driveStats = {key: self.__readStatus(key) for key in drives}
|
|
||||||
kodiLogNotice('fd628ExtStorageCount.__init__: Drive stats ' + str(self._driveStats))
|
|
||||||
self._read = False
|
|
||||||
self._write = False
|
|
||||||
if (type == 'r'):
|
|
||||||
self._read = True
|
|
||||||
elif (type == 'w'):
|
|
||||||
self._write = True
|
|
||||||
elif (type == 'rw'):
|
|
||||||
self._read = True
|
|
||||||
self._write = True
|
|
||||||
else:
|
|
||||||
raise Exception('\'type\' must be \'r\', \'w\' or \'rw\'.')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
value = False
|
|
||||||
if (self._drives == None):
|
|
||||||
drives = self.__getAllDrives()
|
|
||||||
else:
|
|
||||||
drives = self.__getSelectedDrives()
|
|
||||||
for drive in drives:
|
|
||||||
if (not drive in self._driveStats):
|
|
||||||
self._driveStats[drive] = None
|
|
||||||
kodiLogNotice('fd628ExtStorageCount.update: New drive found \'{0}\''.format(drive))
|
|
||||||
for path, stats in self._driveStats.iteritems():
|
|
||||||
newStats = self.__readStatus(path)
|
|
||||||
if (stats != None and newStats != None):
|
|
||||||
if (self._read):
|
|
||||||
value = value or stats[0] != newStats[0]
|
|
||||||
if (self._write):
|
|
||||||
value = value or stats[1] != newStats[1]
|
|
||||||
self._driveStats[path] = newStats
|
|
||||||
self._update(value)
|
|
||||||
|
|
||||||
def __readStatus(self, path):
|
|
||||||
path = os.path.join('/sys/block', path, 'stat')
|
|
||||||
if (os.path.isfile(path)):
|
|
||||||
with open(path, 'rb') as status:
|
|
||||||
values = status.read().split()
|
|
||||||
return (values[2], values[6])
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __getAllDrives(self):
|
|
||||||
drives = []
|
|
||||||
for folder, subs, files in os.walk('/sys/block'):
|
|
||||||
drives = [sub for sub in subs if (not sub.startswith('loop'))]
|
|
||||||
return drives
|
|
||||||
|
|
||||||
def __getSelectedDrives(self):
|
|
||||||
return [drive for drive in self.__getAllDrives() if ([d for d in self._drives if drive.startswith(d)])]
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmc
|
|
||||||
import xbmcaddon
|
|
||||||
|
|
||||||
addonName = xbmcaddon.Addon(id='service.fd628').getAddonInfo('name')
|
|
||||||
|
|
||||||
def kodiLog(message, level = xbmc.LOGDEBUG):
|
|
||||||
xbmc.log('{0} -> {1}'.format(addonName, str(message)), level)
|
|
||||||
|
|
||||||
def kodiLogError(message):
|
|
||||||
kodiLog(message, xbmc.LOGERROR)
|
|
||||||
|
|
||||||
def kodiLogWarning(message):
|
|
||||||
kodiLog(message, xbmc.LOGWARNING)
|
|
||||||
|
|
||||||
def kodiLogNotice(message):
|
|
||||||
kodiLog(message, xbmc.LOGNOTICE)
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
"""
|
|
||||||
Author: SpliFF
|
|
||||||
License: Public Domain
|
|
||||||
|
|
||||||
Python ioctl constants and functions module
|
|
||||||
|
|
||||||
Mostly follows specifications in asm-generic/ioctl.h from linux 2.5.36
|
|
||||||
|
|
||||||
Notable differences:
|
|
||||||
* no architecture dependant stuff
|
|
||||||
* size parameters are all passed as bytes, not types (ie pass 4, not int)
|
|
||||||
|
|
||||||
!! WARNING EXPERIMENTAL SOFTWARE !!
|
|
||||||
Make sure the values returned by these functions are properly tested before using fcntl on anything remotely valuable!
|
|
||||||
"""
|
|
||||||
|
|
||||||
NRBITS = 8
|
|
||||||
TYPEBITS = 8
|
|
||||||
|
|
||||||
# may be arch dependent
|
|
||||||
|
|
||||||
SIZEBITS = 14
|
|
||||||
DIRBITS = 2
|
|
||||||
|
|
||||||
NRMASK = (1 << NRBITS) - 1
|
|
||||||
TYPEMASK = (1 << TYPEBITS) - 1
|
|
||||||
SIZEMASK = (1 << SIZEBITS) - 1
|
|
||||||
DIRMASK = (1 << DIRBITS) - 1
|
|
||||||
|
|
||||||
NRSHIFT = 0
|
|
||||||
TYPESHIFT = NRSHIFT + NRBITS
|
|
||||||
SIZESHIFT = TYPESHIFT + TYPEBITS
|
|
||||||
DIRSHIFT = SIZESHIFT + SIZEBITS
|
|
||||||
|
|
||||||
# may be arch dependent
|
|
||||||
|
|
||||||
NONE = 0x0
|
|
||||||
WRITE = 0x1
|
|
||||||
READ = 0x2
|
|
||||||
|
|
||||||
# for the drivers/sound files...
|
|
||||||
|
|
||||||
IN = WRITE << DIRSHIFT
|
|
||||||
OUT = READ << DIRSHIFT
|
|
||||||
INOUT = (WRITE | READ) << DIRSHIFT
|
|
||||||
IOCSIZE_MASK = SIZEMASK << SIZESHIFT
|
|
||||||
IOCSIZE_SHIFT = SIZESHIFT
|
|
||||||
|
|
||||||
# used to create numbers ...
|
|
||||||
|
|
||||||
def IO( _type, nr):
|
|
||||||
return IOC(NONE, _type, nr, 0)
|
|
||||||
|
|
||||||
def IOC(direction, _type, nr, size):
|
|
||||||
return (direction << DIRSHIFT) | (_type << TYPESHIFT) | (nr << NRSHIFT) | (size << SIZESHIFT)
|
|
||||||
|
|
||||||
def IOR( _type, nr, size):
|
|
||||||
return IOC(READ, _type, nr, size)
|
|
||||||
|
|
||||||
def IOW(_type, nr, size):
|
|
||||||
return IOC(WRITE, _type, nr, size)
|
|
||||||
|
|
||||||
def IOWR(_type, nr, size):
|
|
||||||
return IOC(READ|WRITE, _type, nr, size)
|
|
||||||
|
|
||||||
def IOR_BAD(_type, nr, size):
|
|
||||||
return IOC(READ, _type, nr, size)
|
|
||||||
|
|
||||||
def IOW_BAD(_type, nr, size):
|
|
||||||
return IOC(WRITE, _type, nr, size)
|
|
||||||
|
|
||||||
def IOWR_BAD(_type, nr, size):
|
|
||||||
return IOC(READ|WRITE, _type, nr, size)
|
|
||||||
|
|
||||||
# used to decode ioctl numbers..
|
|
||||||
|
|
||||||
def DIR(nr):
|
|
||||||
return (nr >> DIRSHIFT) & DIRMASK
|
|
||||||
|
|
||||||
def TYPE(nr):
|
|
||||||
return (nr >> TYPESHIFT) & TYPEMASK
|
|
||||||
|
|
||||||
def NR(nr):
|
|
||||||
return (nr >> NRSHIFT) & NRMASK
|
|
||||||
|
|
||||||
def SIZE(nr):
|
|
||||||
return (nr >> SIZESHIFT) & SIZEMASK
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmcaddon
|
|
||||||
import threading
|
|
||||||
import os
|
|
||||||
import fd628states
|
|
||||||
import fd628dev
|
|
||||||
import fd628settings
|
|
||||||
from fd628utils import *
|
|
||||||
|
|
||||||
addon = xbmcaddon.Addon(id='service.fd628')
|
|
||||||
|
|
||||||
class fd628Monitor(xbmc.Monitor):
|
|
||||||
def __init__(self):
|
|
||||||
super(fd628Monitor, self).__init__()
|
|
||||||
self._settingsChangedCallback = None
|
|
||||||
|
|
||||||
def setSettingsChangedCallback(self, callbackObject):
|
|
||||||
self._settingsChangedCallback = callbackObject
|
|
||||||
|
|
||||||
def onSettingsChanged(self):
|
|
||||||
kodiLog('Enter fd628Monitor.onSettingsChanged')
|
|
||||||
if (self._settingsChangedCallback != None):
|
|
||||||
self._settingsChangedCallback.onSettingsChanged()
|
|
||||||
|
|
||||||
class fd628Addon():
|
|
||||||
def __init__(self, monitor):
|
|
||||||
self._fd628 = fd628dev.fd628Dev()
|
|
||||||
self._states = []
|
|
||||||
self._monitor = monitor
|
|
||||||
self._monitor.setSettingsChangedCallback(self)
|
|
||||||
self._settings = fd628settings.fd628Settings()
|
|
||||||
self._vfdon = '/sys/class/leds/le-vfd/led_on'
|
|
||||||
self._vfdoff = '/sys/class/leds/le-vfd/led_off'
|
|
||||||
self._rlock = threading.RLock()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
firstLoop = True
|
|
||||||
while not self._monitor.abortRequested():
|
|
||||||
if self._monitor.waitForAbort(0.5):
|
|
||||||
break
|
|
||||||
if (not os.path.isfile(self._vfdon) or not os.path.isfile(self._vfdoff)):
|
|
||||||
firstLoop = True
|
|
||||||
continue
|
|
||||||
if (firstLoop):
|
|
||||||
self.onSettingsChanged()
|
|
||||||
firstLoop = False
|
|
||||||
self.__updateIndicators()
|
|
||||||
self.__cleanUp()
|
|
||||||
|
|
||||||
def __updateIndicators(self):
|
|
||||||
ledon = []
|
|
||||||
ledoff = []
|
|
||||||
if (self._rlock.acquire()):
|
|
||||||
for state in self._states:
|
|
||||||
state.update()
|
|
||||||
if (state.hasChanged()):
|
|
||||||
if (state.getValue()):
|
|
||||||
ledon.append(state.getLedName())
|
|
||||||
else:
|
|
||||||
ledoff.append(state.getLedName())
|
|
||||||
self.__writeFile(self._vfdon, ledon)
|
|
||||||
self.__writeFile(self._vfdoff, ledoff)
|
|
||||||
self._rlock.release()
|
|
||||||
|
|
||||||
def __cleanUp(self):
|
|
||||||
self.__turnOffIndicators()
|
|
||||||
self._monitor = None
|
|
||||||
|
|
||||||
def __turnOffIndicators(self):
|
|
||||||
if (self._rlock.acquire()):
|
|
||||||
ledoff = [state.getLedName() for state in self._states]
|
|
||||||
self.__writeFile(self._vfdoff, ledoff)
|
|
||||||
self._rlock.release()
|
|
||||||
|
|
||||||
def __writeFile(self, path, values):
|
|
||||||
if (os.path.isfile(path)):
|
|
||||||
with open(path, "wb") as vfd:
|
|
||||||
for j in values:
|
|
||||||
vfd.write(j)
|
|
||||||
vfd.flush()
|
|
||||||
|
|
||||||
def onSettingsChanged(self):
|
|
||||||
kodiLog('Enter fd628Addon.onSettingsChanged')
|
|
||||||
self._settings.readValues()
|
|
||||||
if (self._rlock.acquire()):
|
|
||||||
self.__createStates()
|
|
||||||
self._fd628.enableDisplay(self._settings.isDisplayOn())
|
|
||||||
if (self._settings.isDisplayOn()):
|
|
||||||
self._fd628.setBrightness(self._settings.getBrightness())
|
|
||||||
if (self._settings.isAdvancedSettings()):
|
|
||||||
self._fd628.setDisplayType(self._settings.getDisplay())
|
|
||||||
self._fd628.setCharacterOrder(self._settings.getCharacterIndexes())
|
|
||||||
else:
|
|
||||||
self._fd628.useDtbConfig()
|
|
||||||
if (self._colonIcon != None and self._settings.isColonOn()):
|
|
||||||
self._colonIcon.turnOn()
|
|
||||||
self.__updateIndicators()
|
|
||||||
self._rlock.release()
|
|
||||||
kodiLog('isDisplayOn = {0}'.format(self._settings.isDisplayOn()))
|
|
||||||
kodiLog('getBrightness = {0}'.format(self._settings.getBrightness()))
|
|
||||||
kodiLog('isAdvancedSettings = {0}'.format(self._settings.isAdvancedSettings()))
|
|
||||||
kodiLog('getDisplayType = {0}'.format(self._settings.getDisplayType()))
|
|
||||||
kodiLog('isCommonAnode = {0}'.format(self._settings.isCommonAnode()))
|
|
||||||
kodiLog('getCharacterIndexex = {0}'.format(self._settings.getCharacterIndexes()))
|
|
||||||
|
|
||||||
def __createStates(self):
|
|
||||||
settingsWindows = ['settings', 'systeminfo', 'systemsettings', 'servicesettings', 'pvrsettings', \
|
|
||||||
'playersettings', 'mediasettings', 'interfacesettings', 'profiles', 'skinsettings', 'videossettings', \
|
|
||||||
'musicsettings', 'appearancesettings', 'picturessettings', 'weathersettings', 'gamesettings', \
|
|
||||||
'service-LibreELEC-Settings-mainWindow.xml', 'service-LibreELEC-Settings-wizard.xml', \
|
|
||||||
'service-LibreELEC-Settings-getPasskey.xml']
|
|
||||||
appsWindows = ['addonbrowser', 'addonsettings', 'addoninformation', 'addon', 'programs']
|
|
||||||
states = []
|
|
||||||
states.append(fd628states.fd628IconIndicator(True, 'power'))
|
|
||||||
states.append(fd628states.fd628CondVisibility('play', 'Player.Playing'))
|
|
||||||
states.append(fd628states.fd628CondVisibility('pause', 'Player.Paused'))
|
|
||||||
states.append(fd628states.fd628FileContains('hdmi', '/sys/class/amhdmitx/amhdmitx0/hpd_state', ['1']))
|
|
||||||
states.append(fd628states.fd628FileContains('cvbs', '/sys/class/display/mode', ['cvbs']))
|
|
||||||
states.append(fd628states.fd628FileContains('eth', '/sys/class/net/eth0/operstate', ['up', 'unknown']))
|
|
||||||
states.append(fd628states.fd628FileContains('wifi', '/sys/class/net/wlan0/operstate', ['up']))
|
|
||||||
states.append(fd628states.fd628WindowChecker('setup', settingsWindows))
|
|
||||||
states.append(fd628states.fd628WindowChecker('apps', appsWindows))
|
|
||||||
states.append(fd628states.fd628ExtStorageChecker('usb', '/dev/sd'))
|
|
||||||
states.append(fd628states.fd628ExtStorageChecker('sd', '/dev/mmcblk'))
|
|
||||||
self._colonIcon = fd628states.fd628IconIndicator(False, 'colon')
|
|
||||||
states.append(self._colonIcon)
|
|
||||||
if (self._settings.isStorageIndicator()):
|
|
||||||
for state in states:
|
|
||||||
if (state.getLedName() == self._settings.getStorageIndicatorIcon()):
|
|
||||||
states.remove(state)
|
|
||||||
break
|
|
||||||
states.append(fd628states.fd628ExtStorageCount(self._settings.getStorageIndicatorIcon(), None, 'rw'))
|
|
||||||
kodiLog('Active states: ' + str([str(state) for state in states]))
|
|
||||||
self.__turnOffIndicators()
|
|
||||||
self._states = states
|
|
||||||
|
|
||||||
monitor = fd628Monitor()
|
|
||||||
fd628 = fd628Addon(monitor)
|
|
||||||
kodiLog('Service start.')
|
|
||||||
fd628.run()
|
|
||||||
kodiLog('Service stop.')
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
|
||||||
<settings>
|
|
||||||
<category label="30000">
|
|
||||||
<setting label="30001" type="bool" id="display.on" default="true" />
|
|
||||||
<setting label="30002" type="slider" id="display.brightness" default="7" range="0,7" option="int" visible="eq(-1,true)" />
|
|
||||||
<setting label="30013" type="bool" id="display.storage.indicator" default="false" visible="eq(-2,true)" />
|
|
||||||
<setting label="30014" type="labelenum" id="display.storage.indicator.icon" lvalues="30025|30015|30016|30017|30018|30019|30020|30021|30022|30023|30024|30027" default="30025" visible="eq(-3,true) + eq(-1,true)" subsetting="true" />
|
|
||||||
<setting label="30028" type="bool" id="display.colon.on" default="false" visible="eq(-4,true)" />
|
|
||||||
<setting label="30003" type="bool" id="display.advanced" default="false" visible="eq(-5,true)" />
|
|
||||||
<setting label="30004" type="enum" id="display.type" values="0|1|2|3|4|5|6" default="1" visible="eq(-6,true) + eq(-1,true)" subsetting="true" />
|
|
||||||
<setting label="30026" type="bool" id="display.common.anode" default="false" visible="eq(-7,true) + eq(-2,true)" subsetting="true" />
|
|
||||||
<setting type="lsep" label="30012" visible="eq(-8,true) + eq(-3,true)" />
|
|
||||||
<setting label="30005" type="enum" id="display.char.index0" values="0|1|2|3|4|5|6" default="0" visible="eq(-9 ,true) + eq(-4,true)" subsetting="true" />
|
|
||||||
<setting label="30006" type="enum" id="display.char.index1" values="0|1|2|3|4|5|6" default="1" visible="eq(-10,true) + eq(-5,true)" subsetting="true" />
|
|
||||||
<setting label="30007" type="enum" id="display.char.index2" values="0|1|2|3|4|5|6" default="2" visible="eq(-11,true) + eq(-6,true)" subsetting="true" />
|
|
||||||
<setting label="30008" type="enum" id="display.char.index3" values="0|1|2|3|4|5|6" default="3" visible="eq(-12,true) + eq(-7,true)" subsetting="true" />
|
|
||||||
<setting label="30009" type="enum" id="display.char.index4" values="0|1|2|3|4|5|6" default="4" visible="eq(-13,true) + eq(-8,true)" subsetting="true" />
|
|
||||||
<setting label="30010" type="enum" id="display.char.index5" values="0|1|2|3|4|5|6" default="5" visible="false" subsetting="true" />
|
|
||||||
<setting label="30011" type="enum" id="display.char.index6" values="0|1|2|3|4|5|6" default="6" visible="false" subsetting="true" />
|
|
||||||
</category>
|
|
||||||
</settings>
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
110
|
||||||
|
- Fix RPi4 build to use dispmanx grabber
|
||||||
|
|
||||||
109
|
109
|
||||||
- Update to version 2018-12-20
|
- Update to version 2018-12-20
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ PKG_NAME="hyperion"
|
|||||||
PKG_VERSION="22f7be8df010fe8f0a51e3677fe0c8e709042622"
|
PKG_VERSION="22f7be8df010fe8f0a51e3677fe0c8e709042622"
|
||||||
PKG_SHA256="51cb6c5694d4bad67255ac4ae61a3c0aa481395c4868fb044a3ee19ca35bf19d"
|
PKG_SHA256="51cb6c5694d4bad67255ac4ae61a3c0aa481395c4868fb044a3ee19ca35bf19d"
|
||||||
PKG_VERSION_DATE="2018-12-20"
|
PKG_VERSION_DATE="2018-12-20"
|
||||||
PKG_REV="109"
|
PKG_REV="110"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="GPL"
|
PKG_LICENSE="GPL"
|
||||||
PKG_SITE="https://github.com/hyperion-project/hyperion"
|
PKG_SITE="https://github.com/hyperion-project/hyperion"
|
||||||
@@ -25,10 +25,7 @@ PKG_DISPMANX_SUPPORT="-DENABLE_DISPMANX=0"
|
|||||||
PKG_FB_SUPPORT="-DENABLE_FB=1"
|
PKG_FB_SUPPORT="-DENABLE_FB=1"
|
||||||
PKG_X11_SUPPORT="-DENABLE_X11=0"
|
PKG_X11_SUPPORT="-DENABLE_X11=0"
|
||||||
|
|
||||||
if [ "$KODIPLAYER_DRIVER" = "libamcodec" ]; then
|
if [ "$PROJECT" = "RPi" ]; then
|
||||||
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET libamcodec"
|
|
||||||
PKG_AMLOGIC_SUPPORT="-DENABLE_AMLOGIC=1"
|
|
||||||
elif [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then
|
|
||||||
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET bcm2835-driver"
|
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET bcm2835-driver"
|
||||||
PKG_DISPMANX_SUPPORT="-DENABLE_DISPMANX=1"
|
PKG_DISPMANX_SUPPORT="-DENABLE_DISPMANX=1"
|
||||||
PKG_FB_SUPPORT="-DENABLE_FB=0"
|
PKG_FB_SUPPORT="-DENABLE_FB=0"
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
From 49f9c51f5519d48bae601c174914f82e8e71e093 Mon Sep 17 00:00:00 2001
|
|
||||||
From: redpanther <redpanther@spooky-online.de>
|
|
||||||
Date: Wed, 31 Aug 2016 14:39:14 +0200
|
|
||||||
Subject: [PATCH] fix amlogic for newer kernels crosscompile stay on 32bit aml
|
|
||||||
with kernel 3.10
|
|
||||||
|
|
||||||
backport 58a8e22 from hyperion.ng
|
|
||||||
---
|
|
||||||
libsrc/grabber/amlogic/AmlogicGrabber.cpp | 10 +++++++---
|
|
||||||
libsrc/grabber/amlogic/CMakeLists.txt | 7 +++++++
|
|
||||||
2 files changed, 14 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libsrc/grabber/amlogic/AmlogicGrabber.cpp b/libsrc/grabber/amlogic/AmlogicGrabber.cpp
|
|
||||||
index 11cd280..5f39883 100644
|
|
||||||
--- a/libsrc/grabber/amlogic/AmlogicGrabber.cpp
|
|
||||||
+++ b/libsrc/grabber/amlogic/AmlogicGrabber.cpp
|
|
||||||
@@ -20,9 +20,13 @@
|
|
||||||
#define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH _IOW(AMVIDEOCAP_IOC_MAGIC, 0x02, int)
|
|
||||||
#define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x03, int)
|
|
||||||
|
|
||||||
-// Flags copied from 'include/linux/amlogic/amports/amvstream.h' at https://github.com/codesnake/linux-amlogic
|
|
||||||
-#define AMSTREAM_IOC_MAGIC 'S'
|
|
||||||
-#define AMSTREAM_IOC_GET_VIDEO_DISABLE _IOR(AMSTREAM_IOC_MAGIC, 0x48, unsigned long)
|
|
||||||
+#if HAVE_AML_HEADER
|
|
||||||
+ #include <amcodec/amports/amstream.h>
|
|
||||||
+#else
|
|
||||||
+ // Flags copied from 'include/linux/amlogic/amports/amvstream.h' at https://github.com/codesnake/linux-amlogic
|
|
||||||
+ #define AMSTREAM_IOC_MAGIC 'S'
|
|
||||||
+ #define AMSTREAM_IOC_GET_VIDEO_DISABLE _IOR(AMSTREAM_IOC_MAGIC, 0x48, unsigned long)
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
AmlogicGrabber::AmlogicGrabber(const unsigned width, const unsigned height) :
|
|
||||||
// Minimum required width or height is 160
|
|
||||||
diff --git a/libsrc/grabber/amlogic/CMakeLists.txt b/libsrc/grabber/amlogic/CMakeLists.txt
|
|
||||||
index cf8844b..326f7c7 100644
|
|
||||||
--- a/libsrc/grabber/amlogic/CMakeLists.txt
|
|
||||||
+++ b/libsrc/grabber/amlogic/CMakeLists.txt
|
|
||||||
@@ -1,3 +1,4 @@
|
|
||||||
+INCLUDE (CheckIncludeFiles)
|
|
||||||
|
|
||||||
# Define the current source locations
|
|
||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
|
||||||
@@ -21,6 +22,12 @@ else(ENABLE_QT5)
|
|
||||||
QT4_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS})
|
|
||||||
endif(ENABLE_QT5)
|
|
||||||
|
|
||||||
+CHECK_INCLUDE_FILES ("amcodec/amports/amstream.h" HAVE_AML_HEADER)
|
|
||||||
+IF (${HAVE_AML_HEADER})
|
|
||||||
+ ADD_DEFINITIONS( -DHAVE_AML_HEADER )
|
|
||||||
+ENDIF()
|
|
||||||
+
|
|
||||||
+
|
|
||||||
add_library(amlogic-grabber
|
|
||||||
${AmlogicHEADERS}
|
|
||||||
${AmlogicQT_HEADERS}
|
|
||||||
--
|
|
||||||
2.9.3
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
|
116
|
||||||
|
- Update to 4e3576b (2019-06-01)
|
||||||
|
- Only use Kodi
|
||||||
|
- Rework
|
||||||
|
|
||||||
115
|
115
|
||||||
- Update to daeeeaa (22-02-2019)
|
- Update to daeeeaa (2019-02-22)
|
||||||
|
|
||||||
114
|
114
|
||||||
- Fix discovery mode setting
|
- Fix discovery mode setting
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Copyright (C) 2017 Shane Meagher (shanemeagher)
|
# Copyright (C) 2017 Shane Meagher (shanemeagher)
|
||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="librespot"
|
PKG_NAME="librespot"
|
||||||
PKG_VERSION="daeeeaa122fc2d71edf11e562e23038db4210b39"
|
PKG_VERSION="4e3576ba7c6146cf68e1953daeec929d619b26b1"
|
||||||
PKG_SHA256="e9ebb8ca09c850598ae8c222bdab44e7d8321cb3c36017ba8e17a41db418c06e"
|
PKG_SHA256="c2fef0253bdbb6ff7085d4ec00e80da4727a1c5b1bf84dd2c14edc3de1cfd753"
|
||||||
PKG_VERSION_DATE="2019-02-22"
|
PKG_VERSION_DATE="2019-06-01"
|
||||||
PKG_REV="115"
|
PKG_REV="116"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="MIT"
|
PKG_LICENSE="MIT"
|
||||||
PKG_SITE="https://github.com/librespot-org/librespot/"
|
PKG_SITE="https://github.com/librespot-org/librespot/"
|
||||||
PKG_URL="https://github.com/librespot-org/librespot/archive/$PKG_VERSION.zip"
|
PKG_URL="https://github.com/librespot-org/librespot/archive/$PKG_VERSION.zip"
|
||||||
PKG_DEPENDS_TARGET="toolchain avahi pulseaudio pyalsaaudio rust"
|
PKG_DEPENDS_TARGET="toolchain avahi pulseaudio rust"
|
||||||
PKG_SECTION="service"
|
PKG_SECTION="service"
|
||||||
PKG_SHORTDESC="Librespot: play Spotify through LibreELEC using a Spotify app as a remote"
|
PKG_SHORTDESC="Librespot: play Spotify through Kodi using a Spotify app as a remote"
|
||||||
PKG_LONGDESC="Librespot ($PKG_VERSION_DATE) plays Spotify through LibreELEC using the open source librespot library using a Spotify app as a remote."
|
PKG_LONGDESC="Librespot ($PKG_VERSION_DATE) lets you play Spotify through Kodi using a Spotify app as a remote."
|
||||||
PKG_TOOLCHAIN="manual"
|
PKG_TOOLCHAIN="manual"
|
||||||
|
|
||||||
PKG_IS_ADDON="yes"
|
PKG_IS_ADDON="yes"
|
||||||
PKG_ADDON_NAME="Librespot"
|
PKG_ADDON_NAME="Librespot"
|
||||||
PKG_ADDON_TYPE="xbmc.service.library"
|
PKG_ADDON_TYPE="xbmc.service"
|
||||||
PKG_MAINTAINER="Anton Voyl (awiouy)"
|
PKG_MAINTAINER="Anton Voyl (awiouy)"
|
||||||
|
|
||||||
configure_target() {
|
configure_target() {
|
||||||
@@ -29,21 +29,17 @@ configure_target() {
|
|||||||
|
|
||||||
make_target() {
|
make_target() {
|
||||||
cd src
|
cd src
|
||||||
$CARGO_BUILD --no-default-features --features "alsa-backend pulseaudio-backend with-dns-sd"
|
$CARGO_BUILD --no-default-features --features "pulseaudio-backend with-dns-sd"
|
||||||
cd "$PKG_BUILD/.$TARGET_NAME"/*/release
|
cd "$PKG_BUILD/.$TARGET_NAME"/*/release
|
||||||
$STRIP librespot
|
$STRIP librespot
|
||||||
}
|
}
|
||||||
|
|
||||||
addon() {
|
addon() {
|
||||||
mkdir -p "$ADDON_BUILD/$PKG_ADDON_ID"
|
|
||||||
cp "$(get_build_dir pyalsaaudio)/.install_pkg/usr/lib/$PKG_PYTHON_VERSION/site-packages/alsaaudio.so" \
|
|
||||||
"$ADDON_BUILD/$PKG_ADDON_ID"
|
|
||||||
|
|
||||||
mkdir -p "$ADDON_BUILD/$PKG_ADDON_ID/bin"
|
mkdir -p "$ADDON_BUILD/$PKG_ADDON_ID/bin"
|
||||||
cp "$PKG_BUILD/.$TARGET_NAME"/*/release/librespot \
|
cp "$PKG_BUILD/.$TARGET_NAME"/*/release/librespot \
|
||||||
"$ADDON_BUILD/$PKG_ADDON_ID/bin"
|
"$ADDON_BUILD/$PKG_ADDON_ID/bin"
|
||||||
|
|
||||||
mkdir -p "$ADDON_BUILD/$PKG_ADDON_ID/lib"
|
mkdir -p "$ADDON_BUILD/$PKG_ADDON_ID/lib"
|
||||||
cp "$(get_build_dir avahi)/avahi-compat-libdns_sd/.libs/libdns_sd.so.1" \
|
cp "$(get_build_dir avahi)/avahi-compat-libdns_sd/.libs/libdns_sd.so.1" \
|
||||||
"$ADDON_BUILD/$PKG_ADDON_ID/lib"
|
"$ADDON_BUILD/$PKG_ADDON_ID/lib"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
diff --git a/playback/src/config.rs b/playback/src/config.rs
|
||||||
|
index 0f71110..931167d 100644
|
||||||
|
--- a/playback/src/config.rs
|
||||||
|
+++ b/playback/src/config.rs
|
||||||
|
@@ -30,6 +30,7 @@ pub struct PlayerConfig {
|
||||||
|
pub bitrate: Bitrate,
|
||||||
|
pub normalisation: bool,
|
||||||
|
pub normalisation_pregain: f32,
|
||||||
|
+ pub notify_kodi: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PlayerConfig {
|
||||||
|
@@ -38,6 +39,7 @@ impl Default for PlayerConfig {
|
||||||
|
bitrate: Bitrate::default(),
|
||||||
|
normalisation: false,
|
||||||
|
normalisation_pregain: 0.0,
|
||||||
|
+ notify_kodi: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/playback/src/player.rs b/playback/src/player.rs
|
||||||
|
index ab1a8ab..19d6394 100644
|
||||||
|
--- a/playback/src/player.rs
|
||||||
|
+++ b/playback/src/player.rs
|
||||||
|
@@ -4,7 +4,8 @@ use futures::sync::oneshot;
|
||||||
|
use futures::{future, Future};
|
||||||
|
use std;
|
||||||
|
use std::borrow::Cow;
|
||||||
|
-use std::io::{Read, Result, Seek, SeekFrom};
|
||||||
|
+use std::fs::OpenOptions;
|
||||||
|
+use std::io::{Read, Result, Seek, SeekFrom, Write};
|
||||||
|
use std::mem;
|
||||||
|
use std::sync::mpsc::{RecvError, RecvTimeoutError, TryRecvError};
|
||||||
|
use std::thread;
|
||||||
|
@@ -394,6 +395,14 @@ impl PlayerInternal {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ fn notify_kodi(&mut self, id: &str, track_id: &SpotifyId) {
|
||||||
|
+ // println!("fifo = {} {}", id, track_id.to_base62());
|
||||||
|
+ if self.config.notify_kodi {
|
||||||
|
+ let mut file = OpenOptions::new().write(true).open("/tmp/librespot").unwrap();
|
||||||
|
+ writeln!(&mut file, "{}\n{}", id, track_id.to_base62()).unwrap();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
fn handle_command(&mut self, cmd: PlayerCommand) {
|
||||||
|
debug!("command={:?}", cmd);
|
||||||
|
match cmd {
|
||||||
|
@@ -413,11 +422,17 @@ impl PlayerInternal {
|
||||||
|
| PlayerState::EndOfTrack {
|
||||||
|
track_id: old_track_id,
|
||||||
|
..
|
||||||
|
- } => self.send_event(PlayerEvent::Changed {
|
||||||
|
- old_track_id: old_track_id,
|
||||||
|
- new_track_id: track_id,
|
||||||
|
- }),
|
||||||
|
- _ => self.send_event(PlayerEvent::Started { track_id }),
|
||||||
|
+ } => {
|
||||||
|
+ self.send_event(PlayerEvent::Changed {
|
||||||
|
+ old_track_id: old_track_id,
|
||||||
|
+ new_track_id: track_id,
|
||||||
|
+ });
|
||||||
|
+ self.notify_kodi("1", &track_id)
|
||||||
|
+ }
|
||||||
|
+ _ => {
|
||||||
|
+ self.send_event(PlayerEvent::Started { track_id });
|
||||||
|
+ self.notify_kodi("2", &track_id)
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
self.start_sink();
|
||||||
|
@@ -443,13 +458,17 @@ impl PlayerInternal {
|
||||||
|
| PlayerState::EndOfTrack {
|
||||||
|
track_id: old_track_id,
|
||||||
|
..
|
||||||
|
- } => self.send_event(PlayerEvent::Changed {
|
||||||
|
- old_track_id: old_track_id,
|
||||||
|
- new_track_id: track_id,
|
||||||
|
- }),
|
||||||
|
+ } => {
|
||||||
|
+ self.send_event(PlayerEvent::Changed {
|
||||||
|
+ old_track_id: old_track_id,
|
||||||
|
+ new_track_id: track_id,
|
||||||
|
+ });
|
||||||
|
+ self.notify_kodi("3", &track_id)
|
||||||
|
+ }
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
self.send_event(PlayerEvent::Stopped { track_id });
|
||||||
|
+ self.notify_kodi("4", &track_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -476,6 +495,7 @@ impl PlayerInternal {
|
||||||
|
|
||||||
|
self.send_event(PlayerEvent::Started { track_id });
|
||||||
|
self.start_sink();
|
||||||
|
+ self.notify_kodi("5", &track_id)
|
||||||
|
} else {
|
||||||
|
warn!("Player::play called from invalid state");
|
||||||
|
}
|
||||||
|
@@ -487,6 +507,7 @@ impl PlayerInternal {
|
||||||
|
|
||||||
|
self.stop_sink_if_running();
|
||||||
|
self.send_event(PlayerEvent::Stopped { track_id });
|
||||||
|
+ self.notify_kodi("6", &track_id)
|
||||||
|
} else {
|
||||||
|
warn!("Player::pause called from invalid state");
|
||||||
|
}
|
||||||
|
@@ -499,6 +520,7 @@ impl PlayerInternal {
|
||||||
|
self.stop_sink_if_running();
|
||||||
|
self.send_event(PlayerEvent::Stopped { track_id });
|
||||||
|
self.state = PlayerState::Stopped;
|
||||||
|
+ self.notify_kodi("7", &track_id)
|
||||||
|
}
|
||||||
|
PlayerState::Stopped => {
|
||||||
|
warn!("Player::stop called from invalid state");
|
||||||
|
diff --git a/src/main.rs b/src/main.rs
|
||||||
|
index 36cd1b5..502cac8 100644
|
||||||
|
--- a/src/main.rs
|
||||||
|
+++ b/src/main.rs
|
||||||
|
@@ -168,6 +168,11 @@ fn setup(args: &[String]) -> Setup {
|
||||||
|
"Pregain (dB) applied by volume normalisation",
|
||||||
|
"PREGAIN",
|
||||||
|
)
|
||||||
|
+ .optflag(
|
||||||
|
+ "",
|
||||||
|
+ "notify-kodi",
|
||||||
|
+ "Notify Kodi",
|
||||||
|
+ )
|
||||||
|
.optflag(
|
||||||
|
"",
|
||||||
|
"linear-volume",
|
||||||
|
@@ -248,6 +253,8 @@ fn setup(args: &[String]) -> Setup {
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
+ let notify_kodi = matches.opt_present("notify-kodi");
|
||||||
|
+
|
||||||
|
let session_config = {
|
||||||
|
let device_id = device_id(&name);
|
||||||
|
|
||||||
|
@@ -291,6 +298,7 @@ fn setup(args: &[String]) -> Setup {
|
||||||
|
.opt_str("normalisation-pregain")
|
||||||
|
.map(|pregain| pregain.parse::<f32>().expect("Invalid pregain float value"))
|
||||||
|
.unwrap_or(PlayerConfig::default().normalisation_pregain),
|
||||||
|
+ notify_kodi: notify_kodi,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
From 109452968762175b255d3a46d2447bf103022a68 Mon Sep 17 00:00:00 2001
|
|
||||||
From: awiouy <awiouy@gmail.com>
|
|
||||||
Date: Wed, 7 Nov 2018 07:49:31 +0100
|
|
||||||
Subject: [PATCH] libreelec: kodi hooks
|
|
||||||
|
|
||||||
---
|
|
||||||
playback/src/player.rs | 44 ++++++++++++++++++++++++++-----------
|
|
||||||
src/player_event_handler.rs | 8 +++++--
|
|
||||||
2 files changed, 37 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/playback/src/player.rs b/playback/src/player.rs
|
|
||||||
index ab1a8ab..0aa0630 100644
|
|
||||||
--- a/playback/src/player.rs
|
|
||||||
+++ b/playback/src/player.rs
|
|
||||||
@@ -49,15 +49,18 @@ enum PlayerCommand {
|
|
||||||
pub enum PlayerEvent {
|
|
||||||
Started {
|
|
||||||
track_id: SpotifyId,
|
|
||||||
+ new_state: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
Changed {
|
|
||||||
old_track_id: SpotifyId,
|
|
||||||
new_track_id: SpotifyId,
|
|
||||||
+ new_state: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
Stopped {
|
|
||||||
track_id: SpotifyId,
|
|
||||||
+ new_state: String,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -413,11 +416,18 @@ impl PlayerInternal {
|
|
||||||
| PlayerState::EndOfTrack {
|
|
||||||
track_id: old_track_id,
|
|
||||||
..
|
|
||||||
- } => self.send_event(PlayerEvent::Changed {
|
|
||||||
- old_track_id: old_track_id,
|
|
||||||
- new_track_id: track_id,
|
|
||||||
- }),
|
|
||||||
- _ => self.send_event(PlayerEvent::Started { track_id }),
|
|
||||||
+ } => {
|
|
||||||
+ let new_state = "play".to_string();
|
|
||||||
+ self.send_event(PlayerEvent::Changed {
|
|
||||||
+ old_track_id: old_track_id,
|
|
||||||
+ new_track_id: track_id,
|
|
||||||
+ new_state: new_state,
|
|
||||||
+ });
|
|
||||||
+ },
|
|
||||||
+ _ => {
|
|
||||||
+ let new_state = "play".to_string();
|
|
||||||
+ self.send_event(PlayerEvent::Started { track_id, new_state });
|
|
||||||
+ },
|
|
||||||
}
|
|
||||||
|
|
||||||
self.start_sink();
|
|
||||||
@@ -443,13 +453,18 @@ impl PlayerInternal {
|
|
||||||
| PlayerState::EndOfTrack {
|
|
||||||
track_id: old_track_id,
|
|
||||||
..
|
|
||||||
- } => self.send_event(PlayerEvent::Changed {
|
|
||||||
- old_track_id: old_track_id,
|
|
||||||
- new_track_id: track_id,
|
|
||||||
- }),
|
|
||||||
+ } => {
|
|
||||||
+ let new_state = "pause".to_string();
|
|
||||||
+ self.send_event(PlayerEvent::Changed {
|
|
||||||
+ old_track_id: old_track_id,
|
|
||||||
+ new_track_id: track_id,
|
|
||||||
+ new_state: new_state,
|
|
||||||
+ })
|
|
||||||
+ },
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
- self.send_event(PlayerEvent::Stopped { track_id });
|
|
||||||
+ let new_state = "pause".to_string();
|
|
||||||
+ self.send_event(PlayerEvent::Stopped { track_id, new_state });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -474,7 +489,8 @@ impl PlayerInternal {
|
|
||||||
if let PlayerState::Paused { track_id, .. } = self.state {
|
|
||||||
self.state.paused_to_playing();
|
|
||||||
|
|
||||||
- self.send_event(PlayerEvent::Started { track_id });
|
|
||||||
+ let new_state = "play".to_string();
|
|
||||||
+ self.send_event(PlayerEvent::Started { track_id, new_state });
|
|
||||||
self.start_sink();
|
|
||||||
} else {
|
|
||||||
warn!("Player::play called from invalid state");
|
|
||||||
@@ -486,7 +502,8 @@ impl PlayerInternal {
|
|
||||||
self.state.playing_to_paused();
|
|
||||||
|
|
||||||
self.stop_sink_if_running();
|
|
||||||
- self.send_event(PlayerEvent::Stopped { track_id });
|
|
||||||
+ let new_state = "pause".to_string();
|
|
||||||
+ self.send_event(PlayerEvent::Stopped { track_id, new_state });
|
|
||||||
} else {
|
|
||||||
warn!("Player::pause called from invalid state");
|
|
||||||
}
|
|
||||||
@@ -497,7 +514,8 @@ impl PlayerInternal {
|
|
||||||
| PlayerState::Paused { track_id, .. }
|
|
||||||
| PlayerState::EndOfTrack { track_id } => {
|
|
||||||
self.stop_sink_if_running();
|
|
||||||
- self.send_event(PlayerEvent::Stopped { track_id });
|
|
||||||
+ let new_state = "stop".to_string();
|
|
||||||
+ self.send_event(PlayerEvent::Stopped { track_id, new_state });
|
|
||||||
self.state = PlayerState::Stopped;
|
|
||||||
}
|
|
||||||
PlayerState::Stopped => {
|
|
||||||
diff --git a/src/player_event_handler.rs b/src/player_event_handler.rs
|
|
||||||
index 1e682b9..3b478f1 100644
|
|
||||||
--- a/src/player_event_handler.rs
|
|
||||||
+++ b/src/player_event_handler.rs
|
|
||||||
@@ -19,18 +19,22 @@ pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> io::Result<Ch
|
|
||||||
PlayerEvent::Changed {
|
|
||||||
old_track_id,
|
|
||||||
new_track_id,
|
|
||||||
+ new_state,
|
|
||||||
} => {
|
|
||||||
env_vars.insert("PLAYER_EVENT", "change".to_string());
|
|
||||||
env_vars.insert("OLD_TRACK_ID", old_track_id.to_base62());
|
|
||||||
env_vars.insert("TRACK_ID", new_track_id.to_base62());
|
|
||||||
+ env_vars.insert("STATE", new_state.to_string());
|
|
||||||
}
|
|
||||||
- PlayerEvent::Started { track_id } => {
|
|
||||||
+ PlayerEvent::Started { track_id, new_state } => {
|
|
||||||
env_vars.insert("PLAYER_EVENT", "start".to_string());
|
|
||||||
env_vars.insert("TRACK_ID", track_id.to_base62());
|
|
||||||
+ env_vars.insert("STATE", new_state.to_string());
|
|
||||||
}
|
|
||||||
- PlayerEvent::Stopped { track_id } => {
|
|
||||||
+ PlayerEvent::Stopped { track_id, new_state } => {
|
|
||||||
env_vars.insert("PLAYER_EVENT", "stop".to_string());
|
|
||||||
env_vars.insert("TRACK_ID", track_id.to_base62());
|
|
||||||
+ env_vars.insert("STATE", new_state.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
run_program(onevent, env_vars)
|
|
||||||
@@ -12,7 +12,7 @@ index 88f6280..4e7186b 100644
|
|||||||
--- a/playback/src/audio_backend/pulseaudio.rs
|
--- a/playback/src/audio_backend/pulseaudio.rs
|
||||||
+++ b/playback/src/audio_backend/pulseaudio.rs
|
+++ b/playback/src/audio_backend/pulseaudio.rs
|
||||||
@@ -76,6 +76,7 @@ impl Open for PulseAudioSink {
|
@@ -76,6 +76,7 @@ impl Open for PulseAudioSink {
|
||||||
|
|
||||||
impl Sink for PulseAudioSink {
|
impl Sink for PulseAudioSink {
|
||||||
fn start(&mut self) -> io::Result<()> {
|
fn start(&mut self) -> io::Result<()> {
|
||||||
+ let sink = CString::new("librespot_sink").unwrap();
|
+ let sink = CString::new("librespot_sink").unwrap();
|
||||||
@@ -24,7 +24,7 @@ index 88f6280..4e7186b 100644
|
|||||||
self.name.as_ptr(), // Our application's name.
|
self.name.as_ptr(), // Our application's name.
|
||||||
PA_STREAM_PLAYBACK,
|
PA_STREAM_PLAYBACK,
|
||||||
- null(), // Use the default device.
|
- null(), // Use the default device.
|
||||||
+ sink.as_ptr(), // Our sink.
|
+ sink.as_ptr(), // Our sink.
|
||||||
self.desc.as_ptr(), // desc of our stream.
|
self.desc.as_ptr(), // desc of our stream.
|
||||||
&self.ss, // Our sample format.
|
&self.ss, // Our sample format.
|
||||||
null(), // Use default channel map
|
null(), // Use default channel map
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import alsaaudio
|
|
||||||
import xbmcaddon
|
|
||||||
import xbmcgui
|
|
||||||
|
|
||||||
|
|
||||||
dialog = xbmcgui.Dialog()
|
|
||||||
strings = xbmcaddon.Addon().getLocalizedString
|
|
||||||
while True:
|
|
||||||
pcms = alsaaudio.pcms()[1:]
|
|
||||||
if len(pcms) == 0:
|
|
||||||
dialog.ok(xbmcaddon.Addon().getAddonInfo('name'), strings(30210))
|
|
||||||
break
|
|
||||||
pcmx = dialog.select(strings(30115), pcms)
|
|
||||||
if pcmx == -1:
|
|
||||||
break
|
|
||||||
pcm = pcms[pcmx]
|
|
||||||
xbmcaddon.Addon().setSetting('ls_o', pcm)
|
|
||||||
break
|
|
||||||
del dialog
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
LS_PORT="6666"
|
|
||||||
LS_SINK="librespot_sink"
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
echo -e "$STATE\n$TRACK_ID" > "$LS_FIFO"
|
|
||||||
@@ -3,110 +3,34 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
f="/storage/.kodi/userdata/addon_data/service.librespot/settings.xml"
|
|
||||||
[ -f "$f" ] && sed -i 's/ls_O/ls_m/g' "$f"
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
init_alsa() {
|
|
||||||
. /etc/os-release
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
. /etc/profile
|
. /etc/profile
|
||||||
oe_setup_addon service.librespot
|
oe_setup_addon service.librespot
|
||||||
|
|
||||||
LIBRESPOT="librespot --cache \"$ADDON_HOME/cache\" \
|
PORT="6666"
|
||||||
--disable-audio-cache \
|
SINK_NAME="librespot_sink"
|
||||||
--name \"Librespot@$HOSTNAME\" \
|
|
||||||
--onevent librespot.onevent"
|
|
||||||
|
|
||||||
if [ -n "$ls_b" -a "$ls_b" != "-" ]; then
|
if ! pactl list modules short | grep "sink_name=$SINK_NAME"; then
|
||||||
LIBRESPOT="$LIBRESPOT --bitrate $ls_b"
|
pactl load-module module-null-sink sink_name="$SINK_NAME" > /dev/null
|
||||||
fi
|
fi
|
||||||
|
if ! pactl list modules short | grep "source=$SINK_NAME"; then
|
||||||
|
pactl load-module module-rtp-send source="$SINK_NAME.monitor" \
|
||||||
|
destination_ip=127.0.0.1 port="$PORT" source_ip=127.0.0.1 > /dev/null
|
||||||
|
fi
|
||||||
|
pactl suspend-sink "$SINK_NAME" 1
|
||||||
|
|
||||||
|
LIBRESPOT="librespot \
|
||||||
|
--backend pulseaudio \
|
||||||
|
--cache \"$ADDON_HOME/cache\" \
|
||||||
|
--device-type TV \
|
||||||
|
--disable-audio-cache \
|
||||||
|
--name \"Kodi ($HOSTNAME)\" \
|
||||||
|
--notify-kodi"
|
||||||
|
|
||||||
if [ "$ls_a" = "true" -a -n "$ls_p" -a -n "$ls_u" ]; then
|
if [ "$ls_a" = "true" -a -n "$ls_p" -a -n "$ls_u" ]; then
|
||||||
LIBRESPOT="$LIBRESPOT --disable-discovery \
|
LIBRESPOT="$LIBRESPOT \
|
||||||
--password \"$ls_p\" \
|
--disable-discovery \
|
||||||
--username \"$ls_u\""
|
--password \"$ls_p\" \
|
||||||
|
--username \"$ls_u\""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$ls_m" = "Kodi" ]; then
|
|
||||||
LIBRESPOT="$LIBRESPOT --backend pulseaudio --device-type TV"
|
|
||||||
else
|
|
||||||
init_alsa
|
|
||||||
if [ -n "$ls_o" ]; then
|
|
||||||
LIBRESPOT="$LIBRESPOT --device \"$ls_o\""
|
|
||||||
fi
|
|
||||||
LIBRESPOT="$LIBRESPOT --device-type Speaker"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$(pactl list short modules | grep sink_name=$LS_SINK)" ]; then
|
|
||||||
pactl load-module module-null-sink sink_name="$LS_SINK" > /dev/null
|
|
||||||
fi
|
|
||||||
pactl suspend-sink "$LS_SINK" 1
|
|
||||||
if [ -z "$(pactl list short modules | grep source=$LS_SINK.monitor)" ]; then
|
|
||||||
pactl load-module module-rtp-send source="$LS_SINK.monitor" \
|
|
||||||
destination_ip=127.0.0.1 port="$LS_PORT" source_ip=127.0.0.1 > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
export LS_FIFO="/var/run/librespot"
|
|
||||||
|
|
||||||
eval $LIBRESPOT
|
eval $LIBRESPOT
|
||||||
|
|||||||
@@ -1,13 +1,224 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import stat
|
||||||
|
import subprocess
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import urllib
|
||||||
|
import urllib2
|
||||||
|
import xbmc
|
||||||
|
import xbmcaddon
|
||||||
|
import xbmcgui
|
||||||
|
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'resources', 'lib'))
|
ADDON = xbmcaddon.Addon()
|
||||||
|
ADDON_ID = ADDON.getAddonInfo('id')
|
||||||
|
ADDON_NAME = ADDON.getAddonInfo('name')
|
||||||
|
FIFO = '/tmp/librespot'
|
||||||
|
LOG_LEVEL = xbmc.LOGNOTICE
|
||||||
|
LOG_MESSAGE = ADDON.getAddonInfo('name') + ': {}'
|
||||||
|
SINK_NAME = "librespot_sink"
|
||||||
|
SPOTIFY_ID = '169df5532dee47a59913f8528e83ae71'
|
||||||
|
SPOTIFY_SECRET = '1f3d8b507bbe4f68beb3a4472e8ad411'
|
||||||
|
STREAM_CODEC = 'pcm_s16be'
|
||||||
|
STREAM_PORT = '6666'
|
||||||
|
STREAM_URL = 'rtp://127.0.0.1:{}'.format(STREAM_PORT)
|
||||||
|
|
||||||
from ls_monitor import Monitor as Monitor
|
|
||||||
|
def log(message):
|
||||||
|
xbmc.log(LOG_MESSAGE.format(message), LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
|
class Monitor(xbmc.Monitor):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
log('monitor started')
|
||||||
|
self.player = Player()
|
||||||
|
|
||||||
|
def onSettingsChanged(self):
|
||||||
|
log('settings changed')
|
||||||
|
self.player.update()
|
||||||
|
|
||||||
|
def waitForAbort(self):
|
||||||
|
super(Monitor, self).waitForAbort()
|
||||||
|
log('abort requested')
|
||||||
|
self.player.abort()
|
||||||
|
|
||||||
|
|
||||||
|
class Player(threading.Thread, xbmc.Player):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
log('player started')
|
||||||
|
super(Player, self).__init__()
|
||||||
|
self.isLibrespotStarted = True
|
||||||
|
self.listitem = xbmcgui.ListItem()
|
||||||
|
self.listitem.addStreamInfo('audio', {'codec': STREAM_CODEC})
|
||||||
|
self.listitem.setPath(STREAM_URL)
|
||||||
|
self.spotify = Spotify()
|
||||||
|
if self.isPlaying():
|
||||||
|
self.onAVStarted()
|
||||||
|
else:
|
||||||
|
self.playingFile = ''
|
||||||
|
self.onPlayBackStopped()
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def abort(self):
|
||||||
|
log('aborting player')
|
||||||
|
with open(FIFO, 'w') as fifo:
|
||||||
|
fifo.close()
|
||||||
|
self.join()
|
||||||
|
|
||||||
|
def onAVChange(self):
|
||||||
|
self.onAVStarted()
|
||||||
|
|
||||||
|
def onAVStarted(self):
|
||||||
|
log('playback started')
|
||||||
|
self.playingFile = self.getPlayingFile()
|
||||||
|
if self.isLibrespotStarted and (self.playingFile != STREAM_URL):
|
||||||
|
self.isLibrespotStarted = False
|
||||||
|
self.systemctl('stop')
|
||||||
|
|
||||||
|
def onPlayBackEnded(self):
|
||||||
|
self.onPlayBackStopped()
|
||||||
|
|
||||||
|
def onPlayBackError(self):
|
||||||
|
self.onPlayBackStopped()
|
||||||
|
|
||||||
|
def onPlayBackStopped(self):
|
||||||
|
log('playback stopped')
|
||||||
|
if self.playingFile == STREAM_URL:
|
||||||
|
self.systemctl('restart')
|
||||||
|
elif not self.isLibrespotStarted:
|
||||||
|
self.systemctl('start')
|
||||||
|
self.isLibrespotStarted = True
|
||||||
|
|
||||||
|
def pauseLibrespot(self):
|
||||||
|
if self.isPlaying() and (self.getPlayingFile() == STREAM_URL):
|
||||||
|
log('pausing librespot playback')
|
||||||
|
self.pause()
|
||||||
|
|
||||||
|
def playLibrespot(self, track_id):
|
||||||
|
track = self.spotify.getTrack(track_id)
|
||||||
|
self.listitem.setArt(track.getArt())
|
||||||
|
self.listitem.setInfo('music', track.getInfo())
|
||||||
|
if not self.isPlaying():
|
||||||
|
subprocess.call(['pactl', 'suspend-sink', SINK_NAME, '0'])
|
||||||
|
log('starting librespot playback')
|
||||||
|
self.play(STREAM_URL, self.listitem)
|
||||||
|
elif self.getPlayingFile() == STREAM_URL:
|
||||||
|
log('updating librespot playback')
|
||||||
|
self.updateInfoTag(self.listitem)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
log('control pipe started')
|
||||||
|
try:
|
||||||
|
os.unlink(FIFO)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
os.mkfifo(FIFO)
|
||||||
|
while (os.path.exists(FIFO) and
|
||||||
|
stat.S_ISFIFO(os.stat(FIFO).st_mode)):
|
||||||
|
with open(FIFO, 'r') as fifo:
|
||||||
|
command = fifo.read().splitlines()
|
||||||
|
log('control pipe {}'.format(str(command)))
|
||||||
|
if len(command) == 0:
|
||||||
|
break
|
||||||
|
elif command[0] in ['3', '5', '6']:
|
||||||
|
self.pauseLibrespot()
|
||||||
|
elif command[0] in ['1', '2', '4']:
|
||||||
|
self.playLibrespot(command[1])
|
||||||
|
elif command[0] in ['7']:
|
||||||
|
self.stopLibrespot()
|
||||||
|
try:
|
||||||
|
os.unlink(FIFO)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
log('control pipe stopped')
|
||||||
|
|
||||||
|
def stopLibrespot(self):
|
||||||
|
if self.isPlaying() and (self.getPlayingFile() == STREAM_URL):
|
||||||
|
log('stopping librespot playback')
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
def systemctl(self, command):
|
||||||
|
log('{} librespot'.format(command))
|
||||||
|
subprocess.call(['systemctl', command, ADDON_ID])
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
log('updating player')
|
||||||
|
if self.isLibrespotStarted:
|
||||||
|
self.systemctl('restart')
|
||||||
|
|
||||||
|
|
||||||
|
class Spotify():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.headers = None
|
||||||
|
self.expiration = time.time()
|
||||||
|
self.request = [
|
||||||
|
'https://accounts.spotify.com/api/token',
|
||||||
|
urllib.urlencode({'grant_type': 'client_credentials'}),
|
||||||
|
{'Authorization': 'Basic {}'.format(base64.b64encode(
|
||||||
|
'{}:{}'.format(SPOTIFY_ID, SPOTIFY_SECRET)))}
|
||||||
|
]
|
||||||
|
|
||||||
|
def getHeaders(self):
|
||||||
|
if time.time() > self.expiration:
|
||||||
|
log('token expired')
|
||||||
|
token = json.loads(urllib2.urlopen(
|
||||||
|
urllib2.Request(*self.request)).read())
|
||||||
|
log('new token expires in {} seconds'.format(token['expires_in']))
|
||||||
|
self.expiration = time.time() + float(token['expires_in']) - 60
|
||||||
|
self.headers = {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': 'Bearer {}'.format(token['access_token'])
|
||||||
|
}
|
||||||
|
|
||||||
|
def getTrack(self, track_id):
|
||||||
|
log('getting track')
|
||||||
|
try:
|
||||||
|
self.getHeaders()
|
||||||
|
track = json.loads(urllib2.urlopen(urllib2.Request(
|
||||||
|
'https://api.spotify.com/v1/tracks/{}'.format(track_id), None,
|
||||||
|
self.headers)).read())
|
||||||
|
except Exception as e:
|
||||||
|
log('failed to get track from Spotify: {}'.format(e))
|
||||||
|
track = dict()
|
||||||
|
return Track(track)
|
||||||
|
|
||||||
|
|
||||||
|
class Track():
|
||||||
|
|
||||||
|
def __init__(self, track):
|
||||||
|
self.track = track
|
||||||
|
|
||||||
|
def get(self, default, *indices):
|
||||||
|
tree = self.track
|
||||||
|
try:
|
||||||
|
for index in indices:
|
||||||
|
tree = tree[index]
|
||||||
|
except LookupError:
|
||||||
|
tree = default
|
||||||
|
return tree
|
||||||
|
|
||||||
|
def getArt(self):
|
||||||
|
return {
|
||||||
|
'thumb': self.get('', 'album', 'images', 0, 'url')
|
||||||
|
}
|
||||||
|
|
||||||
|
def getInfo(self):
|
||||||
|
return {
|
||||||
|
'album': self.get('', 'album', 'name'),
|
||||||
|
'artist': self.get('', 'artists', 0, 'name'),
|
||||||
|
'title': self.get('', 'name'),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
log('service started')
|
||||||
Monitor().waitForAbort()
|
Monitor().waitForAbort()
|
||||||
|
log('service stopped')
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
|
PORT="6666"
|
||||||
|
SINK_NAME="librespot_sink"
|
||||||
@@ -4,81 +4,17 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#30100"
|
msgctxt "#30100"
|
||||||
msgid "Librespot"
|
msgid "Configuration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#30102"
|
msgctxt "#30101"
|
||||||
msgid "Bit rate"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30103"
|
|
||||||
msgid "-"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30104"
|
|
||||||
msgid "96"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30105"
|
|
||||||
msgid "160"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30106"
|
|
||||||
msgid "320"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30107"
|
|
||||||
msgid "Output mode"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30108"
|
|
||||||
msgid "ALSA"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30109"
|
|
||||||
msgid "Kodi"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30110"
|
|
||||||
msgid "Username"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30111"
|
|
||||||
msgid "Password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30112"
|
|
||||||
msgid "User mode"
|
msgid "User mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#30113"
|
msgctxt "#30102"
|
||||||
msgid "ALSA"
|
msgid "Username"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#30114"
|
msgctxt "#30103"
|
||||||
msgid "Configuration wizard"
|
msgid "Password"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30115"
|
|
||||||
msgid "Playback device"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30116"
|
|
||||||
msgid "Playback route"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30117"
|
|
||||||
msgid "auto detect"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30118"
|
|
||||||
msgid "headphone jack"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30119"
|
|
||||||
msgid "HDMI"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30210"
|
|
||||||
msgid "Could not find a playback device"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import xbmcaddon
|
|
||||||
|
|
||||||
from ls_log import log as log
|
|
||||||
|
|
||||||
|
|
||||||
_SERVICE = xbmcaddon.Addon().getAddonInfo('id')
|
|
||||||
_SINK = 'librespot_sink'
|
|
||||||
|
|
||||||
|
|
||||||
def _pactl(bit):
|
|
||||||
log('pactl {}'.format(bit))
|
|
||||||
subprocess.call(['pactl', 'suspend-sink', _SINK, bit])
|
|
||||||
|
|
||||||
|
|
||||||
def _systemctl(command):
|
|
||||||
log('systemctl {}'.format(command))
|
|
||||||
subprocess.call(['systemctl', command, _SERVICE])
|
|
||||||
_pactl('1')
|
|
||||||
|
|
||||||
|
|
||||||
class Librespot():
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.state = True
|
|
||||||
|
|
||||||
def restart(self):
|
|
||||||
log('restarting librespot')
|
|
||||||
_systemctl('restart')
|
|
||||||
self.state = True
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
if self.state:
|
|
||||||
log('stopping librespot')
|
|
||||||
_systemctl('stop')
|
|
||||||
self.state = False
|
|
||||||
|
|
||||||
def unsuspend(self):
|
|
||||||
_pactl('0')
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmc
|
|
||||||
import xbmcaddon
|
|
||||||
|
|
||||||
|
|
||||||
_MESSAGE = xbmcaddon.Addon().getAddonInfo('name') + ': {}'
|
|
||||||
|
|
||||||
|
|
||||||
def log(message):
|
|
||||||
xbmc.log(_MESSAGE.format(message), xbmc.LOGNOTICE)
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmc
|
|
||||||
|
|
||||||
from ls_log import log as log
|
|
||||||
from ls_player import Player as Player
|
|
||||||
|
|
||||||
|
|
||||||
class Monitor(xbmc.Monitor):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
log('monitor started')
|
|
||||||
self.player = Player()
|
|
||||||
|
|
||||||
def onSettingsChanged(self):
|
|
||||||
self.player.onSettingsChanged()
|
|
||||||
|
|
||||||
def waitForAbort(self):
|
|
||||||
super(Monitor, self).waitForAbort()
|
|
||||||
self.player.onAbortRequested()
|
|
||||||
log('monitor stopped')
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import os
|
|
||||||
import stat
|
|
||||||
import threading
|
|
||||||
import xbmc
|
|
||||||
import xbmcaddon
|
|
||||||
import xbmcgui
|
|
||||||
|
|
||||||
from ls_librespot import Librespot as Librespot
|
|
||||||
from ls_log import log as log
|
|
||||||
from ls_spotify import Spotify as Spotify
|
|
||||||
|
|
||||||
_CODEC = 'pcm_s16le'
|
|
||||||
_FIFO = '/var/run/librespot'
|
|
||||||
_STREAM = 'rtp://127.0.0.1:6666'
|
|
||||||
|
|
||||||
_DEFAULT_ICON = xbmcaddon.Addon().getAddonInfo('icon')
|
|
||||||
_DEFAULT_TITLE = xbmcaddon.Addon().getAddonInfo('name')
|
|
||||||
|
|
||||||
|
|
||||||
class Player(threading.Thread, xbmc.Player):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(Player, self).__init__()
|
|
||||||
self.updateSettings()
|
|
||||||
self.dialog = xbmcgui.Dialog()
|
|
||||||
self.librespot = Librespot()
|
|
||||||
self.listitem = xbmcgui.ListItem()
|
|
||||||
self.listitem.addStreamInfo('audio', {'codec': _CODEC})
|
|
||||||
self.listitem.setPath(_STREAM)
|
|
||||||
self.spotify = Spotify()
|
|
||||||
self.start()
|
|
||||||
if self.isPlaying():
|
|
||||||
self.onPlayBackStarted()
|
|
||||||
|
|
||||||
def onAbortRequested(self):
|
|
||||||
log('abort requested')
|
|
||||||
with open(_FIFO, 'w') as fifo:
|
|
||||||
fifo.close()
|
|
||||||
self.join()
|
|
||||||
|
|
||||||
def onPlayBackEnded(self):
|
|
||||||
log('a playback ended')
|
|
||||||
self.librespot.restart()
|
|
||||||
|
|
||||||
def onPlayBackStarted(self):
|
|
||||||
log('a playback started')
|
|
||||||
if self.getPlayingFile() != _STREAM:
|
|
||||||
self.librespot.stop()
|
|
||||||
|
|
||||||
def onPlayBackStopped(self):
|
|
||||||
log('a playback stopped')
|
|
||||||
self.librespot.restart()
|
|
||||||
|
|
||||||
def onSettingsChanged(self):
|
|
||||||
log('settings changed')
|
|
||||||
self.stop()
|
|
||||||
self.updateSettings()
|
|
||||||
|
|
||||||
def pause(self):
|
|
||||||
if self.isPlaying() and self.getPlayingFile() == _STREAM:
|
|
||||||
log('pausing librespot playback')
|
|
||||||
super(Player, self).pause()
|
|
||||||
|
|
||||||
def play(self, track_id):
|
|
||||||
track = self.spotify.getTrack(track_id)
|
|
||||||
if track['thumb'] == '':
|
|
||||||
track['thumb'] = _DEFAULT_ICON
|
|
||||||
if track['title'] == '':
|
|
||||||
track['title'] = _DEFAULT_TITLE
|
|
||||||
if self.kodi:
|
|
||||||
self.listitem.setArt({'thumb': track['thumb']})
|
|
||||||
self.listitem.setInfo(
|
|
||||||
'music',
|
|
||||||
{
|
|
||||||
'album': track['album'],
|
|
||||||
'artist': track['artist'],
|
|
||||||
'title': track['title']
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if self.isPlaying() and self.getPlayingFile() == _STREAM:
|
|
||||||
log('updating librespot playback')
|
|
||||||
self.updateInfoTag(self.listitem)
|
|
||||||
else:
|
|
||||||
self.librespot.unsuspend()
|
|
||||||
log('starting librespot playback')
|
|
||||||
super(Player, self).play(_STREAM, self.listitem)
|
|
||||||
else:
|
|
||||||
self.dialog.notification(
|
|
||||||
track['title'],
|
|
||||||
track['artist'],
|
|
||||||
icon=track['thumb'],
|
|
||||||
sound=False)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
log('named pipe started')
|
|
||||||
try:
|
|
||||||
os.unlink(_FIFO)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
os.mkfifo(_FIFO)
|
|
||||||
while (os.path.exists(_FIFO) and
|
|
||||||
stat.S_ISFIFO(os.stat(_FIFO).st_mode)):
|
|
||||||
with open(_FIFO, 'r') as fifo:
|
|
||||||
command = fifo.read().splitlines()
|
|
||||||
log('named pipe received {}'.format(str(command)))
|
|
||||||
if len(command) == 0:
|
|
||||||
break
|
|
||||||
elif command[0] == 'play':
|
|
||||||
self.play(command[1])
|
|
||||||
elif command[0] == 'stop':
|
|
||||||
self.stop()
|
|
||||||
elif command[0] == 'pause':
|
|
||||||
self.pause()
|
|
||||||
try:
|
|
||||||
os.unlink(_FIFO)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
log('named pipe stopped')
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
if self.isPlaying():
|
|
||||||
if self.getPlayingFile() == _STREAM:
|
|
||||||
log('stopping librespot playback')
|
|
||||||
super(Player, self).stop()
|
|
||||||
else:
|
|
||||||
self.librespot.stop()
|
|
||||||
else:
|
|
||||||
self.librespot.restart()
|
|
||||||
|
|
||||||
def updateSettings(self):
|
|
||||||
self.kodi = (xbmcaddon.Addon().getSetting('ls_m') == 'Kodi')
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import base64
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
import urllib
|
|
||||||
import urllib2
|
|
||||||
|
|
||||||
from ls_log import log as log
|
|
||||||
|
|
||||||
_CLIENT_ID = '169df5532dee47a59913f8528e83ae71'
|
|
||||||
_CLIENT_SECRET = '1f3d8b507bbe4f68beb3a4472e8ad411'
|
|
||||||
|
|
||||||
|
|
||||||
def _get(default, tree, *indices):
|
|
||||||
try:
|
|
||||||
for index in indices:
|
|
||||||
tree = tree[index]
|
|
||||||
except LookupError:
|
|
||||||
tree = default
|
|
||||||
return tree
|
|
||||||
|
|
||||||
|
|
||||||
class Spotify():
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.headers = None
|
|
||||||
self.expiration = time.time()
|
|
||||||
self.request = [
|
|
||||||
'https://accounts.spotify.com/api/token',
|
|
||||||
urllib.urlencode({'grant_type': 'client_credentials'}),
|
|
||||||
{'Authorization': 'Basic {}'.format(base64.b64encode(
|
|
||||||
'{}:{}'.format(_CLIENT_ID, _CLIENT_SECRET)))}
|
|
||||||
]
|
|
||||||
|
|
||||||
def getTrack(self, track_id):
|
|
||||||
try:
|
|
||||||
if time.time() > self.expiration:
|
|
||||||
log('token expired')
|
|
||||||
token = json.loads(urllib2.urlopen(
|
|
||||||
urllib2.Request(*self.request)).read())
|
|
||||||
log('token {} expires in {} seconds'.format(
|
|
||||||
token['access_token'], token['expires_in']))
|
|
||||||
self.expiration = time.time() + float(token['expires_in']) - 60
|
|
||||||
self.headers = {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': 'Bearer {}'.format(token['access_token'])
|
|
||||||
}
|
|
||||||
track = json.loads(urllib2.urlopen(urllib2.Request(
|
|
||||||
'https://api.spotify.com/v1/tracks/{}'.format(track_id), None,
|
|
||||||
self.headers)).read())
|
|
||||||
except Exception as e:
|
|
||||||
log('failed to get track {} from Spotify: {}'.format(e))
|
|
||||||
track = dict()
|
|
||||||
return {
|
|
||||||
'album': _get('', track, 'album', 'name'),
|
|
||||||
'artist': _get('', track, 'artists', 0, 'name'),
|
|
||||||
'duration': _get(0, track, 'duration_ms') / 1000,
|
|
||||||
'thumb': _get('', track, 'album', 'images', 0, 'url'),
|
|
||||||
'title': _get('', track, 'name')
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||||
<settings>
|
<settings>
|
||||||
<setting id="ls_m" label="30107" type="labelenum" lvalues="30108|30109" />
|
<category label="30100">
|
||||||
<setting label="30114" type="action" subsetting="true" visible="eq(-1,0)" action="RunAddon(service.librespot)" />
|
<setting label="30101" id="ls_a" type="bool" default="false" />
|
||||||
<setting id="ls_o" label="30115" type="text" subsetting="true" visible="eq(-2,0)" default="" />
|
<setting label="30102" id="ls_u" type="text" default="" subsetting="true" visible="eq(-1,true)" />
|
||||||
<setting id="pcm_3" label="30116" type="enum" subsetting="true" visible="eq(-3,0)" lvalues="30117|30118|30119" enable="eq(-1,default:CARD=ALSA)|eq(-1,sysdefault:CARD=ALSA)" />
|
<setting label="30103" id="ls_p" type="text" default="" subsetting="true" visible="eq(-2,true)" option="hidden" />
|
||||||
<setting id="ls_b" label="30102" type="labelenum" lvalues="30103|30104|30105|30106" />
|
</category>
|
||||||
<setting id="ls_a" label="30112" type="bool" default="false" />
|
|
||||||
<setting id="ls_u" label="30110" type="text" subsetting="true" visible="eq(-1,true)" default="" />
|
|
||||||
<setting id="ls_p" label="30111" type="text" subsetting="true" visible="eq(-2,true)" default="" option="hidden" />
|
|
||||||
</settings>
|
</settings>
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
<settings version="2">
|
<settings version="2">
|
||||||
<setting id="ls_a" default="true">false</setting>
|
<setting id="ls_a" default="true">false</setting>
|
||||||
<setting id="ls_b">320</setting>
|
|
||||||
<setting id="ls_m">ALSA</setting>
|
|
||||||
<setting id="ls_o" default="true"></setting>
|
|
||||||
<setting id="ls_p" default="true"></setting>
|
<setting id="ls_p" default="true"></setting>
|
||||||
<setting id="ls_u" default="true"></setting>
|
<setting id="ls_u" default="true"></setting>
|
||||||
<setting id="pcm_3" default="true">0</setting>
|
|
||||||
</settings>
|
</settings>
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ Wants=kodi.service
|
|||||||
After=kodi.service
|
After=kodi.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
EnvironmentFile=/storage/.kodi/addons/service.librespot/bin/librespot.env
|
EnvironmentFile=/storage/.kodi/addons/service.librespot/ls_env.py
|
||||||
ExecStart=/bin/sh /storage/.kodi/addons/service.librespot/bin/librespot.start
|
ExecStart=/bin/sh /storage/.kodi/addons/service.librespot/bin/librespot.start
|
||||||
ExecStopPost=/usr/bin/pactl suspend-sink "$LS_SINK" 1
|
ExecStopPost=-/usr/bin/pactl suspend-sink librespot_sink 1
|
||||||
Restart=on-failure
|
Restart=always
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=kodi.service
|
WantedBy=kodi.service
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
109
|
||||||
|
- Update to version 11518
|
||||||
|
- fixed missing Modules
|
||||||
|
|
||||||
108
|
108
|
||||||
- Update to version 11517
|
- Update to version 11517
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="oscam"
|
PKG_NAME="oscam"
|
||||||
PKG_VERSION="a2ee0528f1de527748aaf7a79982ed112ffa3183"
|
PKG_VERSION="e8ce7359fa920ca8d63aca9dde4f0eeb1f1f72f1"
|
||||||
PKG_SHA256="24315471faea612a25b39fc14050f4fad4365715fde48dcb0032ebdce770282d"
|
PKG_SHA256="93610d3d61479cae87340a0a3d7dc8c04b326b662f58f4181ac08c87897bd80b"
|
||||||
PKG_VERSION_NUMBER="11517"
|
PKG_VERSION_NUMBER="11518"
|
||||||
PKG_REV="108"
|
PKG_REV="109"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="GPL"
|
PKG_LICENSE="GPL"
|
||||||
PKG_SITE="http://www.streamboard.tv/oscam/wiki"
|
PKG_SITE="http://www.streamboard.tv/oscam/wiki"
|
||||||
@@ -19,17 +19,53 @@ PKG_IS_ADDON="yes"
|
|||||||
PKG_ADDON_NAME="OSCam"
|
PKG_ADDON_NAME="OSCam"
|
||||||
PKG_ADDON_TYPE="xbmc.service"
|
PKG_ADDON_TYPE="xbmc.service"
|
||||||
|
|
||||||
PKG_CMAKE_OPTS_TARGET="-DLIBUSBDIR=$SYSROOT_PREFIX/usr \
|
PKG_CMAKE_OPTS_TARGET="\
|
||||||
-DWITH_SSL=1 \
|
`#Building` \
|
||||||
-DHAVE_LIBCRYPTO=1 \
|
-DLIBUSBDIR=$SYSROOT_PREFIX/usr \
|
||||||
-DHAVE_DVBAPI=1 \
|
-DOPTIONAL_INCLUDE_DIR=$SYSROOT_PREFIX/usr/include \
|
||||||
-DWITH_STAPI=0 \
|
\
|
||||||
-DWEBIF=1 \
|
`#Readers` \
|
||||||
-DWITH_DEBUG=0 \
|
-DCARDREADER_DB2COM=OFF \
|
||||||
-DOPTIONAL_INCLUDE_DIR=$SYSROOT_PREFIX/usr/include \
|
-DCARDREADER_DRECAS=ON \
|
||||||
-DSTATIC_LIBUSB=1 \
|
-DCARDREADER_INTERNAL=OFF \
|
||||||
-DCLOCKFIX=0 \
|
-DCARDREADER_MP35=ON \
|
||||||
-DCARDREADER_DB2COM=OFF"
|
-DCARDREADER_PHOENIX=ON \
|
||||||
|
-DCARDREADER_SC8IN1=ON \
|
||||||
|
-DCARDREADER_SMARGO=ON \
|
||||||
|
-DCARDREADER_STAPI5=OFF \
|
||||||
|
-DCARDREADER_STAPI=OFF \
|
||||||
|
-DCARDREADER_STINGER=ON \
|
||||||
|
\
|
||||||
|
`#Protocol` \
|
||||||
|
-DMODULE_CAMD33=OFF \
|
||||||
|
-DMODULE_CAMD35=ON \
|
||||||
|
-DMODULE_CAMD35_TCP=ON \
|
||||||
|
-DMODULE_CCCAM=ON \
|
||||||
|
-DMODULE_CCCSHARE=ON \
|
||||||
|
-DMODULE_CONSTCW=ON \
|
||||||
|
-DMODULE_GBOX=ON \
|
||||||
|
-DMODULE_GHTTP=ON \
|
||||||
|
-DMODULE_NEWCAMD=ON \
|
||||||
|
-DMODULE_PANDORA=ON \
|
||||||
|
-DMODULE_RADEGAST=ON \
|
||||||
|
-DMODULE_SCAM=ON \
|
||||||
|
-DMODULE_SERIAL=ON \
|
||||||
|
\
|
||||||
|
`#Features` \
|
||||||
|
-DCLOCKFIX=0 \
|
||||||
|
-DCS_ANTICASC=ON \
|
||||||
|
-DCS_CACHEEX=ON \
|
||||||
|
-DCW_CYCLE_CHECK=ON \
|
||||||
|
-DHAVE_DVBAPI=1 \
|
||||||
|
-DHAVE_LIBCRYPTO=1 \
|
||||||
|
-DSTATIC_LIBUSB=1 \
|
||||||
|
-DTOUCH=ON \
|
||||||
|
-DWEBIF=1 \
|
||||||
|
-DWEBIF_LIVELOG=1 \
|
||||||
|
-DWEBIF_JQUERY=1 \
|
||||||
|
-DWITH_DEBUG=0 \
|
||||||
|
-DWITH_SSL=1 \
|
||||||
|
-DWITH_STAPI=0"
|
||||||
|
|
||||||
pre_configure_target() {
|
pre_configure_target() {
|
||||||
export OSCAM_ADDON_VERSION="$PKG_VERSION_NUMBER"
|
export OSCAM_ADDON_VERSION="$PKG_VERSION_NUMBER"
|
||||||
|
|||||||
@@ -20,9 +20,7 @@ PKG_ADDON_PROJECTS="Slice Slice3"
|
|||||||
PKG_ADDON_TYPE="xbmc.service"
|
PKG_ADDON_TYPE="xbmc.service"
|
||||||
|
|
||||||
makeinstall_target() {
|
makeinstall_target() {
|
||||||
PKG_ADDON_INSTALL_DIR="${INSTALL}/usr/share/kodi/addons/${PKG_SECTION}.${PKG_NAME}"
|
install_addon_files "${INSTALL}/usr/share/kodi/addons/${PKG_SECTION}.${PKG_NAME}"
|
||||||
mkdir -p "${PKG_ADDON_INSTALL_DIR}"
|
|
||||||
install_addon_files "${PKG_ADDON_INSTALL_DIR}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addon() {
|
addon() {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
108
|
||||||
|
- Update to 1.2.0
|
||||||
|
|
||||||
107
|
107
|
||||||
- Update to 1.0.0
|
- Update to 1.0.0
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="syncthing"
|
PKG_NAME="syncthing"
|
||||||
PKG_VERSION="1.0.0"
|
PKG_VERSION="1.2.0"
|
||||||
PKG_SHA256="737161bc87c1f414c142d95e04102de2bbdc8b0bfff908a114898305956a16c1"
|
PKG_SHA256="0339877effdcf3bf8aa7d4d1e50b878992792e4752ff778f27788bf71eccecd0"
|
||||||
PKG_REV="107"
|
PKG_REV="108"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="MPLv2"
|
PKG_LICENSE="MPLv2"
|
||||||
PKG_SITE="https://syncthing.net/"
|
PKG_SITE="https://syncthing.net/"
|
||||||
PKG_URL="https://github.com/syncthing/syncthing/archive/v${PKG_VERSION}.tar.gz"
|
PKG_URL="https://github.com/syncthing/syncthing/releases/download/v${PKG_VERSION}/syncthing-source-v${PKG_VERSION}.tar.gz"
|
||||||
PKG_DEPENDS_TARGET="toolchain go:host"
|
PKG_DEPENDS_TARGET="toolchain go:host"
|
||||||
PKG_SECTION="service/system"
|
PKG_SECTION="service/system"
|
||||||
PKG_SHORTDESC="Syncthing: open source continuous file synchronization"
|
PKG_SHORTDESC="Syncthing: open source continuous file synchronization"
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
+100
|
102
|
||||||
|
- Fix a crash with segfaults on x64 machines
|
||||||
|
101
|
||||||
|
- Update
|
||||||
|
100
|
||||||
- Initial release
|
- Initial release
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
PKG_NAME="touchscreen"
|
PKG_NAME="touchscreen"
|
||||||
PKG_VERSION="1.0"
|
PKG_VERSION="1.0"
|
||||||
PKG_REV="101"
|
PKG_REV="102"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_ADDON_PROJECTS="Generic RPi Amlogic"
|
PKG_ADDON_PROJECTS="Generic RPi"
|
||||||
PKG_LICENSE="GPL"
|
PKG_LICENSE="GPL"
|
||||||
PKG_SITE=""
|
PKG_SITE=""
|
||||||
PKG_URL=""
|
PKG_URL=""
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
119
|
||||||
|
- Use system libidn2
|
||||||
|
|
||||||
118
|
118
|
||||||
- update to 4.2.7-44
|
- update to 4.2.7-44
|
||||||
- fix tv_grab_file usage of & in urls
|
- fix tv_grab_file usage of & in urls
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ PKG_NAME="tvheadend42"
|
|||||||
PKG_VERSION="5c218500579d5bd1c1f7e7a4b5f7f0fb35baa626"
|
PKG_VERSION="5c218500579d5bd1c1f7e7a4b5f7f0fb35baa626"
|
||||||
PKG_SHA256="a9fe5a4c36aa185e3f0a73a709f0dc05794ae9c12f5d888985b559ff68a2508d"
|
PKG_SHA256="a9fe5a4c36aa185e3f0a73a709f0dc05794ae9c12f5d888985b559ff68a2508d"
|
||||||
PKG_VERSION_NUMBER="4.2.7-44"
|
PKG_VERSION_NUMBER="4.2.7-44"
|
||||||
PKG_REV="118"
|
PKG_REV="119"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="GPL"
|
PKG_LICENSE="GPL"
|
||||||
PKG_SITE="http://www.tvheadend.org"
|
PKG_SITE="http://www.tvheadend.org"
|
||||||
@@ -114,7 +114,6 @@ addon() {
|
|||||||
cp -PL $(get_build_dir gnutls)/.INSTALL_PKG/usr/lib/libgnutls.so.30 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
cp -PL $(get_build_dir gnutls)/.INSTALL_PKG/usr/lib/libgnutls.so.30 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
||||||
cp -PL $(get_build_dir nettle)/.install_pkg/usr/lib/libnettle.so.6 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
cp -PL $(get_build_dir nettle)/.install_pkg/usr/lib/libnettle.so.6 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
||||||
cp -PL $(get_build_dir nettle)/.install_pkg/usr/lib/libhogweed.so.4 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
cp -PL $(get_build_dir nettle)/.install_pkg/usr/lib/libhogweed.so.4 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
||||||
cp -PL $(get_build_dir libidn2)/.install_pkg/usr/lib/libidn2.so.4 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
|
||||||
cp -PL $(get_build_dir gmp)/.install_pkg/usr/lib/libgmp.so.10 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
cp -PL $(get_build_dir gmp)/.install_pkg/usr/lib/libgmp.so.10 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
||||||
|
|
||||||
# set only version (revision will be added by buildsystem)
|
# set only version (revision will be added by buildsystem)
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
100
|
|
||||||
- Initial addon
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 37 KiB |
@@ -2,48 +2,24 @@
|
|||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
||||||
|
|
||||||
PKG_NAME="tvmosaic"
|
PKG_NAME="tvmosaic"
|
||||||
PKG_VERSION="1.0.0-16296"
|
PKG_VERSION="1.0"
|
||||||
PKG_SHA256="63d48e7b0912f2efb6e894252a13d8312679cdcb155ebe3fa758dc88b4f91816"
|
|
||||||
PKG_REV="100"
|
PKG_REV="100"
|
||||||
PKG_ARCH="any"
|
|
||||||
PKG_ARCH="arm"
|
PKG_ARCH="arm"
|
||||||
PKG_LICENSE="Prop."
|
PKG_LICENSE="GPL"
|
||||||
PKG_SITE="https://tv-mosaic.com"
|
PKG_SITE=""
|
||||||
PKG_URL="https://github.com/awiouy/tvmosaic/archive/$PKG_VERSION.tar.gz"
|
PKG_URL=""
|
||||||
PKG_DEPENDS_TARGET="toolchain"
|
PKG_DEPENDS_TARGET="toolchain"
|
||||||
PKG_SECTION="service"
|
PKG_SECTION="service"
|
||||||
PKG_SHORTDESC="TV Mosaic"
|
PKG_SHORTDESC="Add-on removed"
|
||||||
PKG_LONGDESC="TV Mosaic ($PKG_VERSION) live and recorded TV for Kodi and DLNA clients"
|
PKG_LONGDESC="Add-on removed"
|
||||||
PKG_TOOLCHAIN="manual"
|
PKG_TOOLCHAIN="manual"
|
||||||
PKG_BUILD_FLAGS="-strip"
|
|
||||||
|
PKG_ADDON_BROKEN="TV Mosaic is no longer maintained and has been removed."
|
||||||
|
|
||||||
PKG_IS_ADDON="yes"
|
PKG_IS_ADDON="yes"
|
||||||
PKG_ADDON_NAME="TV Mosaic"
|
PKG_ADDON_NAME="TV Mosaic"
|
||||||
PKG_ADDON_TYPE="xbmc.service"
|
PKG_ADDON_TYPE="xbmc.broken"
|
||||||
PKG_MAINTAINER="Anton Voyl (awiouy)"
|
|
||||||
|
|
||||||
addon() {
|
addon() {
|
||||||
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/bin
|
:
|
||||||
cp $PKG_BUILD/tvmosaic/tvmosaic_reg \
|
|
||||||
$PKG_BUILD/tvmosaic/tvmosaic_server \
|
|
||||||
$PKG_BUILD/tvmosaic/version.dat \
|
|
||||||
$ADDON_BUILD/$PKG_ADDON_ID/bin
|
|
||||||
|
|
||||||
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/config/shared.inst/RecordedTV \
|
|
||||||
$ADDON_BUILD/$PKG_ADDON_ID/config/shared.inst/channel_logo \
|
|
||||||
$ADDON_BUILD/$PKG_ADDON_ID/config/shared.inst/xmltv
|
|
||||||
cp -r $PKG_BUILD/tvmosaic/data \
|
|
||||||
$PKG_BUILD/tvmosaic/shared.inst \
|
|
||||||
$ADDON_BUILD/$PKG_ADDON_ID/config
|
|
||||||
echo $PKG_REV > $ADDON_BUILD/$PKG_ADDON_ID/config/pkg_rev
|
|
||||||
|
|
||||||
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/lib
|
|
||||||
cp -L $PKG_BUILD/tvmosaic/lib/libcares.so.2 \
|
|
||||||
$PKG_BUILD/tvmosaic/lib/libdvbapi.so \
|
|
||||||
$PKG_BUILD/tvmosaic/lib/libdvben50221.so \
|
|
||||||
$PKG_BUILD/tvmosaic/lib/libiconv.so.2 \
|
|
||||||
$PKG_BUILD/tvmosaic/lib/libidn.so.11 \
|
|
||||||
$PKG_BUILD/tvmosaic/lib/libssh2.so.1 \
|
|
||||||
$PKG_BUILD/tvmosaic/lib/libucsi.so \
|
|
||||||
$ADDON_BUILD/$PKG_ADDON_ID/lib
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
. /etc/profile
|
|
||||||
oe_setup_addon service.tvmosaic
|
|
||||||
|
|
||||||
export TVMOSAIC_ROOT_CONFIG_DIR="$ADDON_HOME"
|
|
||||||
|
|
||||||
tvmosaic_server -command_line_mode
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
. /etc/profile
|
|
||||||
oe_setup_addon service.tvmosaic
|
|
||||||
|
|
||||||
sleep "$tvm_delay"
|
|
||||||
|
|
||||||
export TVMOSAIC_ROOT_CONFIG_DIR="$ADDON_HOME"
|
|
||||||
|
|
||||||
pkg_rev() {
|
|
||||||
cat "$1/pkg_rev" 2> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$(pkg_rev $ADDON_DIR/config)" != "$(pkg_rev $ADDON_HOME)" ]; then
|
|
||||||
cp -r "$ADDON_DIR/config/"* "$ADDON_HOME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$ADDON_HOME/tvmosaic_configuration.xml" ]; then
|
|
||||||
tvmosaic_reg -reginstall "$ADDON_HOME/data/common/product_info/tvmosaic.xml" update
|
|
||||||
else
|
|
||||||
tvmosaic_reg -preparenewinstall "$ADDON_DIR/bin" "$ADDON_HOME/data" "$ADDON_HOME/shared.inst"
|
|
||||||
tvmosaic_reg -reginstall "$ADDON_HOME/data/common/product_info/tvmosaic.xml" install
|
|
||||||
fi
|
|
||||||
|
|
||||||
tvmosaic_server
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import xbmc
|
|
||||||
import xbmcaddon
|
|
||||||
|
|
||||||
|
|
||||||
def systemctl(command):
|
|
||||||
subprocess.call(
|
|
||||||
['systemctl', command, xbmcaddon.Addon().getAddonInfo('id')])
|
|
||||||
|
|
||||||
|
|
||||||
class Monitor(xbmc.Monitor):
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
xbmc.Monitor.__init__(self)
|
|
||||||
|
|
||||||
def onSettingsChanged(self):
|
|
||||||
systemctl('restart')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
Monitor().waitForAbort()
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# Kodi Media Center language file
|
|
||||||
# Addon Name: tvmosaic
|
|
||||||
# Addon id: service.tvmosaic
|
|
||||||
# Addon Provider: Team LibreELEC
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30000"
|
|
||||||
msgid "Configuration"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30001"
|
|
||||||
msgid "Start delay"
|
|
||||||
msgstr ""
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
|
||||||
<settings>
|
|
||||||
<category label="30000">
|
|
||||||
<setting label="30001" id="tvm_delay" type="number" default="0"/>
|
|
||||||
</category>
|
|
||||||
</settings>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<settings version="2">
|
|
||||||
<setting id="tvm_delay" default="true">0</setting>
|
|
||||||
</settings>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=TV Mosaic Server
|
|
||||||
Documentation=https://tv-mosaic.com
|
|
||||||
After=network-online.target
|
|
||||||
Requires=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/bin/sh /storage/.kodi/addons/service.tvmosaic/bin/tvmosaic.start
|
|
||||||
Type=forking
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=kodi.target
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
107
|
||||||
|
- Update to 2.2.6
|
||||||
|
|
||||||
106
|
106
|
||||||
- Update to 2.2.4
|
- Update to 2.2.4
|
||||||
|
|
||||||
|
|||||||
@@ -4,24 +4,24 @@
|
|||||||
case "$ARCH" in
|
case "$ARCH" in
|
||||||
"aarch64")
|
"aarch64")
|
||||||
PKG_NC_ARCH="arm64"
|
PKG_NC_ARCH="arm64"
|
||||||
PKG_SHA256="492de061d1e01862c2f208287c5454a19650ab2d6441554347d847656900da70"
|
PKG_SHA256="48d58ac6ff958ec7155befe76f83e276aceff50c4a7d1f578444a9a40720e412"
|
||||||
PKG_URL="https://download.visualstudio.microsoft.com/download/pr/9e06922d-3a96-4f0d-9eb0-94f2cf94458f/93dfe5f0ad50c0eb347e98d7f81b34ec/dotnet-runtime-2.2.4-linux-arm64.tar.gz"
|
PKG_URL="https://download.visualstudio.microsoft.com/download/pr/f5e04830-50fc-435c-8bb5-fcd4629da944/8aa7cce5c3fcb6a7db180b923d3574ef/dotnet-runtime-2.2.6-linux-arm64.tar.gz"
|
||||||
;;
|
;;
|
||||||
"arm")
|
"arm")
|
||||||
PKG_NC_ARCH="arm"
|
PKG_NC_ARCH="arm"
|
||||||
PKG_SHA256="06cc0010e92591c350fe010feacdd6bb55294f89e97ea30eac5a46c33fd8d1f4"
|
PKG_SHA256="a4f2e63471c296b7b173105a2c1d5feb95b81e0a8131f73aeecc00440fa5f544"
|
||||||
PKG_URL="https://download.visualstudio.microsoft.com/download/pr/8c52648c-bedd-44b0-9442-95cd830fdada/d6ba4c50a6b2afddc4ae3d313349f3ac/dotnet-runtime-2.2.4-linux-arm.tar.gz"
|
PKG_URL="https://download.visualstudio.microsoft.com/download/pr/428aaa32-f66c-4847-b845-aa21f90504e4/1cf033db866414997140c2672bd75069/dotnet-runtime-2.2.6-linux-arm.tar.gz"
|
||||||
;;
|
;;
|
||||||
"x86_64")
|
"x86_64")
|
||||||
PKG_NC_ARCH="x64"
|
PKG_NC_ARCH="x64"
|
||||||
PKG_SHA256="0e494df7a3936ac59c17de3b91d928bb3ab3cdd1e6734d581ad4774f551ca239"
|
PKG_SHA256="e30d4568c62d747b030e3c74f3d528ecb8d5c90e844e506bc0e3fcbce52b8cb1"
|
||||||
PKG_URL="https://download.visualstudio.microsoft.com/download/pr/853048a3-764a-4b4d-a608-c6144a84f257/99c5cb1ea145f9dc3c2bbd093c682c9b/dotnet-runtime-2.2.4-linux-x64.tar.gz"
|
PKG_URL="https://download.visualstudio.microsoft.com/download/pr/9f21e352-9d2c-4e3b-af45-915da89158db/0e8a7ea83cc08d4bcf417a927a36ed6f/dotnet-runtime-2.2.6-linux-x64.tar.gz"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
PKG_NAME="dotnet-runtime"
|
PKG_NAME="dotnet-runtime"
|
||||||
PKG_VERSION="2.2.4"
|
PKG_VERSION="2.2.6"
|
||||||
PKG_REV="106"
|
PKG_REV="107"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="MIT"
|
PKG_LICENSE="MIT"
|
||||||
PKG_SITE="https://dotnet.github.io/"
|
PKG_SITE="https://dotnet.github.io/"
|
||||||
@@ -36,14 +36,9 @@ PKG_ADDON_NAME=".Net Core Runtime"
|
|||||||
PKG_ADDON_TYPE="xbmc.python.script"
|
PKG_ADDON_TYPE="xbmc.python.script"
|
||||||
PKG_MAINTAINER="Anton Voyl (awiouy)"
|
PKG_MAINTAINER="Anton Voyl (awiouy)"
|
||||||
|
|
||||||
unpack() {
|
|
||||||
mkdir -p $PKG_BUILD
|
|
||||||
$SCRIPTS/extract $PKG_NAME $PKG_BUILD
|
|
||||||
}
|
|
||||||
|
|
||||||
addon() {
|
addon() {
|
||||||
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/bin
|
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/bin
|
||||||
cp -r $PKG_BUILD/$PKG_NAME-$PKG_VERSION/* \
|
cp -r $PKG_BUILD/* \
|
||||||
$ADDON_BUILD/$PKG_ADDON_ID/bin
|
$ADDON_BUILD/$PKG_ADDON_ID/bin
|
||||||
|
|
||||||
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/libs
|
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/libs
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
106
|
||||||
|
- Use system libidn2
|
||||||
|
|
||||||
105
|
105
|
||||||
- Removed FDK-AAC
|
- Removed FDK-AAC
|
||||||
- Build with GNUTLS
|
- Build with GNUTLS
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
PKG_NAME="ffmpeg-tools"
|
PKG_NAME="ffmpeg-tools"
|
||||||
PKG_VERSION="1.0"
|
PKG_VERSION="1.0"
|
||||||
PKG_REV="105"
|
PKG_REV="106"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="GPL"
|
PKG_LICENSE="GPL"
|
||||||
PKG_SITE="https://libreelec.tv"
|
PKG_SITE="https://libreelec.tv"
|
||||||
@@ -25,7 +25,6 @@ addon() {
|
|||||||
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/lib
|
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/lib
|
||||||
cp -PL $(get_build_dir gmp)/.install_pkg/usr/lib/libgmp.so.10 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
cp -PL $(get_build_dir gmp)/.install_pkg/usr/lib/libgmp.so.10 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
||||||
cp -PL $(get_build_dir gnutls)/.INSTALL_PKG/usr/lib/libgnutls.so.30 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
cp -PL $(get_build_dir gnutls)/.INSTALL_PKG/usr/lib/libgnutls.so.30 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
||||||
cp -PL $(get_build_dir libidn2)/.install_pkg/usr/lib/libidn2.so.4 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
|
||||||
cp -PL $(get_build_dir nettle)/.install_pkg/usr/lib/libhogweed.so.4 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
cp -PL $(get_build_dir nettle)/.install_pkg/usr/lib/libhogweed.so.4 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
||||||
cp -PL $(get_build_dir nettle)/.install_pkg/usr/lib/libnettle.so.6 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
cp -PL $(get_build_dir nettle)/.install_pkg/usr/lib/libnettle.so.6 $ADDON_BUILD/$PKG_ADDON_ID/lib
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user