diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..1c8a70e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,46 @@ +name: Docker Image CI + +on: + push: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: BuildX Install + uses: docker/setup-buildx-action@v3 + id: buildx + with: + install: true + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=sha,format=long,prefix= + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..89cbb3d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM --platform=$BUILDPLATFORM golang:1.22 as builder +ARG TARGETOS +ARG TARGETARCH + +WORKDIR "/app" +COPY index.html index.html +COPY server.go server.go +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ + go build -o server server.go + +FROM jauderho/yt-dlp:latest +WORKDIR "/app" +COPY --from=builder /app/server . + +ENTRYPOINT [] +CMD "/app/server" diff --git a/index.html b/index.html new file mode 100644 index 0000000..866186b --- /dev/null +++ b/index.html @@ -0,0 +1,27 @@ + + + + + +
+ + +
+ + diff --git a/server.go b/server.go new file mode 100644 index 0000000..e8a2a57 --- /dev/null +++ b/server.go @@ -0,0 +1,69 @@ +package main + +import ( + _ "embed" + "fmt" + "io" + "net/http" + "os" + "os/exec" + "path/filepath" + "strings" +) + +//go:embed index.html +var index []byte + +func main() { + cliCmd := append( + strings.Split(os.Getenv("EXEC"), " "), + "-x", + "--audio-format", + "mp3", + "--audio-quality", + "0") + + bind := os.Getenv("BIND") + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodGet { + w.Write(index) + return + } + + cli := append(cliCmd, r.FormValue("link")) + cmd := exec.Command(cli[0], cli[1:]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + _ = cmd.Run() + + var file string + _ = filepath.Walk(".", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + if matched, err := filepath.Match("*.mp3", filepath.Base(path)); err != nil { + return err + } else if matched { + file = path + } + return nil + }) + + f, _ := os.Open(file) + defer func() { + f.Close() + os.Remove(file) + }() + + w.Header().Set("Content-Type", "audio/mpeg") + w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename="%s"`, filepath.Base(file))) + w.WriteHeader(http.StatusOK) + io.Copy(w, f) + }) + + http.ListenAndServe(bind, nil) +}