mirror of
https://github.com/langhuihui/monibuca.git
synced 2026-05-09 17:41:07 +08:00
fix: download m4
This commit is contained in:
+23
-28
@@ -241,7 +241,29 @@ func (a *Allocator) putBlock(b *Block) {
|
||||
|
||||
func (a *Allocator) Free(offset, size int) {
|
||||
//a.history = append(a.history, History{Malloc: false, Offset: offset, Size: size})
|
||||
a.mergeAdjacentBlocks(a.getBlock(offset, offset+size))
|
||||
switch leftAdjacent, rightAdjacent := a.offsetTree.findLeftAdjacentBlock(offset), a.offsetTree.findRightAdjacentBlock(offset+size); true {
|
||||
case leftAdjacent != nil && rightAdjacent != nil:
|
||||
a.deleteOffsetTree(rightAdjacent)
|
||||
a.deleteSizeTree(rightAdjacent)
|
||||
a.deleteSizeTree(leftAdjacent)
|
||||
leftAdjacent.End = rightAdjacent.End
|
||||
a.insertSizeTree(leftAdjacent)
|
||||
a.putBlock(rightAdjacent)
|
||||
case leftAdjacent == nil && rightAdjacent == nil:
|
||||
block := a.getBlock(offset, offset+size)
|
||||
a.insertSizeTree(block)
|
||||
a.insertOffsetTree(block)
|
||||
case leftAdjacent != nil:
|
||||
a.deleteSizeTree(leftAdjacent)
|
||||
leftAdjacent.End = offset + size
|
||||
a.insertSizeTree(leftAdjacent)
|
||||
case rightAdjacent != nil:
|
||||
a.deleteOffsetTree(rightAdjacent)
|
||||
a.deleteSizeTree(rightAdjacent)
|
||||
rightAdjacent.Start = offset
|
||||
a.insertSizeTree(rightAdjacent)
|
||||
a.insertOffsetTree(rightAdjacent)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Allocator) GetBlocks() (blocks []*Block) {
|
||||
@@ -292,33 +314,6 @@ func (a *Allocator) deleteOffsetTree(block *Block) {
|
||||
a.offsetTree = a.offsetTree.delete(block, TreeIndexOffset)
|
||||
}
|
||||
|
||||
func (a *Allocator) mergeAdjacentBlocks(block *Block) {
|
||||
switch leftAdjacent, rightAdjacent := a.offsetTree.findLeftAdjacentBlock(block.Start), a.offsetTree.findRightAdjacentBlock(block.End); true {
|
||||
case leftAdjacent != nil && rightAdjacent != nil:
|
||||
a.deleteOffsetTree(rightAdjacent)
|
||||
a.deleteSizeTree(rightAdjacent)
|
||||
a.deleteSizeTree(leftAdjacent)
|
||||
leftAdjacent.End = rightAdjacent.End
|
||||
a.insertSizeTree(leftAdjacent)
|
||||
a.putBlock(rightAdjacent)
|
||||
case leftAdjacent == nil && rightAdjacent == nil:
|
||||
a.insertSizeTree(block)
|
||||
a.insertOffsetTree(block)
|
||||
return
|
||||
case leftAdjacent != nil:
|
||||
a.deleteSizeTree(leftAdjacent)
|
||||
leftAdjacent.End = block.End
|
||||
a.insertSizeTree(leftAdjacent)
|
||||
case rightAdjacent != nil:
|
||||
a.deleteOffsetTree(rightAdjacent)
|
||||
a.deleteSizeTree(rightAdjacent)
|
||||
rightAdjacent.Start = block.Start
|
||||
a.insertSizeTree(rightAdjacent)
|
||||
a.insertOffsetTree(rightAdjacent)
|
||||
}
|
||||
a.putBlock(block)
|
||||
}
|
||||
|
||||
func (b *Block) findLeftAdjacentBlock(offset int) *Block {
|
||||
for b != nil {
|
||||
if b.End == offset {
|
||||
|
||||
@@ -3,6 +3,8 @@ package util
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func TestAllocator(t *testing.T) {
|
||||
@@ -90,3 +92,83 @@ func FuzzAllocator(f *testing.F) {
|
||||
t.Logf("totalMalloc:%d, free:%v", totalMalloc, size)
|
||||
})
|
||||
}
|
||||
|
||||
const testData = `
|
||||
- malloc: true
|
||||
offset: 0
|
||||
size: 16384
|
||||
- malloc: false
|
||||
offset: 139
|
||||
size: 16245
|
||||
- malloc: false
|
||||
offset: 0
|
||||
size: 50
|
||||
- malloc: false
|
||||
offset: 50
|
||||
size: 31
|
||||
- malloc: false
|
||||
offset: 81
|
||||
size: 9
|
||||
- malloc: false
|
||||
offset: 90
|
||||
size: 26
|
||||
- malloc: false
|
||||
offset: 116
|
||||
size: 21
|
||||
- malloc: false
|
||||
offset: 137
|
||||
size: 2
|
||||
- malloc: true
|
||||
offset: 0
|
||||
size: 16384
|
||||
- malloc: false
|
||||
offset: 277
|
||||
size: 16107
|
||||
- malloc: true
|
||||
offset: 0
|
||||
size: 16384
|
||||
- malloc: false
|
||||
offset: 432
|
||||
size: 16229
|
||||
- malloc: false
|
||||
offset: 0
|
||||
size: 277
|
||||
- malloc: false
|
||||
offset: 277
|
||||
size: 58
|
||||
- malloc: false
|
||||
offset: 335
|
||||
size: 60
|
||||
- malloc: false
|
||||
offset: 395
|
||||
size: 9
|
||||
- malloc: false
|
||||
offset: 404
|
||||
size: 26
|
||||
- malloc: true
|
||||
offset: 0
|
||||
size: 16384
|
||||
- malloc: false
|
||||
offset: 557
|
||||
size: 16259
|
||||
- malloc: false
|
||||
offset: 430
|
||||
size: 2
|
||||
`
|
||||
|
||||
var history []History
|
||||
|
||||
func init() {
|
||||
yaml.Unmarshal([]byte(testData), &history)
|
||||
}
|
||||
|
||||
func TestAllocatorUseData(t *testing.T) {
|
||||
allocator := NewAllocator(65535)
|
||||
for _, h := range history {
|
||||
if h.Malloc {
|
||||
allocator.Allocate(h.Size)
|
||||
} else {
|
||||
allocator.Free(h.Offset, h.Size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-7
@@ -6,7 +6,6 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -91,13 +90,16 @@ func (p *MP4Plugin) Catalog(ctx context.Context, req *emptypb.Empty) (resp *pb.R
|
||||
}
|
||||
|
||||
func (p *MP4Plugin) download(w http.ResponseWriter, r *http.Request) {
|
||||
filePath := r.PathValue("filePath")
|
||||
streamPath := r.PathValue("streamPath")
|
||||
query := r.URL.Query()
|
||||
rangeStr := strings.Split(query.Get("range"), "~")
|
||||
var startTime, endTime time.Time
|
||||
if len(rangeStr) != 2 {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
rangeStr = []string{query.Get(m7s.StartKey), query.Get(m7s.EndKey)}
|
||||
if rangeStr[0] == "" || rangeStr[1] == "" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
var err error
|
||||
startTime, err = util.TimeQueryParse(rangeStr[0])
|
||||
@@ -111,9 +113,9 @@ func (p *MP4Plugin) download(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
//timeRange := endTime.Sub(startTime)
|
||||
p.Info("download", "filePath", filePath, "start", startTime, "end", endTime)
|
||||
p.Info("download", "streamPath", streamPath, "start", startTime, "end", endTime)
|
||||
var streams []m7s.RecordStream
|
||||
p.DB.Find(&streams, "end_time>? AND start_time<? AND file_path=?", startTime, endTime, filePath)
|
||||
p.DB.Find(&streams, "end_time>? AND start_time<? AND stream_path=?", startTime, endTime, streamPath)
|
||||
muxer := mp4.NewMuxer(0)
|
||||
var n int
|
||||
n, err = w.Write(box.MakeFtypBox(box.TypeISOM, 0x200, box.TypeISOM, box.TypeISO2, box.TypeAVC1, box.TypeMP41))
|
||||
@@ -126,9 +128,10 @@ func (p *MP4Plugin) download(w http.ResponseWriter, r *http.Request) {
|
||||
sampleOffset := muxer.CurrentOffset + box.BasicBoxLen*2
|
||||
mdatOffset := sampleOffset
|
||||
var audioTrack, videoTrack *mp4.Track
|
||||
var file *os.File
|
||||
for i, stream := range streams {
|
||||
tsOffset = lastTs
|
||||
file, err := os.Open(filepath.Join(filePath, fmt.Sprintf("%d.mp4", stream.ID)))
|
||||
file, err = os.Open(stream.FilePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -156,6 +159,7 @@ func (p *MP4Plugin) download(w http.ResponseWriter, r *http.Request) {
|
||||
startTimestamp := startTime.Sub(stream.StartTime).Milliseconds()
|
||||
var startSample *box.Sample
|
||||
if startSample, err = demuxer.SeekTime(uint64(startTimestamp)); err != nil {
|
||||
tsOffset = 0
|
||||
continue
|
||||
}
|
||||
tsOffset = -int64(startSample.DTS)
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ var _ = m7s.InstallPlugin[MP4Plugin](defaultConfig, &pb.Api_ServiceDesc, pb.Regi
|
||||
|
||||
func (p *MP4Plugin) RegisterHandler() map[string]http.HandlerFunc {
|
||||
return map[string]http.HandlerFunc{
|
||||
"/download/{filePath...}": p.download,
|
||||
"/download/{streamPath...}": p.download,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ func (p *RecordFilePuller) Start() (err error) {
|
||||
if p.PullEndTime, err = util.TimeQueryParse(p.PullJob.Args.Get(EndKey)); err != nil {
|
||||
return
|
||||
}
|
||||
tx := p.PullJob.Plugin.DB.Find(&p.Streams, "end_time>? AND end_time<? AND stream_path=?", p.PullStartTime, p.PullEndTime, p.PullJob.RemoteURL)
|
||||
tx := p.PullJob.Plugin.DB.Find(&p.Streams, "end_time>? AND start_time<? AND stream_path=?", p.PullStartTime, p.PullEndTime, p.PullJob.RemoteURL)
|
||||
if tx.Error != nil {
|
||||
return tx.Error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user