mirror of
https://github.com/hkmadao/rtsp2rtmp.git
synced 2025-09-26 19:31:19 +08:00
live media info api
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,13 +1,14 @@
|
||||
package flvadmin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/deepch/vdk/av"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/flvadmin/httpflvmanage"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/common"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/dto/vo/ext/live"
|
||||
)
|
||||
|
||||
var hfas *HttpFlvAdmin
|
||||
@@ -31,6 +32,10 @@ func (hfa *HttpFlvAdmin) AddHttpFlvManager(
|
||||
) {
|
||||
hfm := httpflvmanage.NewHttpFlvManager(pktStream, code, codecs)
|
||||
hfa.hfms.Store(code, hfm)
|
||||
go func() {
|
||||
<-hfm.GetDone()
|
||||
hfa.hfms.Delete(code)
|
||||
}()
|
||||
}
|
||||
|
||||
func (hfa *HttpFlvAdmin) StopWrite(code string) {
|
||||
@@ -50,22 +55,26 @@ func (hfa *HttpFlvAdmin) StartWrite(code string) {
|
||||
}
|
||||
}
|
||||
|
||||
//添加播放者
|
||||
// 添加播放者
|
||||
func (hfa *HttpFlvAdmin) AddHttpFlvPlayer(
|
||||
playerDone <-chan int,
|
||||
pulseInterval time.Duration,
|
||||
code string,
|
||||
writer io.Writer,
|
||||
) (<-chan int, error) {
|
||||
) (<-chan int, *common.Rtmp2FlvCustomError) {
|
||||
v, b := hfa.hfms.Load(code)
|
||||
if b {
|
||||
hfm := v.(*httpflvmanage.HttpFlvManager)
|
||||
return hfm.AddHttpFlvPlayer(playerDone, pulseInterval, writer)
|
||||
flvPlayerDone, err := hfm.AddHttpFlvPlayer(playerDone, pulseInterval, writer)
|
||||
if err != nil {
|
||||
return flvPlayerDone, common.InternalError(err)
|
||||
}
|
||||
return flvPlayerDone, nil
|
||||
}
|
||||
return nil, errors.New("camera no connection")
|
||||
return nil, common.CustomError("camera no connection")
|
||||
}
|
||||
|
||||
//更新sps、pps等信息
|
||||
// 更新sps、pps等信息
|
||||
func (hfa *HttpFlvAdmin) UpdateCodecs(code string, codecs []av.CodecData) {
|
||||
rfw, ok := hfa.hfms.Load(code)
|
||||
if ok {
|
||||
@@ -73,3 +82,28 @@ func (hfa *HttpFlvAdmin) UpdateCodecs(code string, codecs []av.CodecData) {
|
||||
rfw.SetCodecs(codecs)
|
||||
}
|
||||
}
|
||||
|
||||
func (hfa *HttpFlvAdmin) GetLiveInfo(code string) (*live.LiveMediaInfo, error) {
|
||||
liveMediaInfo := &live.LiveMediaInfo{
|
||||
HasAudio: false,
|
||||
OnlineStatus: false,
|
||||
AnchorName: code,
|
||||
}
|
||||
rfw, ok := hfa.hfms.Load(code)
|
||||
if ok {
|
||||
rfw := rfw.(*httpflvmanage.HttpFlvManager)
|
||||
|
||||
liveMediaInfo.HasAudio = hasAudio(rfw.GetCodecs())
|
||||
liveMediaInfo.OnlineStatus = true
|
||||
}
|
||||
return liveMediaInfo, nil
|
||||
}
|
||||
|
||||
func hasAudio(streams []av.CodecData) bool {
|
||||
for _, stream := range streams {
|
||||
if stream.Type().IsAudio() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@@ -100,6 +100,8 @@ func commandRes(commandMessage tcpclientcommon.CommandMessage) {
|
||||
startRtmpPush(commandMessage)
|
||||
case "stopPushRtmp":
|
||||
stopRtmpPush(commandMessage)
|
||||
case "getLiveMediaInfo":
|
||||
getLiveMediaInfo(commandMessage)
|
||||
default:
|
||||
logs.Error("unsupport commandType: %s", commandMessage.MessageType)
|
||||
}
|
||||
|
82
src/rtsp2rtmp/tcpclient/get_live_media_info.go
Normal file
82
src/rtsp2rtmp/tcpclient/get_live_media_info.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package tcpclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/flvadmin"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/tcpclient/tcpclientcommon"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/common"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/dto/vo/ext/live"
|
||||
base_service "github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/service/base"
|
||||
)
|
||||
|
||||
func getLiveMediaInfo(commandMessage tcpclientcommon.CommandMessage) {
|
||||
conn, err := tcpclientcommon.ConnectAndResRegister("getLiveMediaInfo", commandMessage.MessageId)
|
||||
if err != nil {
|
||||
logs.Error("getLiveMediaInfo connect to server error: %v", err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
paramStr := commandMessage.Param
|
||||
rtmpPushParam := RtmpPushParam{}
|
||||
err = json.Unmarshal([]byte(paramStr), &rtmpPushParam)
|
||||
if err != nil {
|
||||
logs.Error("getLiveMediaInfo message format error: %v", err)
|
||||
result := common.ErrorResult(fmt.Sprintf("getLiveMediaInfo message format error: %v", err))
|
||||
_, err = tcpclientcommon.WriteResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
condition := common.GetEqualCondition("code", rtmpPushParam.CameraCode)
|
||||
camera, err := base_service.CameraFindOneByCondition(condition)
|
||||
if err != nil {
|
||||
logs.Error("CameraFindOneByCondition error: %v", err)
|
||||
result := common.ErrorResult("CameraFindOneByCondition error")
|
||||
_, err = tcpclientcommon.WriteResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if !camera.RtmpPushStatus {
|
||||
liveMediaInfo := live.LiveMediaInfo{
|
||||
HasAudio: false,
|
||||
OnlineStatus: false,
|
||||
AnchorName: camera.Code,
|
||||
}
|
||||
result := common.SuccessResultData(liveMediaInfo)
|
||||
_, err = tcpclientcommon.WriteResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
liveMediaInfo, err := flvadmin.GetSingleHttpFlvAdmin().GetLiveInfo(camera.Code)
|
||||
if err != nil {
|
||||
logs.Error("getLiveInfo error : %v", err)
|
||||
result := common.ErrorResult("getLiveInfo error")
|
||||
_, err = tcpclientcommon.WriteResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
result := common.SuccessResultData(liveMediaInfo)
|
||||
_, err = tcpclientcommon.WriteResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
type CommandMessage struct {
|
||||
// "cameraAq" "historyVideoPage" "flvFileMediaInfo" "flvPlay" "flvFetchMoreData" "startPushRtmp" "stopPushRtmp"
|
||||
// "cameraAq" "historyVideoPage" "flvFileMediaInfo" "flvPlay" "flvFetchMoreData" "startPushRtmp" "stopPushRtmp" "getLiveMediaInfo"
|
||||
MessageType string `json:"messageType"`
|
||||
Param string `json:"param"`
|
||||
MessageId string `json:"messageId"`
|
||||
@@ -25,7 +25,7 @@ type RegisterInfo struct {
|
||||
ClientCode string `json:"clientCode"`
|
||||
DateStr string `json:"dateStr"`
|
||||
Sign string `json:"sign"`
|
||||
// "keepChannel" "cameraOnline" "cameraOffline" "cameraAq" "historyVideoPage" "flvFileMediaInfo" "flvPlay" "flvFetchMoreData" "startPushRtmp" "stopPushRtmp"
|
||||
// "keepChannel" "cameraOnline" "cameraOffline" "cameraAq" "historyVideoPage" "flvFileMediaInfo" "flvPlay" "flvFetchMoreData" "startPushRtmp" "stopPushRtmp" "getLiveMediaInfo"
|
||||
ConnType string `json:"connType"`
|
||||
MessageId string `json:"messageId"`
|
||||
CameraCode string `json:"cameraCode"`
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package common
|
||||
|
||||
import "errors"
|
||||
|
||||
type AppResult struct {
|
||||
Status uint32 `json:"status"`
|
||||
Message string `json:"message"`
|
||||
@@ -31,6 +33,10 @@ type DeleteRefErrorMessageVO struct {
|
||||
RefClassName string `json:"refClassName"`
|
||||
}
|
||||
|
||||
func (appResult *AppResult) IsFailed() bool {
|
||||
return appResult.Status != 0
|
||||
}
|
||||
|
||||
func ErrorResult(msg string) AppResult {
|
||||
return AppResult{Status: 1, Message: msg}
|
||||
}
|
||||
@@ -46,3 +52,27 @@ func SuccessResultMsg(msg string) AppResult {
|
||||
func SuccessResultWithMsg(msg string, data interface{}) AppResult {
|
||||
return AppResult{Status: 0, Message: msg, Data: data}
|
||||
}
|
||||
|
||||
type Rtmp2FlvCustomError struct {
|
||||
kind int
|
||||
err error
|
||||
}
|
||||
|
||||
func CustomError(errMsg string) *Rtmp2FlvCustomError {
|
||||
return &Rtmp2FlvCustomError{kind: 0, err: errors.New(errMsg)}
|
||||
}
|
||||
|
||||
func InternalError(err error) *Rtmp2FlvCustomError {
|
||||
if err == nil {
|
||||
panic("err param is nil")
|
||||
}
|
||||
return &Rtmp2FlvCustomError{kind: 1, err: err}
|
||||
}
|
||||
|
||||
func (ce *Rtmp2FlvCustomError) IsCustomError() bool {
|
||||
return ce.kind == 0
|
||||
}
|
||||
|
||||
func (ce *Rtmp2FlvCustomError) Error() string {
|
||||
return ce.err.Error()
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ import (
|
||||
base_service "github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/service/base"
|
||||
)
|
||||
|
||||
func CameraRecordFileDuration(ctx *gin.Context) {
|
||||
func CameraRecordFileMediaInfo(ctx *gin.Context) {
|
||||
defer func() {
|
||||
if result := recover(); result != nil {
|
||||
logs.Error("system painc : %v \nstack : %v", result, string(debug.Stack()))
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/flvadmin"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/flvadmin/fileflvmanager/fileflvreader"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/utils"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/common"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/dto/vo/ext/flv_file"
|
||||
base_service "github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/service/base"
|
||||
@@ -20,6 +21,106 @@ import (
|
||||
|
||||
var playerMap sync.Map
|
||||
|
||||
func HttpFlvPlayMediaInfo(ctx *gin.Context) {
|
||||
defer func() {
|
||||
if result := recover(); result != nil {
|
||||
logs.Error("system painc : %v \nstack : %v", result, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
ctx.Writer.Header().Set("Connection", "keep-alive")
|
||||
|
||||
method, ok := ctx.Params.Get("method")
|
||||
if !ok || method == "" {
|
||||
logs.Error("path param method is rquired")
|
||||
result := common.ErrorResult("path param method is rquired")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
|
||||
code, ok := ctx.Params.Get("code")
|
||||
if !ok || code == "" {
|
||||
logs.Error("path param code is rquired")
|
||||
result := common.ErrorResult("path param code is rquired")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
|
||||
authCode, ok := ctx.Params.Get("authCode.flv")
|
||||
if !ok || authCode == "" {
|
||||
logs.Error("path param authCode is rquired")
|
||||
result := common.ErrorResult("path param authCode is rquired")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
authCode = utils.ReverseString(strings.Replace(utils.ReverseString(authCode), utils.ReverseString(".flv"), "", 1))
|
||||
|
||||
conditon := common.GetEqualCondition("code", code)
|
||||
camera, err := base_service.CameraFindOneByCondition(conditon)
|
||||
if err != nil {
|
||||
logs.Error("camera query error : %v", err)
|
||||
result := common.ErrorResult("internal error")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
|
||||
if !(method == "temp" || method == "permanent") {
|
||||
logs.Error("method error : %s", method)
|
||||
result := common.ErrorResult("internal error")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
if method == "temp" {
|
||||
var filters = []common.EqualFilter{{Name: "cameraId", Value: camera.Id}, {Name: "authCode", Value: authCode}}
|
||||
condition := common.GetEqualConditions(filters)
|
||||
|
||||
exists, err := base_service.CameraShareExistsByCondition(condition)
|
||||
if err != nil {
|
||||
logs.Error("cameraShareExistsByCondition error : %v", err)
|
||||
result := common.ErrorResult("internal error")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
if !exists {
|
||||
logs.Error("camera [%s] AuthCodeTemp expired : %s", camera.Code, authCode)
|
||||
result := common.ErrorResult("auth error")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
|
||||
cs, err := base_service.CameraShareFindOneByCondition(condition)
|
||||
if err != nil {
|
||||
logs.Error("CameraShareSelectOne error : %v", err)
|
||||
result := common.ErrorResult("internal error")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
if time.Now().Before(cs.StartTime) || time.Now().After(cs.Deadline) {
|
||||
logs.Error("camera [%s] AuthCodeTemp expired : %s", camera.Code, authCode)
|
||||
result := common.ErrorResult("auth error")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
if method == "permanent" && authCode != camera.PlayAuthCode {
|
||||
logs.Error("AuthCodePermanent error : %s", authCode)
|
||||
result := common.ErrorResult("auth error")
|
||||
ctx.JSON(http.StatusBadRequest, result)
|
||||
return
|
||||
}
|
||||
|
||||
liveMediaInfo, err := flvadmin.GetSingleHttpFlvAdmin().GetLiveInfo(camera.Code)
|
||||
if err != nil {
|
||||
logs.Error("getLiveInfo error : %v", err)
|
||||
result := common.ErrorResult("internal error")
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
result := common.SuccessResultData(liveMediaInfo)
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
func HttpFlvPlay(ctx *gin.Context) {
|
||||
defer func() {
|
||||
if result := recover(); result != nil {
|
||||
@@ -28,15 +129,28 @@ func HttpFlvPlay(ctx *gin.Context) {
|
||||
}()
|
||||
ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
ctx.Writer.Header().Set("Connection", "keep-alive")
|
||||
uri := strings.TrimSuffix(strings.TrimLeft(ctx.Request.RequestURI, "/"), ".flv")
|
||||
uris := strings.Split(uri, "/")
|
||||
if len(uris) < 3 || uris[0] != "live" {
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
|
||||
method, ok := ctx.Params.Get("method")
|
||||
if !ok || method == "" {
|
||||
logs.Error("path param method is rquired")
|
||||
http.Error(ctx.Writer, "path param method is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
method := uris[1]
|
||||
code := uris[2]
|
||||
authCode := uris[3]
|
||||
|
||||
code, ok := ctx.Params.Get("code")
|
||||
if !ok || code == "" {
|
||||
logs.Error("path param code is rquired")
|
||||
http.Error(ctx.Writer, "path param code is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
authCode, ok := ctx.Params.Get("authCode.flv")
|
||||
if !ok || authCode == "" {
|
||||
logs.Error("path param authCode is rquired")
|
||||
http.Error(ctx.Writer, "path param authCode is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
authCode = utils.ReverseString(strings.Replace(utils.ReverseString(authCode), utils.ReverseString(".flv"), "", 1))
|
||||
|
||||
conditon := common.GetEqualCondition("code", code)
|
||||
camera, err := base_service.CameraFindOneByCondition(conditon)
|
||||
@@ -55,8 +169,22 @@ func HttpFlvPlay(ctx *gin.Context) {
|
||||
if method == "temp" {
|
||||
var filters = []common.EqualFilter{{Name: "cameraId", Value: camera.Id}, {Name: "authCode", Value: authCode}}
|
||||
condition := common.GetEqualConditions(filters)
|
||||
cs, err := base_service.CameraShareFindOneByCondition(condition)
|
||||
|
||||
exists, err := base_service.CameraShareExistsByCondition(condition)
|
||||
if err != nil {
|
||||
logs.Error("cameraShareExistsByCondition error : %v", err)
|
||||
result := common.ErrorResult("internal error")
|
||||
ctx.JSON(http.StatusBadRequest, result)
|
||||
return
|
||||
}
|
||||
if !exists {
|
||||
logs.Error("camera [%s] AuthCodeTemp expired : %s", camera.Code, authCode)
|
||||
result := common.ErrorResult("auth error")
|
||||
ctx.JSON(http.StatusBadRequest, result)
|
||||
return
|
||||
}
|
||||
|
||||
cs, err := base_service.CameraShareFindOneByCondition(condition)
|
||||
if err != nil {
|
||||
logs.Error("CameraShareSelectOne error : %v", err)
|
||||
result := common.ErrorResult("internal error")
|
||||
@@ -83,9 +211,15 @@ func HttpFlvPlay(ctx *gin.Context) {
|
||||
playerDone := make(chan int)
|
||||
defer close(playerDone)
|
||||
const timeout = 10 * time.Second
|
||||
flvPlayerDone, err := flvadmin.GetSingleHttpFlvAdmin().AddHttpFlvPlayer(playerDone, timeout/2, code, ctx.Writer)
|
||||
if err != nil {
|
||||
logs.Error("camera [%s] add player error : %s", code, err)
|
||||
flvPlayerDone, addHttpFlvPlayerErr := flvadmin.GetSingleHttpFlvAdmin().AddHttpFlvPlayer(playerDone, timeout/2, code, ctx.Writer)
|
||||
if addHttpFlvPlayerErr != nil {
|
||||
logs.Error("camera [%s] add player error : %v", code, addHttpFlvPlayerErr)
|
||||
if addHttpFlvPlayerErr.IsCustomError() {
|
||||
result := common.ErrorResult(addHttpFlvPlayerErr.Error())
|
||||
ctx.JSON(http.StatusBadRequest, result)
|
||||
return
|
||||
}
|
||||
|
||||
result := common.ErrorResult("internal error")
|
||||
ctx.JSON(http.StatusBadRequest, result)
|
||||
return
|
||||
@@ -94,7 +228,7 @@ func HttpFlvPlay(ctx *gin.Context) {
|
||||
logs.Info("player [%s] addr [%s] exit", code, ctx.Request.RemoteAddr)
|
||||
}
|
||||
|
||||
func HttpFlvVODFileDuration(ctx *gin.Context) {
|
||||
func HttpFlvVODFileMediaInfo(ctx *gin.Context) {
|
||||
defer func() {
|
||||
if result := recover(); result != nil {
|
||||
logs.Error("system painc : %v \nstack : %v", result, string(debug.Stack()))
|
||||
|
7
src/rtsp2rtmp/web/dto/vo/ext/live/live.go
Normal file
7
src/rtsp2rtmp/web/dto/vo/ext/live/live.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package live
|
||||
|
||||
type LiveMediaInfo struct {
|
||||
HasAudio bool `json:"hasAudio"`
|
||||
OnlineStatus bool `json:"onlineStatus"`
|
||||
AnchorName string `json:"anchorName"`
|
||||
}
|
@@ -42,8 +42,9 @@ func (w *web) webRun() {
|
||||
router.POST("/login", ext_controller.Login)
|
||||
router.POST("/logout", ext_controller.Logout)
|
||||
|
||||
router.GET("/live/getMediaInfo/:method/:code/:authCode.flv", ext_controller.HttpFlvPlayMediaInfo)
|
||||
router.GET("/live/:method/:code/:authCode.flv", ext_controller.HttpFlvPlay)
|
||||
router.GET("/vod/getDuration/:fileName", ext_controller.HttpFlvVODFileDuration)
|
||||
router.GET("/vod/getMediaInfo/:fileName", ext_controller.HttpFlvVODFileMediaInfo)
|
||||
router.GET("/vod/start/:fileName", ext_controller.HttpFlvVODStart)
|
||||
router.GET("/vod/fetch", ext_controller.HttpFlvVODFetch)
|
||||
router.GET("/vod/getFileList", ext_controller.CameraGetRecordFiles)
|
||||
@@ -99,7 +100,7 @@ func (w *web) webRun() {
|
||||
router.GET("/cameraRecord/getByIds", base_controller.CameraRecordGetByIds)
|
||||
router.POST("/cameraRecord/aq", base_controller.CameraRecordAq)
|
||||
router.POST("/cameraRecord/aqPage", base_controller.CameraRecordAqPage)
|
||||
router.GET("/cameraRecord/getDuration/:idCameraRecord", ext_controller.CameraRecordFileDuration)
|
||||
router.GET("/cameraRecord/getMediaInfo/:idCameraRecord", ext_controller.CameraRecordFileMediaInfo)
|
||||
router.GET("/cameraRecord/start/:idCameraRecord", ext_controller.CameraRecordFilePlay)
|
||||
router.GET("/cameraRecord/fetch", ext_controller.CameraRecordFileFetch)
|
||||
|
||||
|
Reference in New Issue
Block a user