diff --git a/package/lean/luci-app-airplay2/Makefile b/package/lean/luci-app-airplay2/Makefile new file mode 100644 index 0000000000..29dded12cc --- /dev/null +++ b/package/lean/luci-app-airplay2/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=Luci for Apple Airplay2 Receiver +LUCI_DEPENDS:=@TARGET_x86 +alsa-utils +kmod-sound-hda-core +kmod-sound-hda-codec-realtek +kmod-sound-hda-codec-via +kmod-sound-via82xx +kmod-sound-hda-intel +shairport-sync-openssl +LUCI_PKGARCH:=all +PKG_VERSION:=1 +PKG_RELEASE:=6 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + diff --git a/package/lean/luci-app-airplay2/luasrc/controller/shairport-sync.lua b/package/lean/luci-app-airplay2/luasrc/controller/shairport-sync.lua new file mode 100644 index 0000000000..22d0ffa0eb --- /dev/null +++ b/package/lean/luci-app-airplay2/luasrc/controller/shairport-sync.lua @@ -0,0 +1,22 @@ +-- Copyright 2014 Álvaro Fernández Rojas +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.shairport-sync", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/shairport-sync") then + return + end + + entry({"admin", "services", "shairport-sync"}, cbi("shairport-sync"), _("AirPlay 2 Receiver")).dependent = true + + entry({"admin","services","shairport-sync","run"},call("act_status")).leaf=true + +end + +function act_status() + local e={} + e.running=luci.sys.call("pgrep shairport-sync >/dev/null")==0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/package/lean/luci-app-airplay2/luasrc/model/cbi/shairport-sync.lua b/package/lean/luci-app-airplay2/luasrc/model/cbi/shairport-sync.lua new file mode 100644 index 0000000000..2e016fa075 --- /dev/null +++ b/package/lean/luci-app-airplay2/luasrc/model/cbi/shairport-sync.lua @@ -0,0 +1,55 @@ +-- Copyright 2020 Lean +-- Licensed to the public under the Apache License 2.0. + +m = Map("shairport-sync", translate("Apple AirPlay 2 Receiver"), translate("Apple AirPlay 2 Receiver is a simple AirPlay server implementation")) + +m:section(SimpleSection).template = "shairport-sync/shairport-sync_status" + +s = m:section(TypedSection, "shairport-sync") +s.addremove = false +s.anonymous = true + +enable=s:option(Flag, "enabled", translate("Enabled")) +enable.default = "0" +enable.rmempty = false + +respawn=s:option(Flag, "respawn", translate("Respawn")) +respawn.default = false + +apname = s:option(Value, "name", translate("Airport Name")) +apname.rmempty = false + +auth=s:option(Flag, "auth", translate("Password Auth")) +auth.default = false + +pw = s:option(Value, "password", translate("Password")) +pw.rmempty = true +pw.password = true +pw.default = "" +pw:depends("auth", "1") + +interpolation=s:option(ListValue, "interpolation", translate("Interpolation")) +interpolation:value("basic", translate("Internal Basic Resampler")) +interpolation:value("soxr", translate("High quality SoX Resampler")) + +port=s:option(Value, "port", translate("Port")) +port.rmempty = false +port.datatype = "port" + +alsa_output_device=s:option(ListValue, "alsa_output_device", translate("Alsa Output Device")) +alsa_output_device:value("", translate("default")) +alsa_output_device:value("hw:0", translate("1st Soundcard")) +alsa_output_device:value("hw:1", translate("2nd Soundcard")) + +alsa_mixer_control_name=s:option(ListValue, "alsa_mixer_control_name", translate("Alsa Mixer Control Name")) +alsa_mixer_control_name:value("", translate("default")) +alsa_mixer_control_name:value("PCM", translate("PCM")) + +alsa_output_rate=s:option(ListValue, "alsa_output_rate", translate("Alsa Output Rate")) +alsa_output_rate:value("auto", translate("auto")) +alsa_output_rate:value("44100", translate("44.1Khz")) +alsa_output_rate:value("88200", translate("88.2Khz")) +alsa_output_rate:value("176400", translate("176.4Khz")) +alsa_output_rate:value("352800", translate("352.8Khz")) + +return m diff --git a/package/lean/luci-app-airplay2/luasrc/view/shairport-sync/shairport-sync_status.htm b/package/lean/luci-app-airplay2/luasrc/view/shairport-sync/shairport-sync_status.htm new file mode 100644 index 0000000000..a5358956c7 --- /dev/null +++ b/package/lean/luci-app-airplay2/luasrc/view/shairport-sync/shairport-sync_status.htm @@ -0,0 +1,22 @@ + + +
+

+ <%:Collecting data...%> +

+
\ No newline at end of file diff --git a/package/lean/luci-app-airplay2/po/zh-cn/shairport-sync.po b/package/lean/luci-app-airplay2/po/zh-cn/shairport-sync.po new file mode 100644 index 0000000000..9cf25802f2 --- /dev/null +++ b/package/lean/luci-app-airplay2/po/zh-cn/shairport-sync.po @@ -0,0 +1,56 @@ +msgid "" +msgstr "" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-06-23 20:16+0800\n" +"PO-Revision-Date: 2015-06-23 20:17+0800\n" +"Last-Translator: coolsnowwolf \n" +"Language-Team: PandoraBox Team\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.1\n" +"X-Poedit-SourceCharset: UTF-8\n" + +msgid "AirPlay 2 Receiver" +msgstr "AirPlay 2 音频接收器" + +msgid "Respawn" +msgstr "进程守护" + +msgid "Apple AirPlay 2 Receiver" +msgstr "Apple AirPlay 2 无损音频接收服务器" + +msgid "Apple AirPlay 2 Receiver is a simple AirPlay server implementation" +msgstr "Apple AirPlay 2 是一个强大易用的无损音频服务器( iOS/MacOSX 原生支持)" + +msgid "Airport Name" +msgstr "音频接收器名称" + +msgid "Password Auth" +msgstr "开启密码认证" + +msgid "Interpolation" +msgstr "音频重采样" + +msgid "Internal Basic Resampler" +msgstr "内置" + +msgid "High quality SoX Resampler" +msgstr "高质量 SoX 采样器(需要强力的CPU)" + +msgid "Alsa Output Device" +msgstr "音频输出设备" + +msgid "Alsa Mixer Control Name" +msgstr "硬件音量控制器名称" + +msgid "1st Soundcard" +msgstr "第 1 张声卡" + +msgid "2nd Soundcard" +msgstr "第 2 张声卡" + +msgid "Alsa Output Rate" +msgstr "音频输出采样率" diff --git a/package/lean/luci-app-airplay2/root/etc/asound.conf b/package/lean/luci-app-airplay2/root/etc/asound.conf new file mode 100644 index 0000000000..3cb6f7eeb4 --- /dev/null +++ b/package/lean/luci-app-airplay2/root/etc/asound.conf @@ -0,0 +1,2 @@ +defaults.pcm.dmix.rate 44100 # Force 44.1 KHz +defaults.pcm.dmix.format S16_LE # Force 16 bits diff --git a/package/lean/luci-app-airplay2/root/etc/config/shairport-sync b/package/lean/luci-app-airplay2/root/etc/config/shairport-sync new file mode 100644 index 0000000000..ff385a24c8 --- /dev/null +++ b/package/lean/luci-app-airplay2/root/etc/config/shairport-sync @@ -0,0 +1,12 @@ + +config shairport-sync 'shairport_sync' + option respawn '1' + option output_backend 'alsa' + option mdns_backend 'avahi' + option alsa_output_rate '44100' + option port '5050' + option name 'AirPlay 2 On OpenWrt' + option auth '0' + option interpolation 'basic' + option enabled '0' + diff --git a/package/lean/luci-app-airplay2/root/etc/init.d/shairport-sync b/package/lean/luci-app-airplay2/root/etc/init.d/shairport-sync new file mode 100755 index 0000000000..358b759da9 --- /dev/null +++ b/package/lean/luci-app-airplay2/root/etc/init.d/shairport-sync @@ -0,0 +1,150 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2015-2016 OpenWrt.org + +START=99 +USE_PROCD=1 + +append_num() { + local cfg="$1" + local file="$2" + local var="$3" + local opt="$4" + local def="$5" + local val + + config_get val "$cfg" "$var" + [ -n "$val" -o -n "$def" ] && echo -e "\t$opt = ${val:-$def};" >> $file +} +append_str() { + local cfg="$1" + local file="$2" + local var="$3" + local opt="$4" + local def="$5" + local val + + config_get val "$cfg" "$var" + [ -n "$val" -o -n "$def" ] && echo -e "\t$opt = \"${val:-$def}\";" >> $file +} + +start_instance() { + local cfg=$1 + local conf_custom conf_file aux + + config_get_bool aux "$cfg" 'enabled' '0' + [ "$aux" = 0 ] && return 1 + + config_get_bool conf_custom "$cfg" 'conf_custom' '0' + config_get conf_file "$cfg" "conf_file" + if [ $conf_custom -ne 1 ] && [ ! -n "$conf_file" ]; then + mkdir -p /var/etc + conf_file="/var/etc/shairport-sync-${cfg}.conf" + + echo -e "// Automatically generated from UCI config\n" > $conf_file + + # General + echo -e "general =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" name "name" + append_str "$cfg" "$conf_file" password "password" + append_str "$cfg" "$conf_file" interpolation "interpolation" + append_str "$cfg" "$conf_file" output_backend "output_backend" "alsa" + append_str "$cfg" "$conf_file" mdns_backend "mdns_backend" "avahi" + append_num "$cfg" "$conf_file" port "port" 5050 + append_num "$cfg" "$conf_file" udp_port_base "udp_port_base" + append_num "$cfg" "$conf_file" udp_port_range "udp_port_range" + append_str "$cfg" "$conf_file" statistics "statistics" + append_num "$cfg" "$conf_file" drift "drift" + append_num "$cfg" "$conf_file" resync_threshold "resync_threshold" + append_num "$cfg" "$conf_file" log_verbosity "log_verbosity" + append_str "$cfg" "$conf_file" ignore_volume_control "ignore_volume_control" + append_num "$cfg" "$conf_file" volume_range_db "volume_range_db" + append_str "$cfg" "$conf_file" regtype "regtype" + append_str "$cfg" "$conf_file" playback_mode "playback_mode" + echo -e "};\n" >> $conf_file + + # Metadata + echo -e "metadata =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" metadata_enabled "enabled" + append_str "$cfg" "$conf_file" metadata_cover_art "include_cover_art" + append_str "$cfg" "$conf_file" metadata_pipe_name "pipe_name" + append_num "$cfg" "$conf_file" metadata_pipe_timeout "pipe_timeout" + append_str "$cfg" "$conf_file" metadata_socket_address "socket_address" + append_num "$cfg" "$conf_file" metadata_socket_port "socket_port" + append_num "$cfg" "$conf_file" metadata_socket_msglength "socket_msglength" + echo -e "};\n" >> $conf_file + + # Session control + echo -e "sessioncontrol =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" sesctl_run_before_play_begins "run_this_before_play_begins" + append_str "$cfg" "$conf_file" sesctl_run_after_play_ends "run_this_after_play_ends" + append_str "$cfg" "$conf_file" sesctl_wait_for_completion "wait_for_completion" + append_str "$cfg" "$conf_file" sesctl_session_interruption "allow_session_interruption" + append_num "$cfg" "$conf_file" sesctl_session_timeout "session_timeout" + echo -e "};\n" >> $conf_file + + # Alsa audio back end + echo -e "alsa =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" alsa_output_device "output_device" + append_str "$cfg" "$conf_file" alsa_mixer_control_name "mixer_control_name" "" + append_str "$cfg" "$conf_file" alsa_mixer_device "mixer_device" + append_str "$cfg" "$conf_file" alsa_output_rate "output_rate" "44100" + append_num "$cfg" "$conf_file" alsa_latency_offset "audio_backend_latency_offset" + append_num "$cfg" "$conf_file" alsa_buffer_length "audio_backend_buffer_desired_length" + append_str "$cfg" "$conf_file" alsa_disable_synchronization "disable_synchronization" + append_num "$cfg" "$conf_file" alsa_period_size "period_size" + append_num "$cfg" "$conf_file" alsa_buffer_size "buffer_size" + echo -e "};\n" >> $conf_file + + # Pipe audio back end + echo -e "pipe =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" pipe_name "name" + append_num "$cfg" "$conf_file" pipe_latency_offset "audio_backend_latency_offset" + append_num "$cfg" "$conf_file" pipe_buffer_length "audio_backend_buffer_desired_length" + echo -e "};\n" >> $conf_file + + # Stdout audio back end + echo -e "stdout =" >> $conf_file + echo -e "{" >> $conf_file + append_num "$cfg" "$conf_file" stdout_latency_offset "audio_backend_latency_offset" + append_num "$cfg" "$conf_file" stdout_buffer_length "audio_backend_buffer_desired_length" + echo -e "};\n" >> $conf_file + + # AO audio back end + echo -e "ao =" >> $conf_file + echo -e "{" >> $conf_file + append_num "$cfg" "$conf_file" ao_latency_offset "audio_backend_latency_offset" + append_num "$cfg" "$conf_file" ao_buffer_length "audio_backend_buffer_desired_length" + echo -e "};\n" >> $conf_file + fi + + procd_open_instance + + procd_set_param command /usr/bin/shairport-sync + procd_append_param command -c $conf_file + + config_get_bool aux "$cfg" 'respawn' '0' + [ "$aux" = 1 ] && procd_set_param respawn + + procd_close_instance +} + +service_triggers() { + procd_add_reload_trigger "shairport-sync" +} + +start_service() { + config_load shairport-sync + config_foreach start_instance shairport-sync +} + +boot() { + amixer set Master unmute + amixer set Master 100% + amixer set PCM 100% + start +} \ No newline at end of file diff --git a/package/lean/luci-app-airplay2/root/etc/uci-defaults/shairport-sync b/package/lean/luci-app-airplay2/root/etc/uci-defaults/shairport-sync new file mode 100755 index 0000000000..c685cab990 --- /dev/null +++ b/package/lean/luci-app-airplay2/root/etc/uci-defaults/shairport-sync @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@shairport-sync[-1] + add ucitrack shairport-sync + set ucitrack.@shairport-sync[-1].init=shairport-sync + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0