]> 127.0.0.1 Git - bili_danmu/.git/commitdiff
Improve 添加分段加载回放支持
authorqydysky <qydysky@foxmail.com>
Tue, 15 Aug 2023 16:21:42 +0000 (00:21 +0800)
committerqydysky <qydysky@foxmail.com>
Tue, 15 Aug 2023 16:21:42 +0000 (00:21 +0800)
Reply/F.go
go.mod
go.sum

index 2b8898b95467ef73692e29dcf66f00d32cd13c4e..bab7297bbf5f8f4715bf994abd4e2c8710f19e43 100644 (file)
@@ -1385,7 +1385,7 @@ func init() {
                        //header
                        w.Header().Set("Access-Control-Allow-Credentials", "true")
                        w.Header().Set("Access-Control-Allow-Headers", "*")
-                       w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
+                       w.Header().Set("Access-Control-Allow-Methods", "GET")
                        w.Header().Set("Access-Control-Allow-Origin", "*")
                        w.Header().Set("Connection", "keep-alive")
                        w.Header().Set("Content-Transfer-Encoding", "binary")
@@ -1404,7 +1404,12 @@ func init() {
                        }
 
                        if rpath != `/now/` {
-                               if v, ok := c.C.K_v.LoadV(`直播流保存位置`).(string); ok && v != "" {
+                               if v, ok := c.C.K_v.LoadV(`直播流保存位置`).(string); !ok || v == "" {
+                                       w.Header().Set("Retry-After", "1")
+                                       w.WriteHeader(http.StatusServiceUnavailable)
+                                       flog.L(`W: `, `直播流保存位置无效`)
+                                       return
+                               } else {
                                        if strings.HasSuffix(v, "/") || strings.HasSuffix(v, "\\") {
                                                v += rpath[1:]
                                        } else {
@@ -1419,8 +1424,10 @@ func init() {
                                        }
                                        if file.New(v+"0.flv", 0, true).IsExist() {
                                                v += "0.flv"
+                                               w.Header().Set("Content-Type", "flv-application/octet-stream")
                                        } else if file.New(v+"0.mp4", 0, true).IsExist() {
                                                v += "0.mp4"
+                                               w.Header().Set("Content-Type", "video/mp4")
                                        } else {
                                                w.Header().Set("Retry-After", "1")
                                                w.WriteHeader(http.StatusServiceUnavailable)
@@ -1428,9 +1435,10 @@ func init() {
                                                return
                                        }
 
+                                       // 读取区间
                                        var rangeHeaderNum int
-                                       var e error
                                        if rangeHeader := r.Header.Get(`range`); rangeHeader != "" {
+                                               var e error
                                                if strings.Index(rangeHeader, "bytes=") != 0 {
                                                        w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
                                                        flog.L(`W: `, `请求的范围不合法:仅支持bytes`)
@@ -1443,37 +1451,42 @@ func init() {
                                                        w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
                                                        flog.L(`W: `, `请求的范围不合法:`, e)
                                                        return
-                                               } else if rangeHeaderNum != 0 {
-                                                       w.WriteHeader(http.StatusPartialContent)
                                                }
                                        }
 
-                                       f := file.New(v, int64(rangeHeaderNum), false)
-                                       defer f.Close()
-
                                        // 直播流回放速率
                                        var speed, _ = humanize.ParseBytes("1 M")
                                        if rc, ok := c.C.K_v.LoadV(`直播流回放速率`).(string); ok {
                                                if s, e := humanize.ParseBytes(rc); e != nil {
+                                                       w.WriteHeader(http.StatusServiceUnavailable)
                                                        flog.L(`W: `, `直播流回放速率不合法:`, e)
+                                                       return
                                                } else {
                                                        speed = s
                                                }
                                        }
 
-                                       go func() {
-                                               flog.L(`T: `, r.RemoteAddr, `接入录播`, v)
-                                               <-r.Context().Done()
-                                               flog.L(`T: `, r.RemoteAddr, `断开录播`, v)
-                                       }()
+                                       f := file.New(v, int64(rangeHeaderNum), false)
+                                       defer f.Close()
 
-                                       if e := f.CopyToIoWriter(w, int64(speed), true); e != nil {
-                                               flog.L(`E: `, e)
+                                       // 设置当前返回区间,并拷贝
+                                       if fi, e := f.Stat(); e != nil {
+                                               w.WriteHeader(http.StatusServiceUnavailable)
+                                               flog.L(`W: `, e)
+                                               return
+                                       } else {
+                                               var totalSec int64 = 10
+                                               allSize := fi.Size()
+                                               targetC := int64(rangeHeaderNum) + int64(speed)*totalSec
+                                               if allSize < targetC {
+                                                       targetC = allSize
+                                               }
+                                               w.Header().Add(`Content-Range`, fmt.Sprintf("bytes %d-%d/%d", rangeHeaderNum, targetC, allSize))
+                                               w.WriteHeader(http.StatusPartialContent)
+                                               if e := f.CopyToIoWriterUntil(pweb.WithFlush(w), int64(speed), totalSec, true); e != nil {
+                                                       flog.L(`E: `, e)
+                                               }
                                        }
-                               } else {
-                                       w.Header().Set("Retry-After", "1")
-                                       w.WriteHeader(http.StatusServiceUnavailable)
-                                       flog.L(`W: `, `直播流保存位置无效`)
                                }
                                return
                        }
diff --git a/go.mod b/go.mod
index 5a38f5af5ed6d84e2b97df3f38e22e7045c0b2fd..b52800db2fe3a701887be3e181c8ead3687f7d2a 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.21
 require (
        github.com/gotk3/gotk3 v0.6.2
        github.com/mdp/qrterminal/v3 v3.1.1
-       github.com/qydysky/part v0.28.1-0.20230814074040-f9bfda2de89e
+       github.com/qydysky/part v0.28.1-0.20230815161426-479a1258c761
        github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
        github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
        golang.org/x/text v0.12.0
diff --git a/go.sum b/go.sum
index 09246f308c6504da6c958e2488310b6cb760eca0..6cb9167d0855c9f32f7b2e1610382318c84728f3 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -34,8 +34,8 @@ github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
 github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/qydysky/part v0.28.1-0.20230814074040-f9bfda2de89e h1:6/63PfGwQgzF+jDBVBUiiejRuORWqVsdc/HvN08FE0M=
-github.com/qydysky/part v0.28.1-0.20230814074040-f9bfda2de89e/go.mod h1:iOK6EzUOqdqTyQZm+pf1qxYpKvLmdK+YHZehNN/2J3U=
+github.com/qydysky/part v0.28.1-0.20230815161426-479a1258c761 h1:QF8corbhIb+PtiD0cBab/ejZBI8aflPKpEIK9NhHCyM=
+github.com/qydysky/part v0.28.1-0.20230815161426-479a1258c761/go.mod h1:iOK6EzUOqdqTyQZm+pf1qxYpKvLmdK+YHZehNN/2J3U=
 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
 github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=