small restructuring in preparation for something
This commit is contained in:
parent
8adb7a8b41
commit
491aa6028c
9 changed files with 148 additions and 125 deletions
|
@ -1,6 +1,16 @@
|
|||
Dockerfile
|
||||
*.yaml
|
||||
build
|
||||
.github
|
||||
.gitignore
|
||||
soundcloak.example.json
|
||||
|
||||
LICENSE
|
||||
README.md
|
||||
*.yaml
|
||||
docs
|
||||
|
||||
*.fiber.gz
|
||||
node_modules
|
||||
*_templ.go
|
||||
regexp2_codegen.go
|
||||
regexp2_codegen.go
|
||||
main
|
101
lib/cfg/init.go
101
lib/cfg/init.go
|
@ -2,16 +2,13 @@ package cfg
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// You can now use a soundcloak.json file to configure!
|
||||
|
@ -19,64 +16,6 @@ import (
|
|||
// it's not needed to specify every key in your config, it will use the default values for keys you haven't specified
|
||||
// also, when specifying time, specify it in seconds (instead of nanoseconds as time.Duration)
|
||||
|
||||
const (
|
||||
// Downloads the HLS stream on the backend, and restreams it to frontend as a file. Requires no JS, but less stable client-side
|
||||
RestreamPlayer string = "restream"
|
||||
// Downloads the HLS stream on the frontend (proxying can be enabled). Requires JS, more stable client-side
|
||||
HLSPlayer string = "hls"
|
||||
// Disables the song player
|
||||
NonePlayer string = "none"
|
||||
)
|
||||
|
||||
const (
|
||||
// Just plays every song in order, one after another
|
||||
AutoplayNormal string = "normal"
|
||||
// Randomly selects a song to play from the playlist
|
||||
AutoplayRandom string = "random"
|
||||
)
|
||||
|
||||
const (
|
||||
// choose best for quality/size (AudioAAC over AudioOpus over AudioMP3)
|
||||
AudioBest string = "best"
|
||||
|
||||
// 160kbps m4a AAC audio, rarely available (fallback to AudioMP3 if unavailable)
|
||||
AudioAAC string = "aac"
|
||||
|
||||
// 72kbps ogg opus audio, usually available 99% of the time (fallback to AudioMP3 if unavailable)
|
||||
AudioOpus string = "opus"
|
||||
|
||||
// 128kbps mp3 audio, always available, good for compatibility
|
||||
AudioMP3 string = "mpeg"
|
||||
)
|
||||
|
||||
type Preferences struct {
|
||||
Player *string
|
||||
ProxyStreams *bool
|
||||
|
||||
// fully loads the track on page load
|
||||
// this option is here since the stream expires after some time (5 minutes? correct me if im wrong)
|
||||
// if the stream isn't fully loaded before it expires - you'll need to reload the page
|
||||
FullyPreloadTrack *bool
|
||||
|
||||
ProxyImages *bool
|
||||
|
||||
// Highlight @username, https://example.com and email@example.com in text as clickable links
|
||||
ParseDescriptions *bool
|
||||
|
||||
// Automatically play next track in playlists
|
||||
AutoplayNextTrack *bool
|
||||
|
||||
DefaultAutoplayMode *string // "normal" or "random"
|
||||
|
||||
// Check line 38 for constants
|
||||
// Probably best to keep all at "mpeg" by default for compatibility
|
||||
HLSAudio *string // Please don't use "opus" or "best". hls.js doesn't work with ogg/opus
|
||||
RestreamAudio *string // You can actually use anything here
|
||||
DownloadAudio *string // "aac" may not play well with some players
|
||||
|
||||
ShowAudio *bool // display audio (aac, opus, mpeg etc) under track player
|
||||
}
|
||||
|
||||
// // config // //
|
||||
|
||||
// Retrieve links users set in their profile (social media, website, etc)
|
||||
|
@ -565,44 +504,4 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
// seems soundcloud has 4 of these (i1, i2, i3, i4)
|
||||
// they point to the same ip from my observations, and they all serve the same files
|
||||
const ImageCDN = "i1.sndcdn.com"
|
||||
const HLSCDN = "cf-hls-media.sndcdn.com"
|
||||
const HLSAACCDN = "playback.media-streaming.soundcloud.cloud"
|
||||
|
||||
var True = true
|
||||
var False = false
|
||||
|
||||
var prpool = sync.Pool{
|
||||
New: func() any {
|
||||
return &ProxyReader{}
|
||||
},
|
||||
}
|
||||
|
||||
func AcquireProxyReader() *ProxyReader {
|
||||
return prpool.Get().(*ProxyReader)
|
||||
}
|
||||
|
||||
type ProxyReader struct {
|
||||
Reader io.Reader
|
||||
Resp *fasthttp.Response
|
||||
}
|
||||
|
||||
func (pr *ProxyReader) Read(p []byte) (int, error) {
|
||||
return pr.Reader.Read(p)
|
||||
}
|
||||
|
||||
func (pr *ProxyReader) Close() error {
|
||||
defer fasthttp.ReleaseResponse(pr.Resp)
|
||||
defer prpool.Put(pr)
|
||||
return pr.Resp.CloseBodyStream()
|
||||
}
|
||||
|
||||
const Debug = false
|
||||
|
||||
func Log(what ...any) {
|
||||
if Debug {
|
||||
fmt.Println(what...)
|
||||
}
|
||||
}
|
||||
|
|
68
lib/cfg/misc.go
Normal file
68
lib/cfg/misc.go
Normal file
|
@ -0,0 +1,68 @@
|
|||
package cfg
|
||||
|
||||
// seems soundcloud has 4 of these (i1, i2, i3, i4)
|
||||
// they point to the same ip from my observations, and they all serve the same files
|
||||
const ImageCDN = "i1.sndcdn.com"
|
||||
const HLSCDN = "cf-hls-media.sndcdn.com"
|
||||
const HLSAACCDN = "playback.media-streaming.soundcloud.cloud"
|
||||
|
||||
var True = true
|
||||
var False = false
|
||||
|
||||
const (
|
||||
// Downloads the HLS stream on the backend, and restreams it to frontend as a file. Requires no JS, but less stable client-side
|
||||
RestreamPlayer string = "restream"
|
||||
// Downloads the HLS stream on the frontend (proxying can be enabled). Requires JS, more stable client-side
|
||||
HLSPlayer string = "hls"
|
||||
// Disables the song player
|
||||
NonePlayer string = "none"
|
||||
)
|
||||
|
||||
const (
|
||||
// Just plays every song in order, one after another
|
||||
AutoplayNormal string = "normal"
|
||||
// Randomly selects a song to play from the playlist
|
||||
AutoplayRandom string = "random"
|
||||
)
|
||||
|
||||
const (
|
||||
// choose best for quality/size (AudioAAC over AudioOpus over AudioMP3)
|
||||
AudioBest string = "best"
|
||||
|
||||
// 160kbps m4a AAC audio, rarely available (fallback to AudioMP3 if unavailable)
|
||||
AudioAAC string = "aac"
|
||||
|
||||
// 72kbps ogg opus audio, usually available 99% of the time (fallback to AudioMP3 if unavailable)
|
||||
AudioOpus string = "opus"
|
||||
|
||||
// 128kbps mp3 audio, always available, good for compatibility
|
||||
AudioMP3 string = "mpeg"
|
||||
)
|
||||
|
||||
type Preferences struct {
|
||||
Player *string
|
||||
ProxyStreams *bool
|
||||
|
||||
// fully loads the track on page load
|
||||
// this option is here since the stream expires after some time (5 minutes? correct me if im wrong)
|
||||
// if the stream isn't fully loaded before it expires - you'll need to reload the page
|
||||
FullyPreloadTrack *bool
|
||||
|
||||
ProxyImages *bool
|
||||
|
||||
// Highlight @username, https://example.com and email@example.com in text as clickable links
|
||||
ParseDescriptions *bool
|
||||
|
||||
// Automatically play next track in playlists
|
||||
AutoplayNextTrack *bool
|
||||
|
||||
DefaultAutoplayMode *string // "normal" or "random"
|
||||
|
||||
// Check line 38 for constants
|
||||
// Probably best to keep all at "mpeg" by default for compatibility
|
||||
HLSAudio *string // Please don't use "opus" or "best". hls.js doesn't work with ogg/opus
|
||||
RestreamAudio *string // You can actually use anything here
|
||||
DownloadAudio *string // "aac" may not play well with some players
|
||||
|
||||
ShowAudio *bool // display audio (aac, opus, mpeg etc) under track player
|
||||
}
|
41
lib/misc/init.go
Normal file
41
lib/misc/init.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package misc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/maid-zone/soundcloak/lib/cfg"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
var prpool = sync.Pool{
|
||||
New: func() any {
|
||||
return &ProxyReader{}
|
||||
},
|
||||
}
|
||||
|
||||
func AcquireProxyReader() *ProxyReader {
|
||||
return prpool.Get().(*ProxyReader)
|
||||
}
|
||||
|
||||
type ProxyReader struct {
|
||||
Reader io.Reader
|
||||
Resp *fasthttp.Response
|
||||
}
|
||||
|
||||
func (pr *ProxyReader) Read(p []byte) (int, error) {
|
||||
return pr.Reader.Read(p)
|
||||
}
|
||||
|
||||
func (pr *ProxyReader) Close() error {
|
||||
defer fasthttp.ReleaseResponse(pr.Resp)
|
||||
defer prpool.Put(pr)
|
||||
return pr.Resp.CloseBodyStream()
|
||||
}
|
||||
|
||||
func Log(what ...any) {
|
||||
if cfg.Debug {
|
||||
fmt.Println(what...)
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/maid-zone/soundcloak/lib/cfg"
|
||||
"github.com/maid-zone/soundcloak/lib/misc"
|
||||
"github.com/maid-zone/soundcloak/lib/sc"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
@ -59,7 +60,7 @@ func Load(r fiber.Router) {
|
|||
c.Set("Content-Type", "image/jpeg")
|
||||
c.Set("Cache-Control", cfg.ImageCacheControl)
|
||||
//return c.Send(resp.Body())
|
||||
pr := cfg.AcquireProxyReader()
|
||||
pr := misc.AcquireProxyReader()
|
||||
pr.Reader = resp.BodyStream()
|
||||
pr.Resp = resp
|
||||
return c.SendStream(pr)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/maid-zone/soundcloak/lib/cfg"
|
||||
"github.com/maid-zone/soundcloak/lib/misc"
|
||||
"github.com/maid-zone/soundcloak/lib/sc"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
@ -65,7 +66,7 @@ func Load(r fiber.Router) {
|
|||
return err
|
||||
}
|
||||
//return c.Send(resp.Body())
|
||||
pr := cfg.AcquireProxyReader()
|
||||
pr := misc.AcquireProxyReader()
|
||||
pr.Reader = resp.BodyStream()
|
||||
pr.Resp = resp
|
||||
return c.SendStream(pr)
|
||||
|
@ -103,7 +104,7 @@ func Load(r fiber.Router) {
|
|||
return err
|
||||
}
|
||||
|
||||
pr := cfg.AcquireProxyReader()
|
||||
pr := misc.AcquireProxyReader()
|
||||
pr.Reader = resp.BodyStream()
|
||||
pr.Resp = resp
|
||||
return c.SendStream(pr)
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/gcottom/oggmeta"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/maid-zone/soundcloak/lib/cfg"
|
||||
"github.com/maid-zone/soundcloak/lib/misc"
|
||||
"github.com/maid-zone/soundcloak/lib/preferences"
|
||||
"github.com/maid-zone/soundcloak/lib/sc"
|
||||
"github.com/valyala/fasthttp"
|
||||
|
@ -73,10 +74,10 @@ func (r *reader) Setup(url string, aac bool) error {
|
|||
}
|
||||
|
||||
if r.parts == nil {
|
||||
cfg.Log("make() r.parts")
|
||||
misc.Log("make() r.parts")
|
||||
r.parts = make([][]byte, 0, defaultPartsCapacity)
|
||||
} else {
|
||||
cfg.Log(cap(r.parts), len(r.parts))
|
||||
misc.Log(cap(r.parts), len(r.parts))
|
||||
}
|
||||
if aac {
|
||||
// clone needed to mitigate memory skill issues here
|
||||
|
@ -108,7 +109,7 @@ func (r *reader) Setup(url string, aac bool) error {
|
|||
}
|
||||
|
||||
func (r *reader) Close() error {
|
||||
cfg.Log("closed :D")
|
||||
misc.Log("closed :D")
|
||||
if r.req != nil {
|
||||
fasthttp.ReleaseRequest(r.req)
|
||||
r.req = nil
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/dlclark/regexp2"
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/maid-zone/soundcloak/lib/cfg"
|
||||
"github.com/maid-zone/soundcloak/lib/misc"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
|
@ -61,9 +62,9 @@ type cached[T any] struct {
|
|||
Expires time.Time
|
||||
}
|
||||
|
||||
// don't be spooked by cfg.Log, it will be removed during compilation if cfg.Debug == false
|
||||
// don't be spooked by misc.Log, it will be removed during compilation if cfg.Debug == false
|
||||
func processFile(wg *sync.WaitGroup, ch chan string, uri string, isDone *bool) {
|
||||
cfg.Log(uri)
|
||||
misc.Log(uri)
|
||||
req := fasthttp.AcquireRequest()
|
||||
defer fasthttp.ReleaseRequest(req)
|
||||
|
||||
|
@ -77,18 +78,18 @@ func processFile(wg *sync.WaitGroup, ch chan string, uri string, isDone *bool) {
|
|||
defer wg.Done()
|
||||
|
||||
if *isDone {
|
||||
cfg.Log("early 1")
|
||||
misc.Log("early 1")
|
||||
return
|
||||
}
|
||||
|
||||
err := DoWithRetryAll(genericClient, req, resp)
|
||||
if err != nil {
|
||||
cfg.Log(err)
|
||||
misc.Log(err)
|
||||
return
|
||||
}
|
||||
|
||||
if *isDone {
|
||||
cfg.Log("early 2")
|
||||
misc.Log("early 2")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -98,7 +99,7 @@ func processFile(wg *sync.WaitGroup, ch chan string, uri string, isDone *bool) {
|
|||
}
|
||||
|
||||
if *isDone {
|
||||
cfg.Log("early 3")
|
||||
misc.Log("early 3")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -107,17 +108,17 @@ func processFile(wg *sync.WaitGroup, ch chan string, uri string, isDone *bool) {
|
|||
g := m2.GroupByNumber(1)
|
||||
if g != nil {
|
||||
if *isDone {
|
||||
cfg.Log("early 4")
|
||||
misc.Log("early 4")
|
||||
return
|
||||
}
|
||||
|
||||
ch <- g.String()
|
||||
cfg.Log("found in", uri)
|
||||
misc.Log("found in", uri)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
cfg.Log("not found in", uri)
|
||||
misc.Log("not found in", uri)
|
||||
}
|
||||
|
||||
// Experimental method, which asserts that the clientId is inside the file that starts with "0-"
|
||||
|
@ -126,7 +127,7 @@ const experimental_GetClientID = true
|
|||
// inspired by github.com/imputnet/cobalt (mostly stolen lol)
|
||||
func GetClientID() (string, error) {
|
||||
if ClientIDCache.NextCheck.After(time.Now()) {
|
||||
cfg.Log("clientidcache hit @ 1")
|
||||
misc.Log("clientidcache hit @ 1")
|
||||
return ClientIDCache.ClientID, nil
|
||||
}
|
||||
|
||||
|
@ -162,7 +163,7 @@ func GetClientID() (string, error) {
|
|||
|
||||
ver := g.String()
|
||||
if ver == ClientIDCache.Version {
|
||||
cfg.Log("clientidcache hit @ ver")
|
||||
misc.Log("clientidcache hit @ ver")
|
||||
ClientIDCache.NextCheck = time.Now().Add(cfg.ClientIDTTL)
|
||||
return ClientIDCache.ClientID, nil
|
||||
}
|
||||
|
@ -190,7 +191,7 @@ func GetClientID() (string, error) {
|
|||
ClientIDCache.ClientID = g.String()
|
||||
ClientIDCache.Version = ver
|
||||
ClientIDCache.NextCheck = time.Now().Add(cfg.ClientIDTTL)
|
||||
cfg.Log(ClientIDCache)
|
||||
misc.Log(ClientIDCache)
|
||||
return ClientIDCache.ClientID, nil
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +215,7 @@ func GetClientID() (string, error) {
|
|||
go func() {
|
||||
defer func() {
|
||||
err := recover()
|
||||
cfg.Log("-- GetClientID recovered:", err)
|
||||
misc.Log("-- GetClientID recovered:", err)
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
@ -234,7 +235,7 @@ func GetClientID() (string, error) {
|
|||
ClientIDCache.ClientID = res
|
||||
ClientIDCache.Version = ver
|
||||
ClientIDCache.NextCheck = time.Now().Add(cfg.ClientIDTTL)
|
||||
cfg.Log(ClientIDCache)
|
||||
misc.Log(ClientIDCache)
|
||||
}
|
||||
|
||||
return res, err
|
||||
|
@ -273,7 +274,7 @@ func DoWithRetry(httpc *fasthttp.HostClient, req *fasthttp.Request, resp *fastht
|
|||
return
|
||||
}
|
||||
|
||||
cfg.Log("we failed haha", err)
|
||||
misc.Log("we failed haha", err)
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/maid-zone/soundcloak/lib/cfg"
|
||||
"github.com/maid-zone/soundcloak/lib/misc"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
|
@ -324,7 +325,7 @@ func (tr Transcoding) GetStream(cid string, prefs cfg.Preferences, authorization
|
|||
return "", err
|
||||
}
|
||||
|
||||
cfg.Log(s)
|
||||
misc.Log(s)
|
||||
|
||||
if s.URL == "" {
|
||||
return "", ErrNoURL
|
||||
|
|
Loading…
Reference in a new issue