once again

This commit is contained in:
Laptop
2024-09-19 18:18:04 +03:00
parent d438398fff
commit 014eb3467d
5 changed files with 78 additions and 8 deletions

View File

@@ -4,6 +4,13 @@ wip alternative frontend for soundcloud
# [official public instance](https://sc.maid.zone) # [official public instance](https://sc.maid.zone)
there is no image and audio proxy for now so beware there is no image and audio proxy for now so beware
# Already implemented
- Searching for songs, users, playlists
- Basic user overview (songs, metadata)
- Basic song overview (author, metadata) & streaming (requires javascript if no [browser support for HLS](https://caniuse.com/http-live-streaming))
- Basic playlist/set/album overview (songs list, author, metadata)
- Resolving shortened links (`https://on.soundcloud.com/boiKDP46fayYDoVK9` -> `https://sc.maid.zone/on/boiKDP46fayYDoVK9`)
# Setting it up # Setting it up
## Prerequisites: ## Prerequisites:
1. [node.js + npm](https://nodejs.org) (any recent enough version should do, it's just used for getting hls.js builds) 1. [node.js + npm](https://nodejs.org) (any recent enough version should do, it's just used for getting hls.js builds)
@@ -56,3 +63,14 @@ templ generate && go build main.go
``` ```
This will run soundcloak on localhost, port 4664. (by default) This will run soundcloak on localhost, port 4664. (by default)
# Built with
## Backend
- [Go programming language](https://github.com/golang/go)
- [Fiber (v2)](https://github.com/gofiber/fiber/tree/v2)
- [templ](https://github.com/a-h/templ)
- [fasthttp](https://github.com/valyala/fasthttp)
## Frontend
- HTML, CSS and JavaScript
- [hls.js](https://github.com/video-dev/hls.js)

View File

@@ -25,6 +25,9 @@ const UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
// time-to-live for dns cache // time-to-live for dns cache
const DNSCacheTTL = 10 * time.Minute const DNSCacheTTL = 10 * time.Minute
// // // some webserver configuration, put here to make it easier to configure what you need // // //
// more info can be found here: https://docs.gofiber.io/api/fiber#config
// run soundcloak on this address (localhost:4664 by default) // run soundcloak on this address (localhost:4664 by default)
const Addr = ":4664" const Addr = ":4664"
@@ -32,4 +35,12 @@ const Addr = ":4664"
// each one will be a separate process, so they will have separate cache // each one will be a separate process, so they will have separate cache
const Prefork = false const Prefork = false
// use X-Forwarded-* headers ONLY when ip is in TrustedProxies list
// when disabled, the X-Forwarded-* headers will be blindly used
const TrustedProxyCheck = false
// ip or ip range of trusted proxies (check above)
var TrustedProxies = []string{}
// what JSON library should be used
var JSON = jsoniter.ConfigFastest var JSON = jsoniter.ConfigFastest

40
main.go
View File

@@ -11,6 +11,7 @@ import (
"github.com/gofiber/fiber/v2/middleware/compress" "github.com/gofiber/fiber/v2/middleware/compress"
"github.com/gofiber/fiber/v2/middleware/earlydata" "github.com/gofiber/fiber/v2/middleware/earlydata"
"github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/fiber/v2/middleware/recover"
"github.com/valyala/fasthttp"
"github.com/maid-zone/soundcloak/lib/cfg" "github.com/maid-zone/soundcloak/lib/cfg"
"github.com/maid-zone/soundcloak/lib/sc" "github.com/maid-zone/soundcloak/lib/sc"
@@ -22,6 +23,9 @@ func main() {
Prefork: cfg.Prefork, Prefork: cfg.Prefork,
JSONEncoder: cfg.JSON.Marshal, JSONEncoder: cfg.JSON.Marshal,
JSONDecoder: cfg.JSON.Unmarshal, JSONDecoder: cfg.JSON.Unmarshal,
EnableTrustedProxyCheck: cfg.TrustedProxyCheck,
TrustedProxies: cfg.TrustedProxies,
}) })
app.Use(compress.New()) app.Use(compress.New())
app.Use(recover.New()) app.Use(recover.New())
@@ -68,6 +72,42 @@ func main() {
return c.SendStatus(404) return c.SendStatus(404)
}) })
app.Get("/on/:id", func(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" {
return fiber.ErrNotFound
}
req := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(req)
req.Header.SetMethod("HEAD")
req.SetRequestURI("https://on.soundcloud.com/" + id)
req.Header.Set("User-Agent", cfg.UserAgent)
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(resp)
err := fasthttp.Do(req, resp)
if err != nil {
return err
}
loc := resp.Header.Peek("location")
if len(loc) == 0 {
return fiber.ErrNotFound
}
//fmt.Println(c.Hostname(), c.Protocol(), c.IPs())
u, err := url.Parse(string(loc))
if err != nil {
return err
}
return c.Redirect(u.Path)
})
app.Get("/:user/:track", func(c *fiber.Ctx) error { app.Get("/:user/:track", func(c *fiber.Ctx) error {
track, err := sc.GetTrack(c.Params("user") + "/" + c.Params("track")) track, err := sc.GetTrack(c.Params("user") + "/" + c.Params("track"))
if err != nil { if err != nil {

View File

@@ -8,7 +8,7 @@ templ Base(title string, content templ.Component, head templ.Component) {
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/> <link rel="stylesheet" href="/global.css"/>
if title != "" { if title != "" {
<title>{ title } soundcloak</title> <title>{ title } ~ soundcloak</title>
} else { } else {
<title>soundcloak</title> <title>soundcloak</title>
} }

View File

@@ -20,7 +20,11 @@ templ Track(t sc.Track, stream string) {
<img src={t.Artwork} class={ViewTransition("t" + t.ID)}> <img src={t.Artwork} class={ViewTransition("t" + t.ID)}>
} }
<h1>{ t.Title }</h1> <h1>{ t.Title }</h1>
<audio id="track" data-stream={ stream } controls></audio> <audio id="track" src={ stream } controls></audio>
<noscript>
<br>
JavaScript is disabled! Audio playback may not work without it enabled.
</noscript>
if t.Genre != "" { if t.Genre != "" {
<p class="tag">{ t.Genre }</p> <p class="tag">{ t.Genre }</p>
} else { } else {
@@ -51,15 +55,12 @@ templ Track(t sc.Track, stream string) {
} }
<script> <script>
var audio = document.getElementById('track'); var audio = document.getElementById('track');
var audioSrc = audio.getAttribute('data-stream');
if (Hls.isSupported()) { if (Hls.isSupported()) {
var hls = new Hls(); var hls = new Hls();
hls.loadSource(audioSrc); hls.loadSource(audio.src);
hls.attachMedia(audio); hls.attachMedia(audio);
} else if (audio.canPlayType('application/vnd.apple.mpegurl')) { } else if (!audio.canPlayType('application/vnd.apple.mpegurl')) {
audio.src = audioSrc; alert('HLS is not supported! Audio playback will not work.');
} else {
alert('hls not supported');
} }
</script> </script>
} }