mirror of
https://github.com/Monibuca/plugin-record.git
synced 2025-09-29 05:52:08 +08:00

* [feature] 支持录制完成后上传到Minio * change module id * Update mod name * reset go.mod * Update for minio uploading * Update for log * [feature] support all Recorder * Update * Merge branch 'v4' into githubv4 * v4: git commit for minio * fix error * Update * Update * Update for support max Duration * Update v4.6.5 * Update for chang Config name * [refactor] update for recording duration * Update for remove orgion file * Update mod * Update * fix: close mp4 record error * Update readme * Fix file not upload Successfully * feat(recording): 支持录制检查回调 * feat:增加数据库录制检查 * Update 录制文件没有写入结束标志 * 更新依赖包 * fix(record): 自动删除的录像文件。 * Update for sqllite to db error
320 lines
8.4 KiB
Go
320 lines
8.4 KiB
Go
package record
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
. "m7s.live/engine/v4"
|
|
"m7s.live/engine/v4/util"
|
|
)
|
|
|
|
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", "fmp4", "hls", "raw", "raw_audio"} {
|
|
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")
|
|
fileName := query.Get("fileName")
|
|
fragment := query.Get("fragment")
|
|
if streamPath == "" {
|
|
http.Error(w, "no streamPath", http.StatusBadRequest)
|
|
return
|
|
}
|
|
t := query.Get("type")
|
|
duration := query.Get("duration")
|
|
var id string
|
|
var err error
|
|
var irecorder IRecorder
|
|
switch t {
|
|
case "":
|
|
t = "flv"
|
|
fallthrough
|
|
case "flv":
|
|
irecorder = NewFLVRecorder(OrdinaryMode)
|
|
case "mp4":
|
|
irecorder = NewMP4Recorder()
|
|
case "fmp4":
|
|
irecorder = NewFMP4Recorder()
|
|
case "hls":
|
|
irecorder = NewHLSRecorder()
|
|
case "raw":
|
|
irecorder = NewRawRecorder()
|
|
case "raw_audio":
|
|
irecorder = NewRawAudioRecorder()
|
|
default:
|
|
http.Error(w, "type not supported", http.StatusBadRequest)
|
|
return
|
|
}
|
|
recorder := irecorder.GetRecorder()
|
|
if fragment != "" {
|
|
if f, err := time.ParseDuration(fragment); err == nil {
|
|
recorder.Fragment = f
|
|
}
|
|
}
|
|
recorder.FileName = fileName
|
|
recorder.append = query.Get("append") != ""
|
|
if fileName != "" {
|
|
err = irecorder.StartWithFileName(streamPath, fileName)
|
|
} else {
|
|
err = irecorder.Start(streamPath)
|
|
}
|
|
id = recorder.ID
|
|
if err != nil {
|
|
util.ReturnError(util.APIErrorInternal, err.Error(), w, r)
|
|
return
|
|
}
|
|
|
|
// 设置录制时长限制
|
|
if duration != "" {
|
|
if d, err := time.ParseDuration(duration); err == nil {
|
|
recorder.Duration = d
|
|
}
|
|
}
|
|
util.ReturnError(util.APIErrorNone, id, w, r)
|
|
}
|
|
|
|
func (conf *RecordConfig) API_list_recording(w http.ResponseWriter, r *http.Request) {
|
|
util.ReturnFetchValue(func() (recordings []any) {
|
|
conf.recordings.Range(func(key, value any) bool {
|
|
recordings = append(recordings, value)
|
|
return true
|
|
})
|
|
return
|
|
}, w, r)
|
|
}
|
|
|
|
func (conf *RecordConfig) API_stop(w http.ResponseWriter, r *http.Request) {
|
|
id := r.URL.Query().Get("id")
|
|
if recorder, ok := conf.recordings.Load(id); ok {
|
|
recorder.(ISubscriber).Stop(zap.String("reason", "api"))
|
|
util.ReturnOK(w, r)
|
|
return
|
|
}
|
|
util.ReturnError(util.APIErrorNotFound, "no such recorder", w, r)
|
|
}
|
|
|
|
func (conf *RecordConfig) API_recordfile_delete(w http.ResponseWriter, r *http.Request) {
|
|
query := r.URL.Query()
|
|
path := query.Get("path")
|
|
err := os.Remove(path)
|
|
if err != nil {
|
|
plugin.Error("修改文件时出错", zap.Error(err))
|
|
util.ReturnError(1, "删除文件时出错", w, r)
|
|
return
|
|
}
|
|
util.ReturnOK(w, r)
|
|
}
|
|
|
|
func (conf *RecordConfig) API_recordfile_modify(w http.ResponseWriter, r *http.Request) {
|
|
query := r.URL.Query()
|
|
path := query.Get("path")
|
|
newName := query.Get("newName")
|
|
dirPath := filepath.Dir(path)
|
|
err := os.Rename(path, dirPath+"/"+newName)
|
|
if err != nil {
|
|
plugin.Error("修改文件时出错", zap.Error(err))
|
|
util.ReturnError(1, "修改文件时出错", w, r)
|
|
return
|
|
}
|
|
util.ReturnOK(w, r)
|
|
}
|
|
|
|
func (conf *RecordConfig) API_list_page(w http.ResponseWriter, r *http.Request) {
|
|
query := r.URL.Query()
|
|
t := query.Get("type")
|
|
pageSize := query.Get("pageSize")
|
|
pageNum := query.Get("pageNum")
|
|
streamPath := query.Get("streamPath") //搜索条件
|
|
var files []*VideoFileInfo
|
|
var outFiles []*VideoFileInfo
|
|
var err error
|
|
var totalPageCount int = 1
|
|
recorder := conf.getRecorderConfigByType(t)
|
|
if recorder == nil {
|
|
for _, t = range []string{"flv", "mp4", "fmp4", "hls", "raw", "raw_audio"} {
|
|
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 streamPath != "" {
|
|
for _, file := range files {
|
|
if strings.Contains(file.Path, streamPath) {
|
|
outFiles = append(outFiles, file)
|
|
}
|
|
}
|
|
} else {
|
|
outFiles = files
|
|
}
|
|
|
|
totalCount := len(outFiles) //总条数
|
|
if pageSize != "" && pageNum != "" {
|
|
pageSizeInt, err := strconv.Atoi(pageSize)
|
|
if err != nil {
|
|
http.Error(w, "pageSize parameter error", http.StatusBadRequest)
|
|
return
|
|
}
|
|
pageNumInt, err := strconv.Atoi(pageNum)
|
|
if err != nil {
|
|
http.Error(w, "pageNum parameter error", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if pageSizeInt > 0 {
|
|
if pageNumInt > 0 {
|
|
totalPageCount = (totalCount / pageSizeInt) + 1 //总页数
|
|
remainCount := totalCount % pageSizeInt //分页后剩余条数
|
|
if remainCount == 0 && totalPageCount != 1 {
|
|
totalPageCount = totalCount / pageSizeInt
|
|
}
|
|
if pageNumInt > totalPageCount {
|
|
http.Error(w, "pageSize parameter error", http.StatusBadRequest)
|
|
return
|
|
}
|
|
startIndex := (pageNumInt - 1) * pageSizeInt //开始索引
|
|
endIndex := startIndex + pageSizeInt
|
|
if endIndex > totalCount {
|
|
endIndex = totalCount
|
|
}
|
|
outFiles = outFiles[startIndex:endIndex]
|
|
} else {
|
|
http.Error(w, "pageNum parameter error", http.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
if err == nil {
|
|
//var bytes []byte
|
|
//if bytes, err = json.Marshal(&struct {
|
|
// Files []*VideoFileInfo
|
|
// TotalCount int
|
|
// TotalPageCount int
|
|
//}{
|
|
// Files: outFiles,
|
|
// TotalCount: totalCount,
|
|
// TotalPageCount: totalPageCount,
|
|
//}); err == nil {
|
|
// w.Write(bytes)
|
|
//}
|
|
util.ReturnValue(&struct {
|
|
Files []*VideoFileInfo `json:"files"`
|
|
TotalCount int `json:"totalCount"`
|
|
TotalPageCount int `json:"totalPageCount"`
|
|
}{
|
|
Files: outFiles,
|
|
TotalCount: totalCount,
|
|
TotalPageCount: totalPageCount,
|
|
}, w, r)
|
|
}
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
func (conf *RecordConfig) API_list_recording_page(w http.ResponseWriter, r *http.Request) {
|
|
util.ReturnFetchValue(func() (outdata any) {
|
|
var recordings []any
|
|
conf.recordings.Range(func(key, value any) bool {
|
|
recordings = append(recordings, value)
|
|
return true
|
|
})
|
|
query := r.URL.Query()
|
|
pageSize := query.Get("pageSize")
|
|
pageNum := query.Get("pageNum")
|
|
RecId := query.Get("id") //搜索条件
|
|
var outRecordings []any
|
|
var totalPageCount int = 1
|
|
if RecId != "" {
|
|
for _, record := range recordings {
|
|
if record.(IRecorder).GetRecorder().ID == RecId {
|
|
outRecordings = append(outRecordings, record)
|
|
}
|
|
}
|
|
} else {
|
|
outRecordings = recordings
|
|
}
|
|
|
|
totalCount := len(outRecordings) //总条数
|
|
if pageSize != "" && pageNum != "" {
|
|
pageSizeInt, err := strconv.Atoi(pageSize)
|
|
if err != nil {
|
|
http.Error(w, "pageSize parameter error", http.StatusBadRequest)
|
|
return
|
|
}
|
|
pageNumInt, err := strconv.Atoi(pageNum)
|
|
if err != nil {
|
|
http.Error(w, "pageNum parameter error", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if pageSizeInt > 0 {
|
|
if pageNumInt > 0 {
|
|
totalPageCount = (totalCount / pageSizeInt) + 1 //总页数
|
|
remainCount := totalCount % pageSizeInt //分页后剩余条数
|
|
if remainCount == 0 && totalPageCount != 1 {
|
|
totalPageCount = totalCount / pageSizeInt
|
|
}
|
|
if pageNumInt > totalPageCount {
|
|
http.Error(w, "pageSize parameter error", http.StatusBadRequest)
|
|
return
|
|
}
|
|
startIndex := (pageNumInt - 1) * pageSizeInt //开始索引
|
|
endIndex := startIndex + pageSizeInt
|
|
if endIndex > totalCount {
|
|
endIndex = totalCount
|
|
}
|
|
outRecordings = outRecordings[startIndex:endIndex]
|
|
} else {
|
|
http.Error(w, "pageNum parameter error", http.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
outdata = &struct {
|
|
Files []any `json:"files"`
|
|
TotalCount int `json:"totalCount"`
|
|
TotalPageCount int `json:"totalPageCount"`
|
|
}{
|
|
Files: outRecordings,
|
|
TotalCount: totalCount,
|
|
TotalPageCount: totalPageCount,
|
|
}
|
|
return
|
|
}, w, r)
|
|
}
|