patch duration in m4a for restream/downloads

This commit is contained in:
Laptop
2025-03-11 15:57:20 +02:00
parent 7a044a2dec
commit 2b84ba8748
2 changed files with 37 additions and 9 deletions

View File

@@ -2,6 +2,7 @@ package restream
import (
"bytes"
"encoding/binary"
"image"
"io"
"strings"
@@ -27,6 +28,7 @@ type reader struct {
parts [][]byte
leftover []byte
index int
duration *uint32
req *fasthttp.Request
resp *fasthttp.Response
@@ -49,7 +51,21 @@ func clone(buf []byte) []byte {
return out
}
func (r *reader) Setup(url string, aac bool) error {
var mvhd = []byte("mvhd")
func fixDuration(data []byte, duration *uint32) {
i := bytes.Index(data, mvhd)
if i != -1 {
i += 20
bt := make([]byte, 4)
binary.BigEndian.PutUint32(bt, *duration)
copy(data[i:], bt)
// timescale is already 1000 in the files
}
}
func (r *reader) Setup(url string, aac bool, duration *uint32) error {
if r.req == nil {
r.req = fasthttp.AcquireRequest()
}
@@ -64,6 +80,7 @@ func (r *reader) Setup(url string, aac bool) error {
if aac {
r.client = misc.HlsAacClient
r.duration = duration
} else {
r.client = misc.HlsClient
}
@@ -118,7 +135,6 @@ func (r *reader) Close() error {
r.req.Reset()
r.resp.Reset()
r.client = nil
r.leftover = nil
r.index = 0
r.parts = r.parts[:0]
@@ -168,6 +184,10 @@ func (r *reader) Read(buf []byte) (n int, err error) {
data = r.resp.Body()
}
if r.index == 0 && r.duration != nil {
fixDuration(data, r.duration) // I'm guessing that mvhd will always be in first part
}
if len(data) > len(buf) {
n = copy(buf, data[:len(buf)])
} else {
@@ -241,7 +261,7 @@ func Load(r *fiber.App) {
switch audio {
case cfg.AudioMP3:
r := acquireReader()
if err := r.Setup(u, false); err != nil {
if err := r.Setup(u, false, nil); err != nil {
return err
}
@@ -404,6 +424,8 @@ func Load(r *fiber.App) {
result = append(result, data...)
}
fixDuration(result, &t.Duration)
tag, err := mp4meta.ReadMP4(bytes.NewReader(result))
if err != nil {
return err
@@ -439,7 +461,13 @@ func Load(r *fiber.App) {
}
r := acquireReader()
if err := r.Setup(u, audio == cfg.AudioAAC); err != nil {
if audio == cfg.AudioAAC {
err = r.Setup(u, true, &t.Duration)
} else {
err = r.Setup(u, false, nil)
}
if err != nil {
return err
}

View File

@@ -24,11 +24,11 @@ var TracksCache = map[string]cached[Track]{}
var tracksCacheLock = &sync.RWMutex{}
type Track struct {
Artwork string `json:"artwork_url"`
Comments int `json:"comment_count"`
CreatedAt string `json:"created_at"`
Description string `json:"description"`
//Duration int `json:"duration"` // there are duration and full_duration fields wtf does that mean
Artwork string `json:"artwork_url"`
Comments int `json:"comment_count"`
CreatedAt string `json:"created_at"`
Description string `json:"description"`
Duration uint32 `json:"full_duration"`
Genre string `json:"genre"`
Kind string `json:"kind"` // should always be "track"!
LastModified string `json:"last_modified"`