mirror of
https://git.maid.zone/stuff/soundcloak.git
synced 2025-12-10 05:39:38 +05:00
fix skill issues w/ restream
This commit is contained in:
@@ -70,7 +70,7 @@ func Load(r *fiber.App) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Request().Header.SetContentType(tr.Format.MimeType)
|
c.Response().Header.SetContentType(tr.Format.MimeType)
|
||||||
c.Set("Cache-Control", cfg.RestreamCacheControl)
|
c.Set("Cache-Control", cfg.RestreamCacheControl)
|
||||||
|
|
||||||
if isDownload {
|
if isDownload {
|
||||||
@@ -99,23 +99,23 @@ func Load(r *fiber.App) {
|
|||||||
r.req.SetRequestURI(t.Artwork)
|
r.req.SetRequestURI(t.Artwork)
|
||||||
|
|
||||||
err := sc.DoWithRetry(misc.ImageClient, r.req, r.resp)
|
err := sc.DoWithRetry(misc.ImageClient, r.req, r.resp)
|
||||||
if err != nil {
|
if err == nil && r.resp.StatusCode() == 200 {
|
||||||
return err
|
tag.AddAttachedPicture(id3v2.PictureFrame{MimeType: cfg.B2s(r.req.Header.ContentType()), Picture: r.req.Body(), PictureType: id3v2.PTFrontCover, Encoding: id3v2.EncodingUTF8})
|
||||||
}
|
}
|
||||||
|
|
||||||
tag.AddAttachedPicture(id3v2.PictureFrame{MimeType: cfg.B2s(r.req.Header.ContentType()), Picture: r.req.Body(), PictureType: id3v2.PTFrontCover, Encoding: id3v2.EncodingUTF8})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var col collector
|
var col collector
|
||||||
tag.WriteTo(&col)
|
tag.WriteTo(&col)
|
||||||
r.leftover = col.data
|
r.leftover = col.data
|
||||||
|
|
||||||
c.Response().Header.SetContentType("audio/mpeg")
|
|
||||||
return c.SendStream(r)
|
return c.SendStream(r)
|
||||||
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
|
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()
|
req := fasthttp.AcquireRequest()
|
||||||
resp := fasthttp.AcquireResponse()
|
resp := fasthttp.AcquireResponse()
|
||||||
|
|
||||||
|
defer fasthttp.ReleaseRequest(req)
|
||||||
|
defer fasthttp.ReleaseResponse(resp)
|
||||||
|
|
||||||
req.SetRequestURI(u)
|
req.SetRequestURI(u)
|
||||||
req.Header.SetUserAgent(cfg.UserAgent)
|
req.Header.SetUserAgent(cfg.UserAgent)
|
||||||
|
|
||||||
@@ -124,23 +124,24 @@ func Load(r *fiber.App) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
data := resp.Body()
|
parts := make([][]byte, 0, defaultPartsCapacity)
|
||||||
|
for _, s := range bytes.Split(resp.Body(), newline) {
|
||||||
res := make([]byte, 0, 1024*1024*1)
|
|
||||||
for _, s := range bytes.Split(data, []byte{'\n'}) {
|
|
||||||
if len(s) == 0 || s[0] == '#' {
|
if len(s) == 0 || s[0] == '#' {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parts = append(parts, clone(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
res := make([]byte, 0, 1024*1024*1)
|
||||||
|
for _, s := range parts {
|
||||||
req.SetRequestURIBytes(s)
|
req.SetRequestURIBytes(s)
|
||||||
err := sc.DoWithRetry(misc.HlsClient, req, resp)
|
err := sc.DoWithRetry(misc.HlsClient, req, resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
data = resp.Body()
|
res = append(res, resp.Body()...)
|
||||||
|
|
||||||
res = append(res, data...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tag, err := oggmeta.ReadOGG(bytes.NewReader(res))
|
tag, err := oggmeta.ReadOGG(bytes.NewReader(res))
|
||||||
@@ -159,24 +160,18 @@ func Load(r *fiber.App) {
|
|||||||
req.SetRequestURI(t.Artwork)
|
req.SetRequestURI(t.Artwork)
|
||||||
|
|
||||||
err := sc.DoWithRetry(misc.ImageClient, req, resp)
|
err := sc.DoWithRetry(misc.ImageClient, req, resp)
|
||||||
if err != nil {
|
if err == nil && resp.StatusCode() == 200 {
|
||||||
return err
|
parsed, _, err := image.Decode(resp.BodyStream())
|
||||||
|
if err == nil {
|
||||||
|
tag.SetCoverArt(&parsed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed, _, err := image.Decode(resp.BodyStream())
|
|
||||||
resp.CloseBodyStream()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
tag.SetCoverArt(&parsed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Response().Header.SetContentType(`audio/ogg; codecs="opus"`)
|
|
||||||
return tag.Save(c.Response().BodyWriter())
|
return tag.Save(c.Response().BodyWriter())
|
||||||
case cfg.AudioAAC:
|
case cfg.AudioAAC:
|
||||||
r := acquireReader()
|
r := acquireReader()
|
||||||
err := r.Setup(u, true, &t.Duration)
|
err := r.Setup(u, true, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -204,17 +199,13 @@ func Load(r *fiber.App) {
|
|||||||
r.req.SetRequestURI(t.Artwork)
|
r.req.SetRequestURI(t.Artwork)
|
||||||
|
|
||||||
err := sc.DoWithRetry(misc.ImageClient, r.req, r.resp)
|
err := sc.DoWithRetry(misc.ImageClient, r.req, r.resp)
|
||||||
if err != nil {
|
if err == nil && r.resp.StatusCode() == 200 {
|
||||||
return err
|
parsed, _, err := image.Decode(r.resp.BodyStream())
|
||||||
|
r.resp.CloseBodyStream()
|
||||||
|
if err == nil {
|
||||||
|
tag.SetCoverArt(&parsed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed, _, err := image.Decode(r.resp.BodyStream())
|
|
||||||
r.resp.CloseBodyStream()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
tag.SetCoverArt(&parsed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var col collector
|
var col collector
|
||||||
@@ -222,7 +213,6 @@ func Load(r *fiber.App) {
|
|||||||
fixDuration(col.data, &t.Duration)
|
fixDuration(col.data, &t.Duration)
|
||||||
r.leftover = col.data
|
r.leftover = col.data
|
||||||
|
|
||||||
c.Response().Header.SetContentType("audio/mp4")
|
|
||||||
return c.SendStream(r)
|
return c.SendStream(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ func clone(buf []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var mvhd = []byte("mvhd")
|
var mvhd = []byte("mvhd")
|
||||||
|
var newline = []byte{'\n'}
|
||||||
|
|
||||||
func fixDuration(data []byte, duration *uint32) {
|
func fixDuration(data []byte, duration *uint32) {
|
||||||
i := bytes.Index(data, mvhd)
|
i := bytes.Index(data, mvhd)
|
||||||
@@ -85,9 +86,9 @@ func (r *reader) Setup(url string, aac bool, duration *uint32) error {
|
|||||||
} else {
|
} else {
|
||||||
misc.Log(cap(r.parts), len(r.parts))
|
misc.Log(cap(r.parts), len(r.parts))
|
||||||
}
|
}
|
||||||
|
// clone needed to mitigate memory skill issues smh
|
||||||
if aac {
|
if aac {
|
||||||
// clone needed to mitigate memory skill issues here
|
for _, s := range bytes.Split(r.resp.Body(), newline) {
|
||||||
for _, s := range bytes.Split(r.resp.Body(), []byte{'\n'}) {
|
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -102,12 +103,12 @@ func (r *reader) Setup(url string, aac bool, duration *uint32) error {
|
|||||||
r.parts = append(r.parts, clone(s))
|
r.parts = append(r.parts, clone(s))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, s := range bytes.Split(r.resp.Body(), []byte{'\n'}) {
|
for _, s := range bytes.Split(r.resp.Body(), newline) {
|
||||||
if len(s) == 0 || s[0] == '#' {
|
if len(s) == 0 || s[0] == '#' {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
r.parts = append(r.parts, s)
|
r.parts = append(r.parts, clone(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +128,7 @@ func (r *reader) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// you could prob make this a bit faster by concurrency (make a bunch of workers => make them download the parts => temporarily add them to a map => fully assemble the result => make reader.Read() read out the result as the parts are coming in) but whatever, fine for now
|
// I have no idea what this truly even does anymore. Maybe a rewrite/refactor would be good?
|
||||||
func (r *reader) Read(buf []byte) (n int, err error) {
|
func (r *reader) Read(buf []byte) (n int, err error) {
|
||||||
misc.Log("we read")
|
misc.Log("we read")
|
||||||
if len(r.leftover) != 0 {
|
if len(r.leftover) != 0 {
|
||||||
|
|||||||
@@ -50,16 +50,20 @@ type Track struct {
|
|||||||
type TrackPolicy string
|
type TrackPolicy string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PolicyBlock TrackPolicy = "BLOCK" // not available (in your country)
|
PolicyMonetize TrackPolicy = "MONETIZE" // seems like only certain countries get this policy? sometimes protected by widevine and fairplay
|
||||||
PolicySnip TrackPolicy = "SNIP" // 30-second snippet available
|
PolicyBlock TrackPolicy = "BLOCK" // not available (in your country)
|
||||||
PolicyAllow TrackPolicy = "ALLOW" // all good
|
PolicySnip TrackPolicy = "SNIP" // 30-second snippet available
|
||||||
|
PolicyAllow TrackPolicy = "ALLOW" // all good
|
||||||
)
|
)
|
||||||
|
|
||||||
type Protocol string
|
type Protocol string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ProtocolHLS Protocol = "hls"
|
ProtocolHLS Protocol = "hls"
|
||||||
ProtocolProgressive Protocol = "progressive"
|
ProtocolProgressive Protocol = "progressive"
|
||||||
|
ProtocolEncryptedHLS Protocol = "encrypted-hls" // idk, haven't seen in the wild
|
||||||
|
ProtocolCTREncryptedHLS Protocol = "ctr-encrypted-hls" // google's widevine
|
||||||
|
ProtocolCBCEncryptedHLS Protocol = "cbc-encrypted-hls" // apple's fairplay
|
||||||
)
|
)
|
||||||
|
|
||||||
type Format struct {
|
type Format struct {
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ templ Track(prefs cfg.Preferences, t sc.Track, stream string, displayErr string,
|
|||||||
}
|
}
|
||||||
<h1>{ t.Title }</h1>
|
<h1>{ t.Title }</h1>
|
||||||
@TrackPlayer(prefs, t, stream, displayErr, autoplay, nextTrack, playlist, volume, mode, audio)
|
@TrackPlayer(prefs, t, stream, displayErr, autoplay, nextTrack, playlist, volume, mode, audio)
|
||||||
if cfg.Restream {
|
if displayErr == "" && cfg.Restream {
|
||||||
<div style="display: flex; margin-bottom: 1rem;">
|
<div style="display: flex; margin-bottom: 1rem;">
|
||||||
<a class="btn" href={ templ.SafeURL("/_/restream" + t.Href() + "?metadata=true") } download={ t.Permalink + "." + toExt(*downloadAudio) }>download</a>
|
<a class="btn" href={ templ.SafeURL("/_/restream" + t.Href() + "?metadata=true") } download={ t.Permalink + "." + toExt(*downloadAudio) }>download</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -220,6 +220,7 @@ templ Track(prefs cfg.Preferences, t sc.Track, stream string, displayErr string,
|
|||||||
if t.License != "" {
|
if t.License != "" {
|
||||||
<p>License: { t.License }</p>
|
<p>License: { t.License }</p>
|
||||||
}
|
}
|
||||||
|
<p>Policy: { t.Policy }</p>
|
||||||
if t.TagList != "" {
|
if t.TagList != "" {
|
||||||
<p>Tags: { strings.Join(sc.TagListParser(t.TagList), ", ") }</p>
|
<p>Tags: { strings.Join(sc.TagListParser(t.TagList), ", ") }</p>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user