archive
commit
c5fa6baecd
|
|
@ -0,0 +1,8 @@
|
|||
#! /bin/bash
|
||||
|
||||
docker run --rm -it \
|
||||
--name=ampache \
|
||||
-v $PWD/mnt:/media:ro \
|
||||
-p 8080:80 \
|
||||
ampache/ampache
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#! /bin/bash
|
||||
|
||||
docker run --rm -it \
|
||||
--name=booksonic \
|
||||
-e PUID=$(id -u) \
|
||||
-e PGID=$(id -g) \
|
||||
-e TZ=Europe/London \
|
||||
-e CONTEXT_PATH=localhost \
|
||||
-p 4041:4040 \
|
||||
-v $PWD/mnt/config:/config \
|
||||
-v $PWD/mnt/audiobooks:/audiobooks \
|
||||
-v $PWD/mnt/podcasts:/podcasts \
|
||||
-v $PWD/mnt/othermedia:/othermedia \
|
||||
linuxserver/booksonic
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#! /bin/bash
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
mkdir -p ./mnt/{media,config,storage}
|
||||
chmod -R 777 ./mnt
|
||||
|
||||
echo 'The default username for the web ui is "admin@example.com", password is "admin"'
|
||||
echo 'Run `chmod -R 777 /opt/koel/storage` when it starts nginx'
|
||||
|
||||
docker run --rm -it \
|
||||
-p 8050:8050 \
|
||||
-p 8060:8060 \
|
||||
--name=koel \
|
||||
-v $PWD/mnt/media:/media \
|
||||
-e PHP_MEMORY_LIMIT=2048 \
|
||||
-e FASTCGI_READ_TIMEOUT=6000 \
|
||||
-e UMASK=000 \
|
||||
-e PUID=0 \
|
||||
-e PGID=0 \
|
||||
binhex/arch-koel
|
||||
|
||||
#-v $PWD/mnt/storage:/opt/koel/storage \
|
||||
#-v $PWD/mnt/config:/config \
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#! /bin/bash
|
||||
|
||||
docker-compose up
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
version: '3.4'
|
||||
|
||||
services:
|
||||
koel:
|
||||
image: 0xcaff/koel
|
||||
depends_on:
|
||||
- database
|
||||
ports:
|
||||
- 8080:80
|
||||
environment:
|
||||
DB_CONNECTION: mysql
|
||||
DB_HOST: database
|
||||
DB_USERNAME: koel
|
||||
DB_PASSWORD: koel
|
||||
DB_DATABASE: koel
|
||||
volumes:
|
||||
- music:/music
|
||||
- covers:/var/www/html/public/img/covers
|
||||
|
||||
database:
|
||||
image: mysql/mysql-server:5.7
|
||||
volumes:
|
||||
- db:/var/lib/mysql
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
MYSQL_DATABASE: koel
|
||||
MYSQL_USER: koel
|
||||
MYSQL_PASSWORD: koel
|
||||
|
||||
volumes:
|
||||
db:
|
||||
driver: local
|
||||
|
||||
music:
|
||||
driver: local
|
||||
|
||||
covers:
|
||||
driver: local
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
FUCK its nice but doesnt save position
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
*.swo
|
||||
*.swp
|
||||
mnt
|
||||
goprox/goprox
|
||||
goproxystate
|
||||
libmpc
|
||||
mpc
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
FROM frolvlad/alpine-glibc:alpine-3.9_glibc-2.28
|
||||
#FROM vimagick/mpd:latest
|
||||
|
||||
RUN apk add --no-cache \
|
||||
gcc libc-dev \
|
||||
curl \
|
||||
bash \
|
||||
mpd \
|
||||
mpc \
|
||||
fcron \
|
||||
busybox-suid \
|
||||
ympd
|
||||
|
||||
RUN crond
|
||||
|
||||
WORKDIR /opt
|
||||
RUN addgroup -S user && adduser -S -G user user
|
||||
RUN mkdir -p \
|
||||
/mnt/media \
|
||||
/mnt/playlists \
|
||||
/mnt/database \
|
||||
/var/log/mpd/mpd.log \
|
||||
&& chown -R user:user /mnt /var/log/mpd /opt
|
||||
|
||||
USER user
|
||||
|
||||
COPY ./pause.c ./pause.c
|
||||
RUN gcc ./pause.c -o ./pause
|
||||
|
||||
COPY ./goprox/goprox ./goprox
|
||||
|
||||
COPY ./mpd.conf /etc/mpd.conf
|
||||
COPY ./entrypoint.sh ./entrypoint.sh
|
||||
COPY ./stop.sh ./stop.sh
|
||||
|
||||
CMD []
|
||||
ENTRYPOINT ["bash", "./entrypoint.sh"]
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#! /bin/bash
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
cd "$(dirname "$BASH_SOURCE")"
|
||||
|
||||
pushd ./goprox
|
||||
GOOS=linux GOARCH=amd64 go build
|
||||
popd
|
||||
|
||||
docker network create mpdnet || true
|
||||
|
||||
docker build -t dev:dev .
|
||||
|
||||
chmod -R 777 $PWD/mnt $PWD/goproxystate
|
||||
|
||||
docker images | grep dev.*dev
|
||||
docker run --rm -it \
|
||||
--name dev \
|
||||
--network mpdnet \
|
||||
-v $PWD/mnt:/mnt \
|
||||
-v $PWD/mpd.conf:/etc/mpd.conf \
|
||||
-v $PWD/goproxystate:/opt/goproxystate \
|
||||
-p 4041:4041 \
|
||||
-p 8000:8000 \
|
||||
-p 7000:7000 \
|
||||
dev:dev
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#! /bin/bash
|
||||
set -u
|
||||
set -e
|
||||
|
||||
function main() {
|
||||
start_mpd
|
||||
init_mpd
|
||||
|
||||
start_ympd
|
||||
|
||||
start_goprox
|
||||
|
||||
init_cron
|
||||
|
||||
exec /opt/pause
|
||||
}
|
||||
|
||||
function start_mpd() {
|
||||
mpd --stdout --no-daemon &
|
||||
disown %1
|
||||
sleep 1
|
||||
until curl localhost:6600 2> /dev/null; do
|
||||
echo waiting for mpd...
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
function start_ympd() {
|
||||
ympd -h localhost -p 6600 -w 4041 &
|
||||
disown %1
|
||||
}
|
||||
|
||||
function start_goprox() {
|
||||
./goprox -port 7000 -httpd 8000 -mpd 6600 &
|
||||
disown %1
|
||||
}
|
||||
|
||||
function init_mpd() {
|
||||
mpc update
|
||||
mpc consume 0
|
||||
mpc repeat 1
|
||||
mpc random 1
|
||||
mpc clear
|
||||
if [ -n "$(mpc lsplaylists | grep RESTORE)" ]; then
|
||||
mpc load RESTORE
|
||||
fi
|
||||
mpc play
|
||||
mpc pause
|
||||
}
|
||||
|
||||
function init_cron() {
|
||||
echo '
|
||||
#! /bin/sh
|
||||
set -e
|
||||
set -u
|
||||
mpc rm RESTORE || true
|
||||
mpc save RESTORE
|
||||
echo "Done: $(date)" >> /opt/mpd.save.log
|
||||
' > /opt/mpd.save.sh
|
||||
chmod +x /opt/mpd.save.sh
|
||||
|
||||
echo '*/15 * * * * sh /opt/mpd.save.sh' > /opt/cron
|
||||
crontab /opt/cron
|
||||
}
|
||||
|
||||
if [ "$0" == "${BASH_SOURCE[0]}" ]; then
|
||||
main "${@:-}"
|
||||
fi
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
https://github.com/MusicPlayerDaemon/mpc/blob/master/src/command.c
|
||||
^ get the commands raw
|
||||
|
|
@ -0,0 +1,277 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type mpd struct {
|
||||
conns int32
|
||||
port string
|
||||
httpd string
|
||||
mpd string
|
||||
stateChange chan string
|
||||
stateFilePath string
|
||||
}
|
||||
|
||||
func main() {
|
||||
listenPort := flag.String("port", "7000", "port to listen on")
|
||||
httpdPort := flag.String("httpd", "8000", "port to forward to")
|
||||
mpdPort := flag.String("mpd", "6600", "port of mpd")
|
||||
flag.Parse()
|
||||
|
||||
mpd := &mpd{
|
||||
conns: int32(0),
|
||||
port: ":" + strings.TrimPrefix(*listenPort, ":"),
|
||||
httpd: ":" + strings.TrimPrefix(*httpdPort, ":"),
|
||||
mpd: ":" + strings.TrimPrefix(*mpdPort, ":"),
|
||||
stateChange: make(chan string, 6),
|
||||
stateFilePath: "/mnt/goproxystate",
|
||||
}
|
||||
|
||||
go mpd.proxy()
|
||||
go mpd.periodic()
|
||||
|
||||
catchSignal()
|
||||
mpd.close()
|
||||
}
|
||||
|
||||
func (mpd *mpd) proxy() {
|
||||
go mpd.queueStateChange()
|
||||
mpd.setState("pause")
|
||||
mpd.loadState()
|
||||
log.Printf("xferring %v -> %v", mpd.port, mpd.httpd)
|
||||
listen, err := net.Listen("tcp", ":"+strings.TrimPrefix(mpd.port, ":"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for {
|
||||
conn, err := listen.Accept()
|
||||
if err != nil {
|
||||
log.Printf("accept err: %v", err)
|
||||
} else {
|
||||
remote, err := net.Dial("tcp", mpd.httpd)
|
||||
if err != nil {
|
||||
log.Printf("dial err: %v", err)
|
||||
} else {
|
||||
log.Printf("xferring r:%v <-> c:%v", remote.RemoteAddr(), conn.RemoteAddr())
|
||||
go mpd.xfer(conn, remote)
|
||||
go mpd.xfer(remote, conn)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mpd *mpd) periodic() {
|
||||
for {
|
||||
time.Sleep(time.Hour)
|
||||
if err := mpd.saveState(); err != nil {
|
||||
log.Printf("MPD failed to save state: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mpd *mpd) queueStateChange() {
|
||||
minSilence := time.Second * 1
|
||||
for {
|
||||
last := <-mpd.stateChange
|
||||
complete := false
|
||||
for !complete {
|
||||
select {
|
||||
case last = <-mpd.stateChange:
|
||||
case <-time.After(minSilence):
|
||||
complete = true
|
||||
}
|
||||
}
|
||||
mpd.setState(last)
|
||||
}
|
||||
}
|
||||
|
||||
func (mpd *mpd) queueState(state string) {
|
||||
log.Printf("queue state %q", state)
|
||||
mpd.stateChange <- state
|
||||
}
|
||||
|
||||
func (mpd *mpd) setState(state string) {
|
||||
log.Printf("Set state: %v", state)
|
||||
defer log.Printf("/Set state: %v", state)
|
||||
|
||||
was, err := mpd.getStatus()
|
||||
if err != nil {
|
||||
log.Printf("cannot get state: %v", err)
|
||||
return
|
||||
}
|
||||
log.Printf("WAS: %v", was)
|
||||
if was["state"] == state {
|
||||
log.Printf("state is already %q: %q", state, was["state"])
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := mpd.mpdCommand(state); err != nil {
|
||||
log.Printf("MPD %q returned err on cmd: %v", state, err)
|
||||
return
|
||||
}
|
||||
if state != "pause" {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := mpd.mpdCommand("seekcur -15"); err != nil {
|
||||
log.Printf("MPD seek -15s returned err: %v", err)
|
||||
return
|
||||
} else if err := mpd.saveState(); err != nil {
|
||||
log.Printf("MPD failed to save state: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (mpd *mpd) loadState() error {
|
||||
log.Printf("LOAD STATE")
|
||||
var m map[string]string
|
||||
if b, err := ioutil.ReadFile(mpd.stateFilePath); err != nil {
|
||||
log.Printf("1 %v", err)
|
||||
return err
|
||||
} else if err := json.Unmarshal(b, &m); err != nil {
|
||||
log.Printf("2 %v", err)
|
||||
return err
|
||||
} else if _, err := mpd.mpdCommand("play " + m["song"]); err != nil {
|
||||
log.Printf("3 %v", err)
|
||||
return err
|
||||
} else if _, err := mpd.mpdCommand("pause"); err != nil {
|
||||
log.Printf("4 %v", err)
|
||||
return err
|
||||
} else if _, err := mpd.mpdCommand("seekcur " + m["elapsed"]); err != nil {
|
||||
log.Printf("5 %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mpd *mpd) saveState() error {
|
||||
if is, err := mpd.getStatus(); err != nil {
|
||||
return err
|
||||
} else if b, err := json.Marshal(is); err != nil {
|
||||
return err
|
||||
} else if err := ioutil.WriteFile(mpd.stateFilePath, b, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
shPath, err := exec.LookPath("sh")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := exec.Command(shPath, "/opt/mpd.save.sh")
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mpd *mpd) mpdCommand(cmd string) ([]string, error) {
|
||||
mpc, err := textproto.Dial("tcp", mpd.mpd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer mpc.Close()
|
||||
|
||||
if ok, err := mpc.ReadLine(); err != nil || !strings.HasPrefix(ok, "OK MPD") {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
id, err := mpc.Cmd(cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mpc.StartResponse(id)
|
||||
defer mpc.EndResponse(id)
|
||||
|
||||
b := []string{}
|
||||
line, err := mpc.ReadLine()
|
||||
for err == nil && line != "OK" {
|
||||
b = append(b, line)
|
||||
line, err = mpc.ReadLine()
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
|
||||
func (mpd *mpd) getStatus() (map[string]string, error) {
|
||||
lines, err := mpd.mpdCommand("status")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[string]string)
|
||||
for _, line := range lines {
|
||||
splits := strings.Split(line, ": ")
|
||||
if len(splits) != 2 {
|
||||
continue
|
||||
}
|
||||
m[splits[0]] = splits[1]
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (mpd *mpd) close() {
|
||||
log.Printf("CLOSE")
|
||||
}
|
||||
|
||||
func (mpd *mpd) inc() {
|
||||
if atomic.AddInt32(&mpd.conns, 1) == 1 {
|
||||
mpd.queueState("play")
|
||||
}
|
||||
mpd.blockUntilPlaying()
|
||||
}
|
||||
|
||||
func (mpd *mpd) blockUntilPlaying() {
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
resp, err := http.Get(fmt.Sprintf("http://localhost%s", mpd.httpd))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
b := make([]byte, 1024)
|
||||
if _, err := resp.Body.Read(b); err != nil {
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (mpd *mpd) dec() {
|
||||
if atomic.AddInt32(&mpd.conns, -1) == 0 {
|
||||
mpd.queueState("pause")
|
||||
}
|
||||
}
|
||||
|
||||
func (mpd *mpd) xfer(dst io.WriteCloser, src io.ReadCloser) {
|
||||
mpd.inc()
|
||||
defer mpd.dec()
|
||||
defer dst.Close()
|
||||
defer src.Close()
|
||||
io.Copy(dst, src)
|
||||
log.Printf("xfer %v -> %v ended", dst, src)
|
||||
}
|
||||
|
||||
func catchSignal() {
|
||||
log.Printf("listening for signal")
|
||||
sigc := make(chan os.Signal)
|
||||
signal.Notify(sigc,
|
||||
syscall.SIGHUP,
|
||||
syscall.SIGINT,
|
||||
syscall.SIGTERM,
|
||||
syscall.SIGQUIT,
|
||||
)
|
||||
<-sigc
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
db_file "/mnt/database/database"
|
||||
|
||||
music_directory "/mnt/media"
|
||||
playlist_directory "/mnt/playlists"
|
||||
state_file "/opt/state"
|
||||
|
||||
auto_update "yes"
|
||||
bind_to_address "0.0.0.0"
|
||||
|
||||
audio_output {
|
||||
type "httpd"
|
||||
name "Mpd_Lame"
|
||||
port "8000"
|
||||
max_clients "0"
|
||||
|
||||
encoder "flac"
|
||||
format "44100:16:1"
|
||||
|
||||
#encoder "lame"
|
||||
#bitrate "96"
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main() {
|
||||
int stat;
|
||||
int sig;
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
printf("add signal SIGINT: %i\n", sigaddset(&set, SIGINT));
|
||||
printf("add signal SIGKILL: %i\n", sigaddset(&set, SIGKILL));
|
||||
printf("add signal SIGTERM: %i\n", sigaddset(&set, SIGTERM));
|
||||
sigprocmask(SIG_BLOCK, &set, NULL);
|
||||
printf("Waiting...\n");
|
||||
stat = sigwait(&set, &sig);
|
||||
printf("Wait complete: %i (%i)\n", sig, stat);
|
||||
printf("`sh /opt/stop.sh`: %i\n", system("sh /opt/stop.sh"));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
#! /bin/bash
|
||||
set -u
|
||||
set -e
|
||||
name="$(basename ${BASH_SOURCE})"
|
||||
dir="$(dirname $(realpath ${BASH_SOURCE}))"
|
||||
mntme="$dir/$name-mnt"
|
||||
|
||||
mkdir -p $mntme
|
||||
chmod -R 777 $mntme || true
|
||||
|
||||
docker rm -f \
|
||||
mpd \
|
||||
ympd \
|
||||
rompr \
|
||||
icecast \
|
||||
|| true
|
||||
|
||||
# network
|
||||
docker network create mpdnet || true
|
||||
|
||||
# MPD // server
|
||||
mkdir -p $mntme/mpd/{playlists,db}
|
||||
touch $mntme/mpd/{conf,state}
|
||||
if [ ! -e $mntme/mpd/media ]; then
|
||||
ln -s /volume1/video/Bel/Podcast $mntme/mpd/media
|
||||
fi
|
||||
sudo docker run -d \
|
||||
--restart=unless-stopped \
|
||||
--name=mpd \
|
||||
--network=mpdnet \
|
||||
--net-alias mpd \
|
||||
--net-alias mpd.mpd \
|
||||
-v $mntme/mpd/conf:/etc/mpd.conf \
|
||||
-v $mntme/mpd/state:/state \
|
||||
-v $mntme/mpd/playlists:/playlists \
|
||||
-v $mntme/mpd/media:/media \
|
||||
-v $mntme/mpd/db:/db \
|
||||
-p 6600:6600 \
|
||||
-p 6501-6510:6501-6510 \
|
||||
-p 8000:8000 \
|
||||
vimagick/mpd
|
||||
|
||||
|
||||
sleep 2
|
||||
for cmd in update "consume 1" clear "load RESTORE" play pause; do
|
||||
docker exec -i mpd mpc $cmd
|
||||
done
|
||||
|
||||
# YMPD // remote
|
||||
sudo docker run -d \
|
||||
--restart=unless-stopped \
|
||||
--name=ympd \
|
||||
--network=mpdnet \
|
||||
--net-alias ympd \
|
||||
-p 4041:8080 \
|
||||
vitiman/alpine-ympd
|
||||
|
||||
# rompr // remote
|
||||
#sudo docker run -d \
|
||||
# --restart=unless-stopped \
|
||||
# --name=rompr \
|
||||
# --network=mpdnet \
|
||||
# --net-alias rompr \
|
||||
# -p 4042:80 \
|
||||
# rawdlite/rompr
|
||||
|
||||
# icecast // remote+player
|
||||
#sudo docker run -d \
|
||||
# --restart=unless-stopped \
|
||||
# --name=icecast \
|
||||
# --network=mpdnet \
|
||||
# --net-alias icecast \
|
||||
# -p 8000:8000 \
|
||||
# vitiman/alpine-icecast
|
||||
|
||||
# rompr // remote
|
||||
|
||||
docker exec -i mpd apk add --no-cache fcron
|
||||
docker exec -i mpd mkdir -p /etc/periodic/15min || true
|
||||
echo '
|
||||
#! /bin/sh
|
||||
mpc rm RESTORE
|
||||
mpc save RESTORE
|
||||
echo "Done: $(date)" >> /var/log/mpd_save
|
||||
' | docker exec -i mpd sh -c 'cat > /mpd_save.sh'
|
||||
echo '
|
||||
*/25 * * * * sh /mpd_save.sh
|
||||
' | docker exec -i mpd sh -c 'cat > /save_cron'
|
||||
docker exec -i mpd chmod +x /mpd_save.sh
|
||||
docker exec -i mpd crond
|
||||
docker exec -i mpd crontab /save_cron
|
||||
echo DONE
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
db_file "/db/database"
|
||||
|
||||
music_directory "/media"
|
||||
playlist_directory "/playlists"
|
||||
state_file "/state"
|
||||
auto_update "yes"
|
||||
|
||||
#audio_output {
|
||||
# type "httpd"
|
||||
# name "Mpd_Ogg"
|
||||
# encoder "vorbis" # optional, vorbis or lame
|
||||
# port "6501"
|
||||
# #quality "5.0" # do not define if bitrate is defined
|
||||
# bitrate "128"
|
||||
# max_clients "0" # optional 0=no limit
|
||||
#}
|
||||
|
||||
audio_output {
|
||||
type "httpd"
|
||||
name "Mpd_Lame"
|
||||
encoder "lame"
|
||||
port "8000"
|
||||
bitrate "128"
|
||||
format "44100:16:1"
|
||||
max_clients "0"
|
||||
bind_to_address "0.0.0.0"
|
||||
}
|
||||
|
||||
#
|
||||
#audio_output {
|
||||
# type "httpd"
|
||||
# name "Mpd_Wav"
|
||||
# encoder "wave"
|
||||
# port "6502"
|
||||
#}
|
||||
#
|
||||
#audio_output {
|
||||
# type "httpd"
|
||||
# name "Mpd_Flac"
|
||||
# encoder "flac"
|
||||
# port "6503"
|
||||
# format "44100:16:2"
|
||||
#}
|
||||
|
||||
#audio_output {
|
||||
# type "httpd"
|
||||
# name "Mpd_Lame"
|
||||
# encoder "lame"
|
||||
# port "6504"
|
||||
# bitrate "128"
|
||||
#}
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
### PAUSE
|
||||
FROM frolvlad/alpine-glibc:alpine-3.9_glibc-2.28
|
||||
RUN apk add --no-cache \
|
||||
gcc \
|
||||
libc-dev
|
||||
COPY ./pause.c /pause.c
|
||||
RUN gcc /pause.c -o /pause
|
||||
|
||||
### RUNNER
|
||||
FROM frolvlad/alpine-glibc:alpine-3.9_glibc-2.28
|
||||
|
||||
RUN apk add --no-cache \
|
||||
mpd \
|
||||
mpc \
|
||||
fcron \
|
||||
ympd
|
||||
|
||||
RUN mkdir -p \
|
||||
/mnt/{media,playlists,database} \
|
||||
/var/log/mpd/mpd.log
|
||||
|
||||
COPY --from=0 /pause /pause
|
||||
COPY ./entrypoint.sh /entrypoint.sh
|
||||
COPY ./stop.sh /stop.sh
|
||||
|
||||
CMD []
|
||||
ENTRYPOINT ["sh", "/entrypoint.sh"]
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
ps aux | grep goprox | grep -v grep
|
||||
kill $(ps aux | grep goprox | grep -v grep | awk '{print $1}') || true
|
||||
|
||||
mpd
|
||||
until curl localhost:6600 2> /dev/null; do
|
||||
sleep 1
|
||||
done
|
||||
bash "$(crontab -l | grep "\*" | awk '{print $NF}')"
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#! /bin/bash
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
function clean() {
|
||||
docker rm -f \
|
||||
mpd \
|
||||
ympd
|
||||
}
|
||||
trap clean EXIT
|
||||
|
||||
# network
|
||||
docker network create podcastnet || true
|
||||
|
||||
# mpd // server
|
||||
mkdir -p mpd-mnt/{media,playlists,db}
|
||||
mkdir -p mpd-mnt/playlists
|
||||
touch mpd-mnt/conf
|
||||
docker run --rm -d \
|
||||
--name mpd \
|
||||
-p 6501-6510:6501-6510 \
|
||||
-v $PWD/mpd-mnt/conf:/etc/mpd.conf \
|
||||
-v $PWD/mpd-mnt/playlists:/playlists \
|
||||
-v $PWD/mpd-mnt/media:/media \
|
||||
-v $PWD/mpd-mnt/db:/db \
|
||||
--network podcastnet \
|
||||
--net-alias mpd \
|
||||
vimagick/mpd
|
||||
|
||||
# --device /dev/snd
|
||||
#-v $PWD/mpd-mnt/media:/var/lib/mpd/music \
|
||||
#-v $PWD/mpd-mnt/playlists:/var/lib/mpd/playlists \
|
||||
|
||||
for cmd in "update" "repeat on" "random on" "clear" "play"; do
|
||||
docker exec -i mpd mpc $cmd
|
||||
done
|
||||
|
||||
## rompr // remote1
|
||||
#docker run --rm -d \
|
||||
# --name rompr \
|
||||
# -p 8801:80 \
|
||||
# --network podcastnet \
|
||||
# --net-alias rompr.rompr \
|
||||
# rawdlite/rompr
|
||||
|
||||
# ympd // remoteA
|
||||
docker run --rm -d \
|
||||
--name ympd \
|
||||
-p 4041:8080 \
|
||||
--network podcastnet \
|
||||
--net-alias ympd \
|
||||
vitiman/alpine-ympd
|
||||
|
||||
read -p "Enter when done..." asf
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
db_file "/db/database"
|
||||
|
||||
music_directory "/media"
|
||||
playlist_directory "/playlists"
|
||||
auto_update "yes"
|
||||
|
||||
audio_output {
|
||||
type "httpd"
|
||||
name "Mpd_Ogg"
|
||||
encoder "vorbis" # optional, vorbis or lame
|
||||
port "6501"
|
||||
quality "5.0" # do not define if bitrate is defined
|
||||
max_clients "0" # optional 0=no limit
|
||||
}
|
||||
|
||||
audio_output {
|
||||
type "httpd"
|
||||
name "Mpd_Wav"
|
||||
encoder "wave"
|
||||
port "6502"
|
||||
}
|
||||
|
||||
audio_output {
|
||||
type "httpd"
|
||||
name "Mpd_Flac"
|
||||
encoder "flac"
|
||||
port "6503"
|
||||
format "44100:16:2"
|
||||
}
|
||||
|
||||
audio_output {
|
||||
type "httpd"
|
||||
name "Mpd_Lame"
|
||||
encoder "lame"
|
||||
port "6504"
|
||||
bitrate "128"
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,2 @@
|
|||
03 - 1985.mp3
|
||||
03 - 1985.mp3
|
||||
Loading…
Reference in New Issue