Skip to content

Commit e33c0f6

Browse files
committed
in progress
1 parent 7d4a2cf commit e33c0f6

File tree

2 files changed

+138
-5
lines changed

2 files changed

+138
-5
lines changed

apiHTTPRouter.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import (
1010
"github.com/sirupsen/logrus"
1111
)
1212

13-
//Message resp struct
13+
// Message resp struct
1414
type Message struct {
1515
Status int `json:"status"`
1616
Payload interface{} `json:"payload"`
1717
}
1818

19-
//HTTPAPIServer start http server routes
19+
// HTTPAPIServer start http server routes
2020
func HTTPAPIServer() {
2121
//Set HTTP API mode
2222
log.WithFields(logrus.Fields{
@@ -95,6 +95,9 @@ func HTTPAPIServer() {
9595
//HLS
9696
public.GET("/stream/:uuid/channel/:channel/hls/live/index.m3u8", HTTPAPIServerStreamHLSM3U8)
9797
public.GET("/stream/:uuid/channel/:channel/hls/live/segment/:seq/file.ts", HTTPAPIServerStreamHLSTS)
98+
//HLS remote record
99+
//public.GET("/stream/:uuid/channel/:channel/hls/rr/:s/:e/index.m3u8", HTTPAPIServerStreamRRM3U8)
100+
//public.GET("/stream/:uuid/channel/:channel/hls/rr/:s/:e/:seq/file.ts", HTTPAPIServerStreamRRTS)
98101
//HLS LL
99102
public.GET("/stream/:uuid/channel/:channel/hlsll/live/index.m3u8", HTTPAPIServerStreamHLSLLM3U8)
100103
public.GET("/stream/:uuid/channel/:channel/hlsll/live/init.mp4", HTTPAPIServerStreamHLSLLInit)
@@ -103,7 +106,8 @@ func HTTPAPIServer() {
103106
//MSE
104107
public.GET("/stream/:uuid/channel/:channel/mse", HTTPAPIServerStreamMSE)
105108
public.POST("/stream/:uuid/channel/:channel/webrtc", HTTPAPIServerStreamWebRTC)
106-
109+
//Save fragment to mp4
110+
public.GET("/stream/:uuid/channel/:channel/save/mp4/fragment/:duration", HTTPAPIServerStreamSaveToMP4)
107111
/*
108112
HTTPS Mode Cert
109113
# Key considerations for algorithm "RSA" ≥ 2048-bit
@@ -150,7 +154,7 @@ func HTTPAPIServer() {
150154

151155
}
152156

153-
//HTTPAPIServerIndex index file
157+
// HTTPAPIServerIndex index file
154158
func HTTPAPIServerIndex(c *gin.Context) {
155159
c.HTML(http.StatusOK, "index.tmpl", gin.H{
156160
"port": Storage.ServerHTTPPort(),
@@ -282,7 +286,7 @@ func HTTPAPIFullScreenMultiView(c *gin.Context) {
282286
})
283287
}
284288

285-
//CrossOrigin Access-Control-Allow-Origin any methods
289+
// CrossOrigin Access-Control-Allow-Origin any methods
286290
func CrossOrigin() gin.HandlerFunc {
287291
return func(c *gin.Context) {
288292
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")

apiHTTPSaveMP4.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/deepch/vdk/format/mp4"
6+
"github.com/gin-gonic/gin"
7+
"github.com/sirupsen/logrus"
8+
"os"
9+
"time"
10+
)
11+
12+
// HTTPAPIServerStreamSaveToMP4 func
13+
func HTTPAPIServerStreamSaveToMP4(c *gin.Context) {
14+
var err error
15+
16+
requestLogger := log.WithFields(logrus.Fields{
17+
"module": "http_save_mp4",
18+
"stream": c.Param("uuid"),
19+
"channel": c.Param("channel"),
20+
"func": "HTTPAPIServerStreamSaveToMP4",
21+
})
22+
23+
defer func() {
24+
if err != nil {
25+
requestLogger.WithFields(logrus.Fields{
26+
"call": "Close",
27+
}).Errorln(err)
28+
}
29+
}()
30+
31+
if !Storage.StreamChannelExist(c.Param("uuid"), c.Param("channel")) {
32+
requestLogger.WithFields(logrus.Fields{
33+
"call": "StreamChannelExist",
34+
}).Errorln(ErrorStreamNotFound.Error())
35+
return
36+
}
37+
38+
if !RemoteAuthorization("save", c.Param("uuid"), c.Param("channel"), c.Query("token"), c.ClientIP()) {
39+
requestLogger.WithFields(logrus.Fields{
40+
"call": "RemoteAuthorization",
41+
}).Errorln(ErrorStreamUnauthorized.Error())
42+
return
43+
}
44+
c.Writer.Write([]byte("await save started"))
45+
go func() {
46+
Storage.StreamChannelRun(c.Param("uuid"), c.Param("channel"))
47+
cid, ch, _, err := Storage.ClientAdd(c.Param("uuid"), c.Param("channel"), MSE)
48+
if err != nil {
49+
requestLogger.WithFields(logrus.Fields{
50+
"call": "ClientAdd",
51+
}).Errorln(err.Error())
52+
return
53+
}
54+
55+
defer Storage.ClientDelete(c.Param("uuid"), cid, c.Param("channel"))
56+
codecs, err := Storage.StreamChannelCodecs(c.Param("uuid"), c.Param("channel"))
57+
if err != nil {
58+
requestLogger.WithFields(logrus.Fields{
59+
"call": "StreamCodecs",
60+
}).Errorln(err.Error())
61+
return
62+
}
63+
err = os.MkdirAll(fmt.Sprintf("save/%s/%s/", c.Param("uuid"), c.Param("channel")), 0755)
64+
if err != nil {
65+
requestLogger.WithFields(logrus.Fields{
66+
"call": "MkdirAll",
67+
}).Errorln(err.Error())
68+
}
69+
f, err := os.Create(fmt.Sprintf("save/%s/%s/%s.mp4", c.Param("uuid"), c.Param("channel"), time.Now().String()))
70+
if err != nil {
71+
requestLogger.WithFields(logrus.Fields{
72+
"call": "Create",
73+
}).Errorln(err.Error())
74+
}
75+
defer f.Close()
76+
77+
muxer := mp4.NewMuxer(f)
78+
err = muxer.WriteHeader(codecs)
79+
if err != nil {
80+
requestLogger.WithFields(logrus.Fields{
81+
"call": "WriteHeader",
82+
}).Errorln(err.Error())
83+
return
84+
}
85+
defer muxer.WriteTrailer()
86+
87+
var videoStart bool
88+
controlExit := make(chan bool, 10)
89+
dur, err := time.ParseDuration(c.Param("duration"))
90+
if err != nil {
91+
requestLogger.WithFields(logrus.Fields{
92+
"call": "ParseDuration",
93+
}).Errorln(err.Error())
94+
}
95+
saveLimit := time.NewTimer(dur)
96+
noVideo := time.NewTimer(10 * time.Second)
97+
defer log.Println("client exit")
98+
for {
99+
select {
100+
case <-controlExit:
101+
requestLogger.WithFields(logrus.Fields{
102+
"call": "controlExit",
103+
}).Errorln("Client Reader Exit")
104+
return
105+
case <-saveLimit.C:
106+
requestLogger.WithFields(logrus.Fields{
107+
"call": "saveLimit",
108+
}).Errorln("Saved Limit End")
109+
return
110+
case <-noVideo.C:
111+
requestLogger.WithFields(logrus.Fields{
112+
"call": "ErrorStreamNoVideo",
113+
}).Errorln(ErrorStreamNoVideo.Error())
114+
return
115+
case pck := <-ch:
116+
if pck.IsKeyFrame {
117+
noVideo.Reset(10 * time.Second)
118+
videoStart = true
119+
}
120+
if !videoStart {
121+
continue
122+
}
123+
if err = muxer.WritePacket(*pck); err != nil {
124+
return
125+
}
126+
}
127+
}
128+
}()
129+
}

0 commit comments

Comments
 (0)