mirror of
https://github.com/hkmadao/rtsp2rtmp.git
synced 2025-09-26 19:31:19 +08:00
receive remote command
This commit is contained in:
2
main.go
2
main.go
@@ -8,6 +8,7 @@ import (
|
||||
_ "github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/conf" // 必须先导入配置文件
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/ffmpegmanager"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/rtmpserver"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/tcpclient"
|
||||
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/rtspclientmanager"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web"
|
||||
@@ -35,6 +36,7 @@ func main() {
|
||||
}
|
||||
task.GetSingleTask().StartTask()
|
||||
web.GetSingleWeb().StartWeb()
|
||||
tcpclient.StartCommandReceiveServer()
|
||||
sigs := make(chan os.Signal, 1)
|
||||
done := make(chan bool, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
@@ -19,4 +19,11 @@ server:
|
||||
show-sql: false
|
||||
token:
|
||||
duration: 1440
|
||||
remote:
|
||||
server-ip: 127.0.0.1
|
||||
port: 8089
|
||||
client-id: demo
|
||||
sign-secret: 123456
|
||||
secret: 123456
|
||||
|
||||
|
53
src/rtsp2rtmp/tcpclient/camera_aq.go
Normal file
53
src/rtsp2rtmp/tcpclient/camera_aq.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package tcpclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/common"
|
||||
dto_convert "github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/controller/convert"
|
||||
base_service "github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/service/base"
|
||||
)
|
||||
|
||||
func cameraAq(paramStr string) {
|
||||
condition := common.AqCondition{}
|
||||
err := json.Unmarshal([]byte(paramStr), &condition)
|
||||
if err != nil {
|
||||
logs.Error("flvFileMediaInfo message format error: %v", err)
|
||||
return
|
||||
}
|
||||
conn, err := connectAndRegister("historyVideoPage")
|
||||
if err != nil {
|
||||
logs.Error("historyVideoPage connect to server error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
cameras, err := base_service.CameraFindCollectionByCondition(condition)
|
||||
if err != nil {
|
||||
logs.Error("CameraFindCollectionByCondition error: %v", err)
|
||||
result := common.ErrorResult("CameraFindCollectionByCondition error")
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
voList, err := dto_convert.ConvertCameraToVOList(cameras)
|
||||
if err != nil {
|
||||
logs.Error("ConvertCameraToVOList error: %v", err)
|
||||
result := common.ErrorResult("ConvertCameraToVOList error")
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
result := common.SuccessResultData(voList)
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
86
src/rtsp2rtmp/tcpclient/command_receive.go
Normal file
86
src/rtsp2rtmp/tcpclient/command_receive.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package tcpclient
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/core/config"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/utils"
|
||||
)
|
||||
|
||||
func StartCommandReceiveServer() {
|
||||
go func() {
|
||||
for {
|
||||
commandReceiveConnect()
|
||||
<-time.NewTicker(1 * time.Minute).C
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func commandReceiveConnect() {
|
||||
conn, err := connectAndRegister("keepChannel")
|
||||
if err != nil {
|
||||
logs.Error("keepChannel connect to server error: %v", err)
|
||||
return
|
||||
}
|
||||
logs.Info("keepChannel connect to server successful, remote: %s", conn.RemoteAddr().String())
|
||||
// read command
|
||||
for {
|
||||
dataLenBytes := make([]byte, 4)
|
||||
_, err := conn.Read(dataLenBytes)
|
||||
if err != nil {
|
||||
logs.Error("read len error: %v", err)
|
||||
break
|
||||
}
|
||||
var dataLen int32
|
||||
buffer := bytes.NewBuffer(dataLenBytes)
|
||||
err = binary.Read(buffer, binary.LittleEndian, &dataLen)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
break
|
||||
}
|
||||
logs.Info("receive message dataLen: %d", dataLen)
|
||||
serverRepBytes := make([]byte, dataLen)
|
||||
_, err = conn.Read(serverRepBytes)
|
||||
if err != nil {
|
||||
logs.Error("read message body error: %v", err)
|
||||
break
|
||||
}
|
||||
secretCommandStr := string(serverRepBytes)
|
||||
logs.Info("receive message: %s", secretCommandStr)
|
||||
secretStr, err := config.String("server.remote.secret")
|
||||
if err != nil {
|
||||
logs.Error("get remote secret error: %v", err)
|
||||
return
|
||||
}
|
||||
commandStr, err := utils.DecryptAES([]byte(secretStr), secretCommandStr)
|
||||
if err != nil {
|
||||
logs.Error("message DecryptAES error: %v", err)
|
||||
continue
|
||||
}
|
||||
commandMessage := CommandMessage{}
|
||||
err = json.Unmarshal([]byte(commandStr), &commandMessage)
|
||||
if err != nil {
|
||||
logs.Error("message format error: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
switch commandMessage.MessageType {
|
||||
case "cameraAq":
|
||||
cameraAq(commandMessage.Param)
|
||||
case "historyVideoPage":
|
||||
historyVideoPage(commandMessage.Param)
|
||||
case "flvFileMediaInfo":
|
||||
flvFileMediaInfo(commandMessage.Param)
|
||||
case "flvPlay":
|
||||
flvPlay(commandMessage.Param)
|
||||
case "flvFetchMoreData":
|
||||
flvFetchMoreData(commandMessage.Param)
|
||||
default:
|
||||
logs.Error("unsupport commandType: %s", commandMessage.MessageType)
|
||||
}
|
||||
}
|
||||
}
|
127
src/rtsp2rtmp/tcpclient/common.go
Normal file
127
src/rtsp2rtmp/tcpclient/common.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package tcpclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/core/config"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/utils"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/common"
|
||||
)
|
||||
|
||||
type CommandMessage struct {
|
||||
// "cameraAq" "historyVideoPage" "flvFileMediaInfo" "flvPlay" "flvFetchMoreData" "startPushRtmp" "stopPushRtmp"
|
||||
MessageType string `json:"messageType"`
|
||||
Param string `json:"param"`
|
||||
}
|
||||
|
||||
// when connect to server, first send register packet to server
|
||||
type RegisterInfo struct {
|
||||
ClientId string `json:"clientId"`
|
||||
DateStr string `json:"dateStr"`
|
||||
Sign string `json:"sign"`
|
||||
// "keepChannel" "cameraAq" "historyVideoPage" "flvFileMediaInfo" "flvPlay" "flvFetchMoreData" "startPushRtmp" "stopPushRtmp"
|
||||
ConnType string `json:"connType"`
|
||||
}
|
||||
|
||||
func newReisterInfo(connType string) (ri RegisterInfo, err error) {
|
||||
currentDateStr := time.Now().Format(time.RFC3339)
|
||||
clientId, err := config.String("server.remote.client-id")
|
||||
if err != nil {
|
||||
logs.Error("get remote client-id error: %v\n", err)
|
||||
return
|
||||
}
|
||||
signSecret, err := config.String("server.remote.sign-secret")
|
||||
if err != nil {
|
||||
logs.Error("get remote sign-secret error: %v\n", err)
|
||||
return
|
||||
}
|
||||
planText := fmt.Sprintf("cilentId=%s&dateStr=%s", clientId, currentDateStr)
|
||||
signStr, err := utils.EncryptAES([]byte(signSecret), planText)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("buildSign error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ri = RegisterInfo{
|
||||
ClientId: clientId,
|
||||
ConnType: connType,
|
||||
DateStr: currentDateStr,
|
||||
Sign: signStr,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func connectAndRegister(connType string) (conn net.Conn, err error) {
|
||||
serverIp, err := config.String("server.remote.server-ip")
|
||||
if err != nil {
|
||||
logs.Error("get remote server-ip error: %v. \n", err)
|
||||
return
|
||||
}
|
||||
port, err := config.Int("server.remote.port")
|
||||
if err != nil {
|
||||
logs.Error("get httpflv port error: %v. \n use default port : 9090", err)
|
||||
return
|
||||
}
|
||||
conn, err = net.Dial("tcp", fmt.Sprintf("%s:%d", serverIp, port))
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
conn.Close()
|
||||
}()
|
||||
|
||||
// register to server
|
||||
ri, err := newReisterInfo(connType)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
registerBodyBytes, err := json.Marshal(ri)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
registerBodyLen := len(registerBodyBytes)
|
||||
registerBodyLenBytes := utils.Int32ToByteBigEndian(int32(registerBodyLen))
|
||||
messageBytes := append(registerBodyLenBytes, registerBodyBytes...)
|
||||
_, err = conn.Write(messageBytes)
|
||||
if err != nil {
|
||||
logs.Error("register error: %v", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func writeResult(result common.AppResult, writer io.Writer) (n int, err error) {
|
||||
messageBytes, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
secretStr, err := config.String("server.remote.secret")
|
||||
if err != nil {
|
||||
logs.Error("get remote secret error: %v", err)
|
||||
return
|
||||
}
|
||||
encryptMessageStr, err := utils.EncryptAES([]byte(secretStr), string(messageBytes))
|
||||
if err != nil {
|
||||
logs.Error("EncryptAES error: %v", err)
|
||||
return
|
||||
}
|
||||
encryptMessageBytes := string(encryptMessageStr)
|
||||
encryptMessageLen := len(encryptMessageBytes)
|
||||
encryptMessageLenBytes := utils.Int32ToByteBigEndian(int32(encryptMessageLen))
|
||||
fullMessageBytes := append(encryptMessageLenBytes, encryptMessageBytes...)
|
||||
n, err = writer.Write(fullMessageBytes)
|
||||
if err != nil {
|
||||
logs.Error("register error: %v", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
98
src/rtsp2rtmp/tcpclient/flv_data_push.go
Normal file
98
src/rtsp2rtmp/tcpclient/flv_data_push.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package tcpclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/beego/beego/v2/core/config"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/flvadmin/fileflvmanager/fileflvreader"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/utils"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/common"
|
||||
base_service "github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/service/base"
|
||||
)
|
||||
|
||||
var playerMap sync.Map
|
||||
|
||||
type PlayParam struct {
|
||||
PlayerId string `json:"playerId"`
|
||||
IdCameraRecord string `json:"idCameraRecord"`
|
||||
SeekSecond uint64 `json:"seekSecond"`
|
||||
}
|
||||
|
||||
type FlvPush struct {
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
// override io.Writer
|
||||
func (flvPush FlvPush) Write(p []byte) (n int, err error) {
|
||||
messageBytes := p
|
||||
secretStr, err := config.String("server.remote.secret")
|
||||
if err != nil {
|
||||
logs.Error("get remote secret error: %v", err)
|
||||
return
|
||||
}
|
||||
encryptMessageStr, err := utils.EncryptAES([]byte(secretStr), string(messageBytes))
|
||||
if err != nil {
|
||||
logs.Error("EncryptAES error: %v", err)
|
||||
return
|
||||
}
|
||||
encryptMessageBytes := string(encryptMessageStr)
|
||||
encryptMessageLen := len(encryptMessageBytes)
|
||||
encryptMessageLenBytes := utils.Int32ToByteBigEndian(int32(encryptMessageLen))
|
||||
fullMessageBytes := append(encryptMessageLenBytes, encryptMessageBytes...)
|
||||
_, err = flvPush.conn.Write(fullMessageBytes)
|
||||
if err != nil {
|
||||
logs.Error("register error: %v", err)
|
||||
return
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func flvPlay(paramStr string) {
|
||||
playParam := PlayParam{}
|
||||
err := json.Unmarshal([]byte(paramStr), &playParam)
|
||||
if err != nil {
|
||||
logs.Error("flvPlay message format error: %v", err)
|
||||
return
|
||||
}
|
||||
conn, err := connectAndRegister("flvFileMediaInfo")
|
||||
if err != nil {
|
||||
logs.Error("flvFileMediaInfo connect to server error: %v", err)
|
||||
return
|
||||
}
|
||||
camera_record, err := base_service.CameraRecordSelectById(playParam.IdCameraRecord)
|
||||
if err != nil {
|
||||
logs.Error("CameraRecordSelectById error: %v", err)
|
||||
result := common.ErrorResult(fmt.Sprintf("idCameraRecord: %s CameraRecordSelectById error", playParam.IdCameraRecord))
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
fileName := camera_record.FileName
|
||||
if camera_record.FgTemp {
|
||||
fileName = camera_record.TempFileName
|
||||
}
|
||||
|
||||
ffr := fileflvreader.NewFileFlvReader(playParam.SeekSecond, conn, fileName)
|
||||
_, ok := playerMap.Load(playParam.PlayerId)
|
||||
if ok {
|
||||
logs.Error("playerId: %s exists", playParam.PlayerId)
|
||||
result := common.ErrorResult(fmt.Sprintf("playerId: %s exists", playParam.PlayerId))
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
playerMap.Store(playParam.PlayerId, ffr)
|
||||
<-ffr.GetDone()
|
||||
playerMap.Delete(playParam.PlayerId)
|
||||
logs.Info("vod player [%s] addr [%s] exit", fileName, conn.LocalAddr().String())
|
||||
}
|
50
src/rtsp2rtmp/tcpclient/flv_fetch_more_data.go
Normal file
50
src/rtsp2rtmp/tcpclient/flv_fetch_more_data.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package tcpclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/flvadmin/fileflvmanager/fileflvreader"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/common"
|
||||
)
|
||||
|
||||
type FetchMoreDataParam struct {
|
||||
PlayerId string `json:"playerId"`
|
||||
SeekSecond uint64 `json:"seekSecond"`
|
||||
}
|
||||
|
||||
func flvFetchMoreData(paramStr string) {
|
||||
param := FetchMoreDataParam{}
|
||||
err := json.Unmarshal([]byte(paramStr), ¶m)
|
||||
if err != nil {
|
||||
logs.Error("flvPlay message format error: %v", err)
|
||||
return
|
||||
}
|
||||
conn, err := connectAndRegister("flvFetchMoreData")
|
||||
if err != nil {
|
||||
logs.Error("flvFetchMoreData connect to server error: %v", err)
|
||||
return
|
||||
}
|
||||
value, ok := playerMap.Load(param.PlayerId)
|
||||
if !ok {
|
||||
logs.Error("playerId: %s not exists or complate", param.PlayerId)
|
||||
result := common.SuccessResultMsg(fmt.Sprintf("playerId: %s not exists or complate, skip this request", param.PlayerId))
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
loadFfr := (value.(*fileflvreader.FileFlvReader))
|
||||
loadFfr.SetSeekSecond(param.SeekSecond)
|
||||
|
||||
logs.Info("vod player [%s] fetch data, addr [%s]", param.PlayerId, conn.LocalAddr().String())
|
||||
result := common.SuccessResultMsg("fetch sccess")
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
72
src/rtsp2rtmp/tcpclient/flv_media_info.go
Normal file
72
src/rtsp2rtmp/tcpclient/flv_media_info.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package tcpclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/flvadmin/fileflvmanager/fileflvreader"
|
||||
"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"
|
||||
)
|
||||
|
||||
type FlvFileMediaInfoParam struct {
|
||||
IdCameraRecord string `json:"idCameraRecord"`
|
||||
}
|
||||
|
||||
func flvFileMediaInfo(paramStr string) {
|
||||
param := FlvFileMediaInfoParam{}
|
||||
err := json.Unmarshal([]byte(paramStr), ¶m)
|
||||
if err != nil {
|
||||
logs.Error("flvFileMediaInfo message format error: %v", err)
|
||||
return
|
||||
}
|
||||
idCameraRecord := param.IdCameraRecord
|
||||
conn, err := connectAndRegister("flvFileMediaInfo")
|
||||
if err != nil {
|
||||
logs.Error("flvFileMediaInfo connect to server error: %v", err)
|
||||
return
|
||||
}
|
||||
camera_record, err := base_service.CameraRecordSelectById(idCameraRecord)
|
||||
if err != nil {
|
||||
logs.Error("idCameraRecord: %s CameraRecordSelectById error: %v", idCameraRecord, err)
|
||||
result := common.ErrorResult(fmt.Sprintf("idCameraRecord: %s CameraRecordSelectById error", idCameraRecord))
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
mediaInfo := flv_file.FlvMediaInfo{
|
||||
Duration: camera_record.Duration,
|
||||
HasAudio: true,
|
||||
}
|
||||
|
||||
if camera_record.FgTemp {
|
||||
durationInt, err := fileflvreader.FlvDurationReadUntilErr(camera_record.TempFileName)
|
||||
mediaInfo = flv_file.FlvMediaInfo{
|
||||
Duration: uint32(durationInt),
|
||||
HasAudio: true,
|
||||
}
|
||||
if err != nil {
|
||||
logs.Error("file: %s get mediaInfo error", camera_record.TempFileName)
|
||||
result := common.ErrorResult(fmt.Sprintf("file: %s get mediaInfo error", camera_record.TempFileName))
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
result := common.SuccessResultData(mediaInfo)
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
63
src/rtsp2rtmp/tcpclient/history_video_page.go
Normal file
63
src/rtsp2rtmp/tcpclient/history_video_page.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package tcpclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/common"
|
||||
dto_convert "github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/controller/convert"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/dao/entity"
|
||||
base_service "github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/web/service/base"
|
||||
)
|
||||
|
||||
func historyVideoPage(paramStr string) {
|
||||
pageInfoInput := common.AqPageInfoInput{}
|
||||
err := json.Unmarshal([]byte(paramStr), &pageInfoInput)
|
||||
if err != nil {
|
||||
logs.Error("flvFileMediaInfo message format error: %v", err)
|
||||
return
|
||||
}
|
||||
conn, err := connectAndRegister("historyVideoPage")
|
||||
if err != nil {
|
||||
logs.Error("historyVideoPage connect to server error: %v", err)
|
||||
return
|
||||
}
|
||||
pageInfo, err := base_service.CameraRecordFindPageByCondition(pageInfoInput)
|
||||
if err != nil {
|
||||
logs.Error("aqPage error : %v", err)
|
||||
result := common.ErrorResult("CameraRecordFindPageByCondition error")
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
var cameraRecords = make([]entity.CameraRecord, 0)
|
||||
for _, data := range pageInfo.DataList {
|
||||
cameraRecords = append(cameraRecords, data.(entity.CameraRecord))
|
||||
}
|
||||
voList, err := dto_convert.ConvertCameraRecordToVOList(cameraRecords)
|
||||
if err != nil {
|
||||
logs.Error("aqPage error: %v", err)
|
||||
result := common.ErrorResult(fmt.Sprintf("ConvertCameraRecordToVOList error"))
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
var dataList = make([]interface{}, 0)
|
||||
for _, vo := range voList {
|
||||
dataList = append(dataList, vo)
|
||||
}
|
||||
pageInfo.DataList = dataList
|
||||
result := common.SuccessResultData(pageInfo)
|
||||
_, err = writeResult(result, conn)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
48
src/rtsp2rtmp/utils/aes.go
Normal file
48
src/rtsp2rtmp/utils/aes.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
func EncryptAES(key []byte, plaintext string) (string, error) {
|
||||
plainBytes := []byte(plaintext)
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// The IV needs to be unique, but does not have to be secret.
|
||||
// You can calculate it once with the key and keep it with the ciphertext.
|
||||
iv := key[:block.BlockSize()]
|
||||
|
||||
stream := cipher.NewOFB(block, iv)
|
||||
|
||||
ciphertext := make([]byte, len(plainBytes))
|
||||
stream.XORKeyStream(ciphertext, plainBytes)
|
||||
|
||||
return hex.EncodeToString(ciphertext), nil
|
||||
}
|
||||
|
||||
func DecryptAES(key []byte, ciphertext string) (string, error) {
|
||||
encrypted, err := hex.DecodeString(ciphertext)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
iv := key[:block.BlockSize()]
|
||||
|
||||
stream := cipher.NewOFB(block, iv)
|
||||
|
||||
plaintext := make([]byte, len(encrypted))
|
||||
stream.XORKeyStream(plaintext, encrypted)
|
||||
|
||||
return string(plaintext), nil
|
||||
}
|
@@ -37,6 +37,16 @@ func Float64ToByteBigEndian(float float64) []byte {
|
||||
return bytes
|
||||
}
|
||||
|
||||
func Int32ToByteBigEndian(number int32) []byte {
|
||||
bytes := make([]byte, 4)
|
||||
bytes[0] = byte(number >> (3 * 8))
|
||||
bytes[0] = byte(number >> (2 * 8))
|
||||
bytes[0] = byte(number >> (1 * 8))
|
||||
bytes[0] = byte(number)
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
func ByteToFloat64(bytes []byte) float64 {
|
||||
bits := binary.LittleEndian.Uint64(bytes)
|
||||
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/hkmadao/rtsp2rtmp/src/rtsp2rtmp/flvadmin/fileflvmanager/fileflvreader"
|
||||
"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,10 +21,10 @@ func CameraRecordFileDuration(ctx *gin.Context) {
|
||||
}
|
||||
}()
|
||||
|
||||
idCameraRecord := ctx.Query("idCameraRecord")
|
||||
if idCameraRecord == "" {
|
||||
logs.Error("get param idCameraRecord failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
idCameraRecord, ok := ctx.Params.Get("idCameraRecord")
|
||||
if !ok || idCameraRecord == "" {
|
||||
logs.Error("path param idCameraRecord is rquired")
|
||||
http.Error(ctx.Writer, "path param idCameraRecord is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -34,19 +35,25 @@ func CameraRecordFileDuration(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
duration := camera_record.Duration
|
||||
mediaInfo := flv_file.FlvMediaInfo{
|
||||
Duration: camera_record.Duration,
|
||||
HasAudio: true,
|
||||
}
|
||||
|
||||
if camera_record.FgTemp {
|
||||
durationInt, err := fileflvreader.FlvDurationReadUntilErr(camera_record.TempFileName)
|
||||
duration = uint32(durationInt)
|
||||
mediaInfo = flv_file.FlvMediaInfo{
|
||||
Duration: uint32(durationInt),
|
||||
HasAudio: true,
|
||||
}
|
||||
if err != nil {
|
||||
logs.Error("file: %s get duration error", camera_record.TempFileName)
|
||||
logs.Error("file: %s get mediaInfo error", camera_record.TempFileName)
|
||||
http.Error(ctx.Writer, "Internal Server Error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
result := common.SuccessResultData(duration)
|
||||
result := common.SuccessResultData(mediaInfo)
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
@@ -60,15 +67,15 @@ func CameraRecordFilePlay(ctx *gin.Context) {
|
||||
ctx.Writer.Header().Set("Connection", "keep-alive")
|
||||
playerId := ctx.Query("playerId")
|
||||
if playerId == "" {
|
||||
logs.Error("get param playerId failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param playerId is rquired")
|
||||
http.Error(ctx.Writer, "query param playerId is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
idCameraRecord := ctx.Query("idCameraRecord")
|
||||
if idCameraRecord == "" {
|
||||
logs.Error("get param idCameraRecord failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
idCameraRecord, ok := ctx.Params.Get("idCameraRecord")
|
||||
if !ok || idCameraRecord == "" {
|
||||
logs.Error("path param idCameraRecord is rquired")
|
||||
http.Error(ctx.Writer, "path param idCameraRecord is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -81,14 +88,14 @@ func CameraRecordFilePlay(ctx *gin.Context) {
|
||||
|
||||
seekSecond := ctx.Query("seekSecond")
|
||||
if seekSecond == "" {
|
||||
logs.Error("get param seekSecond failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param seekSecond is rquired")
|
||||
http.Error(ctx.Writer, "query param seekSecond is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
seekSecondUint, err := strconv.ParseUint(seekSecond, 10, 64)
|
||||
if err != nil {
|
||||
logs.Error("get param seekSecond failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param seekSecond need uint")
|
||||
http.Error(ctx.Writer, "query param seekSecond need uint", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -98,7 +105,7 @@ func CameraRecordFilePlay(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
ffr := fileflvreader.NewFileFlvReader(seekSecondUint, ctx.Writer, fileName)
|
||||
_, ok := playerMap.Load(playerId)
|
||||
_, ok = playerMap.Load(playerId)
|
||||
if ok {
|
||||
logs.Error("playerId: %s exists", playerId)
|
||||
http.Error(ctx.Writer, fmt.Sprintf("playerId: %s exists", playerId), http.StatusBadRequest)
|
||||
@@ -121,28 +128,29 @@ func CameraRecordFileFetch(ctx *gin.Context) {
|
||||
|
||||
playerId := ctx.Query("playerId")
|
||||
if playerId == "" {
|
||||
logs.Error("get param playerId failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param playerId failed")
|
||||
http.Error(ctx.Writer, "query param playerId is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
seekSecond := ctx.Query("seekSecond")
|
||||
if playerId == "" {
|
||||
logs.Error("get param seekSecond failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
http.Error(ctx.Writer, "query param seekSecond is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
seekSecondUint, err := strconv.ParseUint(seekSecond, 10, 64)
|
||||
if err != nil {
|
||||
logs.Error("get param seekSecond failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
http.Error(ctx.Writer, "query param seekSecond need uint", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
value, ok := playerMap.Load(playerId)
|
||||
if !ok {
|
||||
logs.Error("playerId: %s not exists", playerId)
|
||||
http.Error(ctx.Writer, fmt.Sprintf("playerId: %s not exists", playerId), http.StatusBadRequest)
|
||||
logs.Error("playerId: %s not exists or complate", playerId)
|
||||
result := common.SuccessResultMsg(fmt.Sprintf("playerId: %s not exists or complate, skip this request", playerId))
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
loadFfr := (value.(*fileflvreader.FileFlvReader))
|
||||
|
@@ -102,8 +102,8 @@ func HttpFlvVODFileDuration(ctx *gin.Context) {
|
||||
|
||||
fileName, ok := ctx.Params.Get("fileName")
|
||||
if !ok {
|
||||
logs.Error("get param fileName failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("path param fileName is rquired")
|
||||
http.Error(ctx.Writer, "path param fileName is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -133,15 +133,15 @@ func HttpFlvVODStart(ctx *gin.Context) {
|
||||
ctx.Writer.Header().Set("Connection", "keep-alive")
|
||||
fileName, ok := ctx.Params.Get("fileName")
|
||||
if !ok {
|
||||
logs.Error("get param fileName failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("path param fileName is rquired")
|
||||
http.Error(ctx.Writer, "path param fileName is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
playerId := ctx.Query("playerId")
|
||||
if playerId == "" {
|
||||
logs.Error("get param playerId failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param playerId is rquired")
|
||||
http.Error(ctx.Writer, "query param playerId is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -153,14 +153,14 @@ func HttpFlvVODStart(ctx *gin.Context) {
|
||||
|
||||
seekSecond := ctx.Query("seekSecond")
|
||||
if seekSecond == "" {
|
||||
logs.Error("get param seekSecond failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param seekSecond is rquired")
|
||||
http.Error(ctx.Writer, "query param seekSecond is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
seekSecondUint, err := strconv.ParseUint(seekSecond, 10, 64)
|
||||
if err != nil {
|
||||
logs.Error("get param seekSecond failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param seekSecond need uint")
|
||||
http.Error(ctx.Writer, "query param seekSecond need uint", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -188,28 +188,29 @@ func HttpFlvVODFetch(ctx *gin.Context) {
|
||||
|
||||
playerId := ctx.Query("playerId")
|
||||
if playerId == "" {
|
||||
logs.Error("get param playerId failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param playerId is rquired")
|
||||
http.Error(ctx.Writer, "query param playerId is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
seekSecond := ctx.Query("seekSecond")
|
||||
if playerId == "" {
|
||||
logs.Error("get param seekSecond failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param seekSecond is rquired")
|
||||
http.Error(ctx.Writer, "query param seekSecond is rquired", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
seekSecondUint, err := strconv.ParseUint(seekSecond, 10, 64)
|
||||
if err != nil {
|
||||
logs.Error("get param seekSecond failed")
|
||||
http.Error(ctx.Writer, "invalid path", http.StatusBadRequest)
|
||||
logs.Error("query param seekSecond need uint")
|
||||
http.Error(ctx.Writer, "query param seekSecond need uint", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
value, ok := playerMap.Load(playerId)
|
||||
if !ok {
|
||||
logs.Error("playerId: %s not exists", playerId)
|
||||
http.Error(ctx.Writer, fmt.Sprintf("playerId: %s not exists", playerId), http.StatusBadRequest)
|
||||
logs.Error("playerId: %s not exists or complate", playerId)
|
||||
result := common.SuccessResultMsg(fmt.Sprintf("playerId: %s not exists or complate, skip this request", playerId))
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
return
|
||||
}
|
||||
loadFfr := (value.(*fileflvreader.FileFlvReader))
|
||||
|
6
src/rtsp2rtmp/web/dto/vo/ext/flv_file/flv_media_info.go
Normal file
6
src/rtsp2rtmp/web/dto/vo/ext/flv_file/flv_media_info.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package flv_file
|
||||
|
||||
type FlvMediaInfo struct {
|
||||
Duration uint32 `json:"duration"`
|
||||
HasAudio bool `json:"hasAudio"`
|
||||
}
|
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/adapter/logs"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type DynQueryMysql struct {
|
||||
|
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/adapter/logs"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
type DynQueryPostgres struct {
|
||||
|
@@ -117,8 +117,8 @@ 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", ext_controller.CameraRecordFileDuration)
|
||||
router.GET("/cameraRecord/start", ext_controller.CameraRecordFilePlay)
|
||||
router.GET("/cameraRecord/getDuration/:idCameraRecord", ext_controller.CameraRecordFileDuration)
|
||||
router.GET("/cameraRecord/start/:idCameraRecord", ext_controller.CameraRecordFilePlay)
|
||||
router.GET("/cameraRecord/fetch", ext_controller.CameraRecordFileFetch)
|
||||
|
||||
staticPath, err := config.String("server.http.static.path")
|
||||
|
Reference in New Issue
Block a user