修复字计数为0的flv的问题

This commit is contained in:
charlestamz
2023-02-03 15:49:47 +08:00
parent dd63ca86c8
commit 84937b73f7
3 changed files with 116 additions and 111 deletions

23
flv.go
View File

@@ -34,11 +34,7 @@ func (r *FLVRecorder) start() {
RecordPluginConfig.recordings.Store(r.ID, r) RecordPluginConfig.recordings.Store(r.ID, r)
r.PlayFLV() r.PlayFLV()
RecordPluginConfig.recordings.Delete(r.ID) RecordPluginConfig.recordings.Delete(r.ID)
if file, ok := r.Writer.(*os.File); ok { r.Close()
go r.writeMetaData(file, r.duration)
} else {
r.Close()
}
} }
func (r *FLVRecorder) writeMetaData(file *os.File, duration int64) { func (r *FLVRecorder) writeMetaData(file *os.File, duration int64) {
@@ -141,13 +137,9 @@ func (r *FLVRecorder) OnEvent(event any) {
r.times = append(r.times, float64(absTime)/1000) r.times = append(r.times, float64(absTime)/1000)
} }
} }
if r.Fragment > 0 && check && time.Duration(r.duration)*time.Millisecond >= r.Fragment { if r.duration = int64(absTime - r.SkipTS); r.Fragment > 0 && check && time.Duration(r.duration)*time.Millisecond >= r.Fragment {
r.SkipTS = absTime r.SkipTS = absTime
if file, ok := r.Writer.(*os.File); ok { r.Close()
go r.writeMetaData(file, r.duration)
} else {
r.Close()
}
r.Offset = 0 r.Offset = 0
if file, err := r.CreateFileFn(filepath.Join(r.Stream.Path, strconv.FormatInt(time.Now().Unix(), 10)+r.Ext), false); err == nil { if file, err := r.CreateFileFn(filepath.Join(r.Stream.Path, strconv.FormatInt(time.Now().Unix(), 10)+r.Ext), false); err == nil {
r.SetIO(file) r.SetIO(file)
@@ -169,9 +161,16 @@ func (r *FLVRecorder) OnEvent(event any) {
r.Stop() r.Stop()
} else { } else {
r.Offset += n r.Offset += n
r.duration = int64(absTime - r.SkipTS)
} }
default: default:
r.Subscriber.OnEvent(event) r.Subscriber.OnEvent(event)
} }
} }
func (r *FLVRecorder) Close() {
if file, ok := r.Writer.(*os.File); ok {
go r.writeMetaData(file, r.duration)
} else {
r.Recorder.Close()
}
}

99
main.go
View File

@@ -2,10 +2,8 @@ package record
import ( import (
_ "embed" _ "embed"
"encoding/json"
"errors" "errors"
"io" "io"
"net/http"
"sync" "sync"
. "m7s.live/engine/v4" . "m7s.live/engine/v4"
@@ -107,103 +105,6 @@ func (conf *RecordConfig) getRecorderConfigByType(t string) (recorder *Record) {
return return
} }
func (conf *RecordConfig) API_list(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
t := query.Get("type")
var files []*VideoFileInfo
var err error
recorder := conf.getRecorderConfigByType(t)
if recorder == nil {
for _, t = range []string{"flv", "mp4", "hls", "raw"} {
recorder = conf.getRecorderConfigByType(t)
var fs []*VideoFileInfo
if fs, err = recorder.Tree(recorder.Path, 0); err == nil {
files = append(files, fs...)
}
}
} else {
files, err = recorder.Tree(recorder.Path, 0)
}
if err == nil {
var bytes []byte
if bytes, err = json.Marshal(files); err == nil {
w.Write(bytes)
}
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func (conf *RecordConfig) API_start(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
streamPath := query.Get("streamPath")
if streamPath == "" {
http.Error(w, "no streamPath", http.StatusBadRequest)
return
}
t := query.Get("type")
var id string
var filePath string
var err error
switch t {
case "":
t = "flv"
fallthrough
case "flv":
var flvRecoder FLVRecorder
flvRecoder.IsInternal = true
flvRecoder.append = query.Get("append") != "" && util.Exist(filePath)
err = flvRecoder.Start(streamPath)
id = flvRecoder.ID
case "mp4":
recorder := NewMP4Recorder()
recorder.IsInternal = true
err = recorder.Start(streamPath)
id = recorder.ID
case "hls":
var recorder HLSRecorder
recorder.IsInternal = true
err = recorder.Start(streamPath)
id = recorder.ID
case "raw":
var recorder RawRecorder
recorder.IsInternal = true
recorder.append = query.Get("append") != "" && util.Exist(filePath)
err = recorder.Start(streamPath)
id = recorder.ID
default:
http.Error(w, "type not supported", http.StatusBadRequest)
return
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write([]byte(id))
}
func (conf *RecordConfig) API_list_recording(w http.ResponseWriter, r *http.Request) {
var recordings []any
conf.recordings.Range(func(key, value any) bool {
recordings = append(recordings, value)
return true
})
if err := json.NewEncoder(w).Encode(recordings); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func (conf *RecordConfig) API_stop(w http.ResponseWriter, r *http.Request) {
if recorder, ok := conf.recordings.Load(r.URL.Query().Get("id")); ok {
recorder.(ISubscriber).Stop()
w.Write([]byte("ok"))
return
}
http.Error(w, "no such recorder", http.StatusBadRequest)
}
func getFLVDuration(file io.ReadSeeker) uint32 { func getFLVDuration(file io.ReadSeeker) uint32 {
_, err := file.Seek(-4, io.SeekEnd) _, err := file.Seek(-4, io.SeekEnd)
if err == nil { if err == nil {

105
restful.go Normal file
View File

@@ -0,0 +1,105 @@
package record
import (
"encoding/json"
. "m7s.live/engine/v4"
"m7s.live/engine/v4/util"
"net/http"
)
func (conf *RecordConfig) API_list(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
t := query.Get("type")
var files []*VideoFileInfo
var err error
recorder := conf.getRecorderConfigByType(t)
if recorder == nil {
for _, t = range []string{"flv", "mp4", "hls", "raw"} {
recorder = conf.getRecorderConfigByType(t)
var fs []*VideoFileInfo
if fs, err = recorder.Tree(recorder.Path, 0); err == nil {
files = append(files, fs...)
}
}
} else {
files, err = recorder.Tree(recorder.Path, 0)
}
if err == nil {
var bytes []byte
if bytes, err = json.Marshal(files); err == nil {
w.Write(bytes)
}
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func (conf *RecordConfig) API_start(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
streamPath := query.Get("streamPath")
if streamPath == "" {
http.Error(w, "no streamPath", http.StatusBadRequest)
return
}
t := query.Get("type")
var id string
var filePath string
var err error
switch t {
case "":
t = "flv"
fallthrough
case "flv":
var flvRecoder FLVRecorder
flvRecoder.IsInternal = true
flvRecoder.append = query.Get("append") != "" && util.Exist(filePath)
err = flvRecoder.Start(streamPath)
id = flvRecoder.ID
case "mp4":
recorder := NewMP4Recorder()
recorder.IsInternal = true
err = recorder.Start(streamPath)
id = recorder.ID
case "hls":
var recorder HLSRecorder
recorder.IsInternal = true
err = recorder.Start(streamPath)
id = recorder.ID
case "raw":
var recorder RawRecorder
recorder.IsInternal = true
recorder.append = query.Get("append") != "" && util.Exist(filePath)
err = recorder.Start(streamPath)
id = recorder.ID
default:
http.Error(w, "type not supported", http.StatusBadRequest)
return
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write([]byte(id))
}
func (conf *RecordConfig) API_list_recording(w http.ResponseWriter, r *http.Request) {
var recordings []any
conf.recordings.Range(func(key, value any) bool {
recordings = append(recordings, value)
return true
})
if err := json.NewEncoder(w).Encode(recordings); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func (conf *RecordConfig) API_stop(w http.ResponseWriter, r *http.Request) {
if recorder, ok := conf.recordings.Load(r.URL.Query().Get("id")); ok {
recorder.(ISubscriber).Stop()
w.Write([]byte("ok"))
return
}
http.Error(w, "no such recorder", http.StatusBadRequest)
}