-
Notifications
You must be signed in to change notification settings - Fork 0
/
http.go
121 lines (107 loc) · 2.79 KB
/
http.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package main
import (
"log"
"net/http"
"time"
webrtc "github.com/deepch/vdk/format/webrtcv3"
"github.com/gin-gonic/gin"
)
type JCodec struct {
Type string
}
func serveHTTP() {
gin.SetMode(gin.ReleaseMode)
router := gin.Default()
router.OPTIONS("/"+Config.Server.AuthToken, CORSMiddleware())
router.POST("/"+Config.Server.AuthToken, CORSMiddleware(), HTTPAPIServerStreamWebRTC)
var err error
if Config.Server.UseTLS {
err = router.RunTLS(Config.Server.HTTPPort, Config.Server.TLSCert, Config.Server.TLSKey)
} else {
err = router.Run(Config.Server.HTTPPort)
}
if err != nil {
log.Fatalln("Start HTTP Server error", err)
}
}
func HTTPAPIServerStreamWebRTC(c *gin.Context) {
uuid := "H264"
if !Config.ext(uuid) {
log.Println("Stream Not Found")
return
}
Config.RunIFNotRun(uuid)
codecs := Config.coGe(uuid)
if codecs == nil {
log.Println("Stream Codec Not Found")
return
}
var AudioOnly bool
if len(codecs) == 1 && codecs[0].Type().IsAudio() {
AudioOnly = true
}
muxerWebRTC := webrtc.NewMuxer(webrtc.Options{ICEServers: Config.GetICEServers(), ICEUsername: Config.GetICEUsername(), ICECredential: Config.GetICECredential(), PortMin: Config.GetWebRTCPortMin(), PortMax: Config.GetWebRTCPortMax()})
answer, err := muxerWebRTC.WriteHeader(codecs, c.PostForm("data"))
if err != nil {
log.Println("WriteHeader", err)
return
}
_, err = c.Writer.Write([]byte(answer))
if err != nil {
log.Println("Write", err)
return
}
go func() {
cid, ch := Config.clAd(uuid)
defer Config.clDe(uuid, cid)
defer muxerWebRTC.Close()
var videoStart bool
noVideo := time.NewTimer(10 * time.Second)
for {
select {
case <-noVideo.C:
log.Println("noVideo")
return
case pck := <-ch:
if pck.IsKeyFrame || AudioOnly {
noVideo.Reset(10 * time.Second)
videoStart = true
}
if !videoStart && !AudioOnly {
continue
}
err = muxerWebRTC.WritePacket(pck)
if err != nil {
log.Println("WritePacket", err)
return
}
}
}
}()
}
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
host := c.Request.Header.Get("Origin")
if Config.Server.Host != host {
c.Next()
return
}
c.Header("Access-Control-Allow-Origin", host)
c.Header("Access-Control-Allow-Credentials", "true")
c.Header("Access-Control-Allow-Headers", "Content-Type")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
c.Header("Access-Control-Allow-Methods", "POST, OPTIONS")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Next()
}
}
type Response struct {
Tracks []string `json:"tracks"`
Sdp64 string `json:"sdp64"`
}
type ResponseError struct {
Error string `json:"error"`
}