diff --git a/go.mod b/go.mod index 64ccea9..469076d 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/gcottom/oggmeta v0.0.8 github.com/goccy/go-json v0.10.5 github.com/gofiber/fiber/v3 v3.0.0-beta.4 - github.com/valyala/fasthttp v1.60.0 + github.com/valyala/fasthttp v1.61.0 ) require ( diff --git a/go.sum b/go.sum index 70875eb..f35bb81 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po= github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.60.0 h1:kBRYS0lOhVJ6V+bYN8PqAHELKHtXqwq9zNMLKx1MBsw= -github.com/valyala/fasthttp v1.60.0/go.mod h1:iY4kDgV3Gc6EqhRZ8icqcmlG6bqhcDXfuHgTO4FXCvc= +github.com/valyala/fasthttp v1.61.0 h1:VV08V0AfoRaFurP1EWKvQQdPTZHiUzaVoulX1aBDgzU= +github.com/valyala/fasthttp v1.61.0/go.mod h1:wRIV/4cMwUPWnRcDno9hGnYZGh78QzODFfo1LTUhBog= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= diff --git a/lib/restream/init.go b/lib/restream/init.go index 1a6373b..1064cc2 100644 --- a/lib/restream/init.go +++ b/lib/restream/init.go @@ -16,6 +16,7 @@ import ( "github.com/gcottom/mp4meta" "github.com/gcottom/oggmeta" "github.com/gofiber/fiber/v3" + "github.com/valyala/fasthttp" ) type collector struct { @@ -67,7 +68,6 @@ func Load(r *fiber.App) { c.Request().Header.SetContentType(tr.Format.MimeType) c.Set("Cache-Control", cfg.RestreamCacheControl) - r := acquireReader() if isDownload { if t.Artwork != "" { t.Artwork = strings.Replace(t.Artwork, "t500x500", "original", 1) @@ -75,6 +75,7 @@ func Load(r *fiber.App) { switch audio { case cfg.AudioMP3: + r := acquireReader() err := r.Setup(u, false, nil) if err != nil { return err @@ -106,21 +107,47 @@ func Load(r *fiber.App) { tag.WriteTo(&col) r.leftover = col.data + c.Response().Header.SetContentType("audio/mpeg") return c.SendStream(r) - case cfg.AudioOpus: - err := r.Setup(u, false, nil) + case cfg.AudioOpus: // might try to fuck around with metadata injection. Dynamically injecting metadata for opus wasn't really good idea as it breaks some things :P + req := fasthttp.AcquireRequest() + resp := fasthttp.AcquireResponse() + + req.SetRequestURI(u) + req.Header.SetUserAgent(cfg.UserAgent) + req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") + + err := sc.DoWithRetry(misc.HlsClient, req, resp) if err != nil { return err } - r.req.SetRequestURIBytes(r.parts[0]) - err = sc.DoWithRetry(r.client, r.req, r.resp) + data, err := resp.BodyUncompressed() if err != nil { - return err + data = resp.Body() } - r.index++ - tag, err := oggmeta.ReadOGG(bytes.NewReader(r.resp.Body())) + res := make([]byte, 0, 1024*1024*1) + for _, s := range bytes.Split(data, []byte{'\n'}) { + if len(s) == 0 || s[0] == '#' { + continue + } + + req.SetRequestURIBytes(s) + err := sc.DoWithRetry(misc.HlsClient, req, resp) + if err != nil { + return err + } + + data, err = resp.BodyUncompressed() + if err != nil { + data = resp.Body() + } + + res = append(res, data...) + } + + tag, err := oggmeta.ReadOGG(bytes.NewReader(res)) if err != nil { return err } @@ -133,30 +160,27 @@ func Load(r *fiber.App) { tag.SetTitle(t.Title) if t.Artwork != "" { - r.req.SetRequestURI(t.Artwork) - r.req.Header.Del("Accept-Encoding") + req.SetRequestURI(t.Artwork) + req.Header.Del("Accept-Encoding") - err := sc.DoWithRetry(misc.ImageClient, r.req, r.resp) + err := sc.DoWithRetry(misc.ImageClient, req, resp) if err != nil { return err } - parsed, _, err := image.Decode(r.resp.BodyStream()) - r.resp.CloseBodyStream() + parsed, _, err := image.Decode(resp.BodyStream()) + resp.CloseBodyStream() if err != nil { return err } tag.SetCoverArt(&parsed) - r.req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") } - var col collector - tag.Save(&col) - r.leftover = col.data - - return c.SendStream(r) + c.Response().Header.SetContentType(`audio/ogg; codecs="opus"`) + return tag.Save(c.Response().BodyWriter()) case cfg.AudioAAC: + r := acquireReader() err := r.Setup(u, true, &t.Duration) if err != nil { return err @@ -202,12 +226,15 @@ func Load(r *fiber.App) { var col collector tag.Save(&col) + fixDuration(col.data, &t.Duration) r.leftover = col.data + c.Response().Header.SetContentType("audio/mp4") return c.SendStream(r) } } + r := acquireReader() if audio == cfg.AudioAAC { err = r.Setup(u, true, &t.Duration) } else {