]> 127.0.0.1 Git - bili_danmu/.git/commitdiff
Add 指定房间录制区间
authorqydysky <qydysky@foxmail.com>
Sat, 18 Nov 2023 04:29:14 +0000 (12:29 +0800)
committerqydysky <qydysky@foxmail.com>
Sat, 18 Nov 2023 04:29:14 +0000 (12:29 +0800)
18 files changed:
README.md
Reply/F.go
Reply/F/comp.go
Reply/F/danmuXml/danmuXml.go
Reply/F/fmp4Tomp4/fmp4Tomp4.go [deleted file]
Reply/F/fmp4Tomp4/fmp4Tomp4_test.go [deleted file]
Reply/F/fmp4Tomp4/reader.go [deleted file]
Reply/F/fmp4Tomp4/reader_test.go [deleted file]
Reply/F/fmp4Tomp4/writer.go [deleted file]
Reply/F/fmp4Tomp4/writer_test.go [deleted file]
Reply/F/liveOver/liveOver.go
Reply/F/reSetMp4TimeStamp/reSetMp4TimeStamp.go [deleted file]
Reply/F/recStartEnd/recStartEnd.go [new file with mode: 0644]
Reply/Reply.go
bili_danmu.go
demo/config/config_K_v.json
go.mod
go.sum

index a3de1c107767f4054ea657bef172761be2abb662..e09f23632c3086ecf76a167a6ad29b79c39c0671 100644 (file)
--- a/README.md
+++ b/README.md
 ### 说明
 本项目使用github action自动构建,构建过程详见[yml](https://github.com/qydysky/bili_danmu/blob/master/.github/workflows/go.yml)
 
+#### 指定房间录制区间
+配置文件中添加配置项`指定房间录制区间`。
+
+指定roomid的房间在指定时间段内将会开启录制。
+- `start`时检查是否在直播,是则开始录制,如已在录制则切片。
+- `end`时如已在录制则停止录制。
+- 在开播时,若在`start`与`end`之间,则录制,不在则不录制(仅检查同时有`start`,`end`的`fromTo`)。
+- 5s内只能触发一个`fromTo`,所以同房间各`start`、`end`之间间隔不要少于5s。
+
+```json
+{
+  "指定房间录制区间":[
+      {
+          "roomid":0,
+          "fromTo":[
+              {
+                  "start": "12:01:00",
+                  "end": "12:03:00"
+              },
+              {
+                  "start": "12:02:00"
+              }
+          ]
+      }
+  ]
+}
+```
+
 #### 保存日志至DB
 配置文件中添加配置项`保存日志至db`。大部分可以参考保存弹幕至db,但有些许不同:
 
index 4bedb3abf6b58db09456d4d429bbbd38ac55752e..0d62204dd22f422d4a2031ece8a9fbd62eeb6b01 100644 (file)
@@ -33,10 +33,10 @@ import (
        c "github.com/qydysky/bili_danmu/CV"
        F "github.com/qydysky/bili_danmu/F"
        _ "github.com/qydysky/bili_danmu/Reply/F"
+       "github.com/qydysky/bili_danmu/Reply/F/danmuXml"
        send "github.com/qydysky/bili_danmu/Send"
 
        p "github.com/qydysky/part"
-       comp "github.com/qydysky/part/component"
        pctx "github.com/qydysky/part/ctx"
        file "github.com/qydysky/part/file"
        pio "github.com/qydysky/part/io"
@@ -1576,7 +1576,7 @@ func init() {
                                                return
                                        } else if !file.New(v+"0.xml", 0, true).IsExist() {
                                                type empty struct{}
-                                               if e := comp.Run(comp.Sign[empty](`SerF`, `player`, `ws`), context.Background(), &v); e != nil {
+                                               if e := danmuXml.DanmuXml.Run(context.Background(), &v); e != nil {
                                                        msglog.L(`E: `, e)
                                                }
                                        }
@@ -1665,7 +1665,7 @@ func init() {
                                        }
 
                                        type empty struct{}
-                                       if e := comp.Run(comp.Sign[empty](`SerF`, `player`, `xml`), context.Background(), &v); e != nil {
+                                       if e := danmuXml.DanmuXml.Run(context.Background(), &v); e != nil {
                                                msglog.L(`E: `, e)
                                        }
                                }
@@ -1705,8 +1705,8 @@ func StartRecDanmu(ctx context.Context, filePath string) {
 
        // 弹幕录制结束
        type empty struct{}
-       if e := comp.Run[string](comp.Sign[empty](`startRecDanmu`, `stop`), context.Background(), &filePath); e != nil {
-               f.L(`E: `, e)
+       if e := danmuXml.DanmuXml.Run(context.Background(), &filePath); e != nil {
+               msglog.L(`E: `, e)
        }
 
        Recoder.Stop()
index 39cf657ee3ac0a6718a168643c59365c61b5842b..05df26984420af0cc5842fb68a1cdd156bddb53e 100644 (file)
@@ -1,30 +1 @@
 package f
-
-import (
-       "github.com/qydysky/bili_danmu/Reply/F/danmuXml"
-       "github.com/qydysky/bili_danmu/Reply/F/liveOver"
-       "github.com/qydysky/bili_danmu/Reply/F/reSetMp4TimeStamp"
-       comp "github.com/qydysky/part/component"
-)
-
-func init() {
-       var linkMap = map[string][]string{
-               "github.com/qydysky/bili_danmu/Reply.startRecDanmu.stop": {
-                       comp.Sign[danmuXml.Sign](`toXml`),
-                       comp.Sign[reSetMp4TimeStamp.Sign](`_resetTS`),
-                       // comp.Sign[fmp4Tomp4.Sign](`conver`),
-               },
-               "github.com/qydysky/bili_danmu/Reply.SerF.player.ws": {
-                       comp.Sign[danmuXml.Sign](`toXml`),
-               },
-               "github.com/qydysky/bili_danmu/Reply.SerF.player.xml": {
-                       comp.Sign[danmuXml.Sign](`toXml`),
-               },
-               "github.com/qydysky/bili_danmu/Reply.preparing": {
-                       comp.Sign[liveOver.Sign](`sumup`),
-               },
-       }
-       if e := comp.Link(linkMap); e != nil {
-               panic(e)
-       }
-}
index 5e5a12d5c090924ed614d0cdf23fb1f2a09e45c6..f1025b947568dbd1f8e0228102a5a9d853bd6b6f 100644 (file)
@@ -13,19 +13,8 @@ import (
        file "github.com/qydysky/part/file"
 )
 
-type Sign struct {
-       // path: csv所在目录,末尾无
-       toXml func(ctx context.Context, path *string) error
-}
-
-func init() {
-       sign := Sign{
-               toXml: toXml,
-       }
-       if e := comp.Put[string](comp.Sign[Sign](`toXml`), sign.toXml); e != nil {
-               panic(e)
-       }
-}
+// path
+var DanmuXml = comp.NewComp(toXml)
 
 type danmu struct {
        XMLName    xml.Name `xml:"i"`
diff --git a/Reply/F/fmp4Tomp4/fmp4Tomp4.go b/Reply/F/fmp4Tomp4/fmp4Tomp4.go
deleted file mode 100644 (file)
index 0c15fa5..0000000
+++ /dev/null
@@ -1,601 +0,0 @@
-package fmp4Tomp4
-
-import (
-       "bytes"
-       "context"
-       "errors"
-       "fmt"
-       "time"
-
-       comp "github.com/qydysky/part/component"
-       file "github.com/qydysky/part/file"
-)
-
-// 直接保存下来的mp4在chrome上无法直接播放
-//
-// https://serverfault.com/questions/738881/chrome-makes-way-too-many-requests-22000-while-downloading-mp4-video-34mb
-type Sign struct {
-       // 重设mp4的时间戳
-       conver func(ctx context.Context, ptr *string) error
-}
-
-func init() {
-       sign := Sign{
-               conver: conver,
-       }
-       if e := comp.Put[string](comp.Sign[Sign](`conver`), sign.conver); e != nil {
-               panic(e)
-       }
-}
-
-var (
-       ErrParse = errors.New("ErrParse")
-)
-
-func conver(ctx context.Context, ptr *string) error {
-       be := time.Now()
-       fmt.Println("conver")
-       defer func() { fmt.Printf("conver fin (%v)\n", time.Since(be)) }()
-
-       sf := file.New(*ptr+"0.mp4", 0, false)
-       if !sf.IsExist() {
-               return nil
-       }
-       defer sf.Close()
-
-       r, _ := NewReader(sf)
-       if e := r.Parse(); e != nil || len(r.Boxs) == 0 {
-               return e
-       }
-       traks, e := r.ParseTrun()
-       if e != nil {
-               return e
-       }
-       fmt.Printf("conver parse ok (%v)\n", time.Since(be))
-
-       boxReader := r.Read(r.getN("mvhd", 1)[0], 30)
-       timescale := boxReader.I32(20)
-       scaleDur := boxReader.I32(24)
-       mainDuration := float64(scaleDur) / float64(timescale)
-
-       tf := file.New(*ptr+"1.mp4", 0, false)
-       if tf.IsExist() {
-               _ = tf.Delete()
-       }
-       defer tf.Close()
-
-       w, e := NewBoxWriter(tf)
-       if e != nil {
-               return e
-       }
-
-       // ftyp
-       {
-               ftyp := w.Box("ftyp")
-               ftyp.Write([]byte("isom"))
-               ftyp.Write(itob32(512))
-               ftyp.Write([]byte("isom"))
-               ftyp.Write([]byte("iso2"))
-               ftyp.Write([]byte("avc1"))
-               ftyp.Write([]byte("mp41"))
-               if e := ftyp.Close(); e != nil {
-                       return e
-               }
-       }
-
-       // moov
-       {
-               moov := w.Box("moov")
-               // mvhd
-               {
-                       mvhd := moov.Box("mvhd")
-                       mvhd.Write(make([]byte, 12))
-                       mvhd.Write(itob32(1000))
-                       mvhd.Write(itob32(int32(mainDuration * 1000)))
-                       mvhd.Write(r.Read(r.getN("mvhd", 1)[0], -1).Buf[28:])
-                       if e := mvhd.Close(); e != nil {
-                               return e
-                       }
-               }
-               // trak
-               var trakCount = -1
-               for trakId, trakSum := range traks {
-                       fmt.Printf("conver traks (%v)(%v)\n", trakId, time.Since(be))
-
-                       trakCount++
-                       trak := moov.Box("trak")
-                       // tkhd
-                       {
-                               if boxs := r.getN("trak", 2); len(boxs) != 2 {
-                                       return errors.Join(ErrParse, fmt.Errorf("trak"))
-                               } else {
-                                       tkhd := trak.Box("tkhd")
-                                       tkhd.Write([]byte{0, 0, 0, 3})
-                                       tkhd.Write(make([]byte, 8))
-                                       tkhd.Write(itob32(trakId))
-                                       tkhd.Write(make([]byte, 4))
-                                       tkhd.Write(itob32(int32(mainDuration * 1000)))
-                                       tkhd.Write(r.Read(boxs[trakCount], -1).Buf[32:])
-                                       if e := tkhd.Close(); e != nil {
-                                               return e
-                                       }
-                               }
-                       }
-                       // mdia
-                       {
-                               mdia := trak.Box("mdia")
-                               // mdhd
-                               {
-                                       if boxs := r.getN("mdhd", 2); len(boxs) != 2 {
-                                               return errors.Join(ErrParse, fmt.Errorf("mdhd"))
-                                       } else {
-                                               mdhd := mdia.Box("mdhd")
-                                               mdhd.Write(r.Read(boxs[trakCount], -1).Buf)
-                                               if e := mdhd.Close(); e != nil {
-                                                       return e
-                                               }
-                                       }
-                               }
-                               // hdlr
-                               var handlerType = make([]byte, 4)
-                               {
-                                       if boxs := r.getN("hdlr", 2); len(boxs) != 2 {
-                                               return errors.Join(ErrParse, fmt.Errorf("hdlr"))
-                                       } else {
-                                               hdlr := mdia.Box("hdlr")
-                                               boxReader := r.Read(boxs[trakCount], -1)
-                                               copy(handlerType, boxReader.Buf[16:20])
-                                               hdlr.Write(boxReader.Buf)
-                                               if e := hdlr.Close(); e != nil {
-                                                       return e
-                                               }
-                                       }
-                               }
-                               // minf
-                               {
-                                       minf := mdia.Box("minf")
-                                       // vmhd
-                                       if bytes.Equal(handlerType, []byte("vide")) {
-                                               if boxs := r.getN("vmhd", 1); len(boxs) != 1 {
-                                                       return errors.Join(ErrParse, fmt.Errorf("vmhd"))
-                                               } else {
-                                                       vmhd := minf.Box("vmhd")
-                                                       vmhd.Write(r.Read(boxs[0], -1).Buf)
-                                                       if e := vmhd.Close(); e != nil {
-                                                               return e
-                                                       }
-                                               }
-                                       }
-                                       // dinf
-                                       {
-                                               if boxs := r.getN("dinf", 2); len(boxs) != 2 {
-                                                       return errors.Join(ErrParse, fmt.Errorf("dinf"))
-                                               } else {
-                                                       dinf := minf.Box("dinf")
-                                                       dinf.Write(r.Read(boxs[trakCount], -1).Buf)
-                                                       if e := dinf.Close(); e != nil {
-                                                               return e
-                                                       }
-                                               }
-                                       }
-                                       // stbl
-                                       {
-                                               stbl := minf.Box("stbl")
-                                               // stsd
-                                               {
-                                                       if boxs := r.getN("stsd", 2); len(boxs) != 2 {
-                                                               return errors.Join(ErrParse, fmt.Errorf("stsd"))
-                                                       } else {
-                                                               stsd := stbl.Box("stsd")
-                                                               stsd.Write(r.Read(boxs[trakCount], -1).Buf)
-                                                               if e := stsd.Close(); e != nil {
-                                                                       return e
-                                                               }
-                                                       }
-                                               }
-                                               // stts
-                                               {
-                                                       stts := stbl.Box("stts")
-                                                       stts.Write([]byte{0, 0, 0, 0})
-                                                       stts.Write(itob32(int32(len(trakSum.dur))))
-                                                       for k, v := range trakSum.dur {
-                                                               stts.Write(itob32(int32(k)))
-                                                               stts.Write(itob32(v))
-                                                       }
-                                                       if e := stts.Close(); e != nil {
-                                                               return e
-                                                       }
-                                               }
-                                               // stsc
-                                               {
-                                                       stsc := stbl.Box("stsc")
-                                                       stsc.Write([]byte{0, 0, 0, 0})
-                                                       stsc.Write(itob32(int32(len(trakSum.sampleCount))))
-                                                       for k, v := range trakSum.sampleCount {
-                                                               stsc.Write(itob32(int32(k)))
-                                                               stsc.Write(itob32(v))
-                                                               stsc.Write([]byte{0, 0, 0, 1})
-                                                       }
-                                                       if e := stsc.Close(); e != nil {
-                                                               return e
-                                                       }
-                                               }
-                                               // stsz
-                                               {
-                                                       stsz := stbl.Box("stsz")
-                                                       stsz.Write([]byte{0, 0, 0, 0})
-                                                       stsz.Write(itob32(int32(len(trakSum.size))))
-                                                       for _, v := range trakSum.size {
-                                                               stsz.Write(itob32(v))
-                                                       }
-                                                       if e := stsz.Close(); e != nil {
-                                                               return e
-                                                       }
-                                               }
-                                               // co64
-                                               {
-                                                       co64 := stbl.Box("co64")
-                                                       co64.Write([]byte{0, 0, 0, 0})
-                                                       co64.Write(itob32(int32(len(trakSum.chunkSize))))
-
-                                                       cuIndex, _ := tf.CurIndex()
-                                                       cuIndex += int64(8*len(trakSum.chunkSize)) + 8
-
-                                                       co64.Write(itob64(cuIndex))
-                                                       for i := 0; i < len(trakSum.chunkSize)-1; i++ {
-                                                               co64.Write(itob64(cuIndex + trakSum.chunkSize[i]))
-                                                       }
-                                                       if e := co64.Close(); e != nil {
-                                                               return e
-                                                       }
-                                               }
-                                               if e := stbl.Close(); e != nil {
-                                                       return e
-                                               }
-                                       }
-                                       if e := minf.Close(); e != nil {
-                                               return e
-                                       }
-                               }
-                               if e := mdia.Close(); e != nil {
-                                       return e
-                               }
-                       }
-                       if e := trak.Close(); e != nil {
-                               return e
-                       }
-               }
-               if e := moov.Close(); e != nil {
-                       return e
-               }
-               fmt.Printf("conver moov fin (%v)\n", time.Since(be))
-       }
-
-       // mdat
-       {
-               mdat := w.Box("mdat")
-               for i := 0; i < len(r.Boxs); i++ {
-                       box := r.Boxs[i]
-                       if box.Name == "mdat" {
-                               if e := sf.SeekIndex(box.Index+box.HeaderSize, file.AtOrigin); e != nil {
-                                       return e
-                               }
-                               mdat.CopyFrom(sf, uint64(box.Size-box.HeaderSize))
-                       }
-               }
-               if e := mdat.Close(); e != nil {
-                       return e
-               }
-       }
-       return nil
-}
-
-// func bufChange(buf []byte, size int) {
-//     if n := size - len(buf); n > 0 {
-//             if size <= cap(buf) {
-//                     buf = buf[:size]
-//             } else {
-//                     buf = append(buf, make([]byte, n)...)
-//             }
-//     } else if n < 0 {
-//             buf = buf[:size]
-//     }
-//     clear(buf)
-// }
-
-// type track struct {
-//     chunkSize   []int64
-//     sampleCount []int32
-//     dur         []int32
-//     size        []int32
-// }
-
-// type wt struct {
-//     sf  *reader
-//     f   *file.File
-//     buf []byte
-//     m   map[string]float64
-// }
-
-// func NewWt(sf *reader, tf *file.File) *wt {
-//     return &wt{
-//             sf:  sf,
-//             f:   tf,
-//             buf: make([]byte, 1<<20),
-//             m:   make(map[string]float64),
-//     }
-// }
-
-// func (t *wt) start(boxName string, wrongPanic bool) (wSize int) {
-//     if _, e := t.f.Write([]byte{0, 0, 0, 1}, false); e != nil {
-//             panic(e)
-//     }
-//     if _, e := t.f.Write([]byte(boxName), false); e != nil {
-//             panic(e)
-//     }
-//     if _, e := t.f.Write(make([]byte, 8), false); e != nil {
-//             panic(e)
-//     }
-//     wSize = 16
-//     return
-// }
-
-// func (t *wt) skipt(size int) (n int) {
-//     if size == 0 {
-//             return
-//     }
-//     t.bufChange(size)
-//     if n, e := io.Writer(t.f.File()).Write(t.buf); e != nil {
-//             panic(e)
-//     } else {
-//             return n
-//     }
-// }
-
-// func (t *wt) skips(size int64) (n int64) {
-//     if size == 0 {
-//             return
-//     }
-//     if e := t.sf.f.SeekIndex(size, file.AtCurrent); e != nil {
-//             panic(e)
-//     }
-//     return size
-// }
-
-// func (t *wt) w(p []byte) (n int) {
-//     if n, e := t.f.Write(p, false); e != nil {
-//             panic(e)
-//     } else {
-//             return n
-//     }
-// }
-
-// func (t *wt) r(size int) (n int64) {
-//     t.bufChange(size)
-//     if n, e := t.sf.f.Read(t.buf); e != nil {
-//             panic(e)
-//     } else {
-//             return int64(n)
-//     }
-// }
-
-// func (t *wt) bufChange(size int) {
-//     if n := size - len(t.buf); n > 0 {
-//             if size <= cap(t.buf) {
-//                     t.buf = t.buf[:size]
-//             } else {
-//                     t.buf = append(t.buf, make([]byte, n)...)
-//             }
-//     } else if n < 0 {
-//             t.buf = t.buf[:size]
-//     }
-//     clear(t.buf)
-// }
-
-// func (t *wt) fin(size int) int {
-//     if e := t.f.SeekIndex(-int64(size), file.AtCurrent); e != nil {
-//             panic(e)
-//     }
-//     if e := t.f.SeekIndex(8, file.AtCurrent); e != nil {
-//             panic(e)
-//     }
-//     if _, e := t.f.Write(itob64(int64(size)), false); e != nil {
-//             panic(e)
-//     }
-//     if e := t.f.SeekIndex(int64(size-16), file.AtCurrent); e != nil {
-//             panic(e)
-//     }
-//     return size
-// }
-
-// func (t *wt) copyBox(boxName string) int {
-//     wSize := t.start(boxName, true)
-//     t.r(int(lSize))
-//     wSize += t.w(t.buf)
-//     return t.fin(wSize)
-// }
-
-// func (t *wt) ftyp() {
-//     n := t.start("ftyp", true)
-//     n += t.w([]byte("isom"))
-//     n += t.w(itob32(512))
-//     n += t.w([]byte("isom"))
-//     n += t.w([]byte("iso2"))
-//     n += t.w([]byte("avc1"))
-//     n += t.w([]byte("mp41"))
-//     t.fin(n)
-// }
-
-// func (t *wt) moov() {
-//     n, _ := t.start("moov", true)
-//     n += t.mvhd()
-//     n += t.trak()
-//     t.fin(n)
-// }
-
-// func (t *wt) mvhd() int {
-//     wSize, lSize := t.start("mvhd", true)
-//     lSize -= t.skips(12)
-//     lSize -= t.r(4)
-//     timescale := btoi32(t.buf, 0)
-//     lSize -= t.r(4)
-//     duration := btoi32(t.buf, 0)
-//     t.m["mainDuration"] = float64(duration) / float64(timescale)
-//     wSize += t.skipt(12)
-//     wSize += t.w(itob32(1000))
-//     wSize += t.w(itob32(timescale * duration / 1000))
-//     lSize -= t.r(56)
-//     wSize += t.w(t.buf)
-//     t.skips(lSize)
-//     return t.fin(wSize)
-// }
-
-// func (t *wt) trak() int {
-//     wSize, _ := t.start("trak", false)
-//     if wSize == 0 {
-//             return 0
-//     }
-
-//     wSize += t.tkhd()
-//     wSize += t.mdia()
-
-//     return t.fin(wSize)
-// }
-
-// func (t *wt) tkhd() int {
-//     wSize, lSize := t.start("mvhd", true)
-//     lSize -= t.r(12)
-//     wSize += t.w(t.buf)
-//     lSize -= t.r(4)
-//     wSize += t.w(t.buf)
-//     wSize += t.skipt(4)
-//     wSize += t.w(itob32(int32(t.m["mainDuration"] / 1000)))
-//     wSize += t.skipt(10)
-//     lSize -= t.skips(18)
-//     lSize -= t.r(52)
-//     wSize += t.w(t.buf)
-//     t.skips(lSize)
-//     return t.fin(wSize)
-// }
-
-// func (t *wt) mdia() int {
-//     wSize, _ := t.start("mdia", false)
-//     if wSize == 0 {
-//             return 0
-//     }
-
-//     wSize += t.mdhd()
-//     wSize += t.copyBox(`hdlr`)
-//     wSize += t.minf()
-
-//     return t.fin(wSize)
-// }
-
-// func (t *wt) mdhd() int {
-//     wSize, lSize := t.start("mdhd", true)
-//     lSize -= t.r(16)
-//     wSize += t.w(t.buf)
-//     lSize -= t.skips(8)
-//     wSize += t.w(itob32(1000))
-//     wSize += t.w(itob32(int32(t.m["mainDuration"] / 1000)))
-//     lSize -= t.r(4)
-//     wSize += t.w(t.buf)
-//     t.skips(lSize)
-//     return t.fin(wSize)
-// }
-
-// func (t *wt) minf() int {
-//     wSize, _ := t.start("mdia", false)
-//     if wSize == 0 {
-//             return 0
-//     }
-
-//     wSize += t.copyBox(`vmhd`)
-//     wSize += t.copyBox(`dinf`)
-//     wSize += t.stbl()
-
-//     return t.fin(wSize)
-// }
-
-// func (t *wt) stbl() int {
-//     wSize, _ := t.start("stbl", false)
-//     if wSize == 0 {
-//             return 0
-//     }
-
-//     wSize += t.copyBox(`stsd`)
-//     wSize += t.stts()
-
-//     return t.fin(wSize)
-// }
-
-// func (t *wt) stts() int {
-//     wSize, lSize := t.start("stts", true)
-//     for {
-//             lSize -= t.r(1 << 20)
-//     }
-//     // lSize -= t.r(16)
-//     // wSize += t.w(t.buf)
-//     // lSize -= t.skips(8)
-//     // wSize += t.w(itob32(1000))
-//     // wSize += t.w(itob32(int32(t.m["mainDuration"] / 1000)))
-//     // lSize -= t.r(4)
-//     // wSize += t.w(t.buf)
-//     t.skips(lSize)
-//     return t.fin(wSize)
-// }
-
-func btoi64(b []byte, offset int) int64 {
-       s := 8
-       bu := make([]byte, s)
-       l := len(b) - offset
-       if l > s {
-               l = s
-       }
-       for i := 0; i < s && i < l; i++ {
-               bu[i+s-l] = b[offset+i]
-       }
-
-       //binary.BigEndian.Uint64
-       return int64(uint64(bu[7]) | uint64(bu[6])<<8 | uint64(bu[5])<<16 | uint64(bu[4])<<24 |
-               uint64(bu[3])<<32 | uint64(bu[2])<<40 | uint64(bu[1])<<48 | uint64(bu[0])<<56)
-}
-
-func btoi32(b []byte, offset int) int32 {
-       s := 4
-       bu := make([]byte, s)
-       l := len(b) - offset
-       if l > s {
-               l = s
-       }
-       for i := 0; i < s && i < l; i++ {
-               bu[i+s-l] = b[offset+i]
-       }
-
-       //binary.BigEndian.Uint32
-       return int32((uint32(bu[3]) | uint32(bu[2])<<8 | uint32(bu[1])<<16 | uint32(bu[0])<<24))
-}
-
-func itob64(v int64) []byte {
-       //binary.BigEndian.PutUint64
-       b := make([]byte, 8)
-       b[0] = byte(v >> 56)
-       b[1] = byte(v >> 48)
-       b[2] = byte(v >> 40)
-       b[3] = byte(v >> 32)
-       b[4] = byte(v >> 24)
-       b[5] = byte(v >> 16)
-       b[6] = byte(v >> 8)
-       b[7] = byte(v)
-       return b
-}
-
-func itob32(v int32) []byte {
-       //binary.BigEndian.PutUint32
-       b := make([]byte, 4)
-       b[0] = byte(v >> 24)
-       b[1] = byte(v >> 16)
-       b[2] = byte(v >> 8)
-       b[3] = byte(v)
-       return b
-}
diff --git a/Reply/F/fmp4Tomp4/fmp4Tomp4_test.go b/Reply/F/fmp4Tomp4/fmp4Tomp4_test.go
deleted file mode 100644 (file)
index 38c3809..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package fmp4Tomp4
-
-// func Test_conver(t *testing.T) {
-//     path := "/codefile/testdata/"
-//     if e := conver(context.Background(), &path); e != nil {
-//             t.Fatal(e)
-//     }
-// }
diff --git a/Reply/F/fmp4Tomp4/reader.go b/Reply/F/fmp4Tomp4/reader.go
deleted file mode 100644 (file)
index 9ed2249..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-package fmp4Tomp4
-
-import (
-       "bytes"
-       "errors"
-       "fmt"
-
-       file "github.com/qydysky/part/file"
-       "golang.org/x/exp/slices"
-)
-
-type Box struct {
-       Name       string
-       Size       int64
-       HeaderSize int64
-       Index      int64
-}
-
-type reader struct {
-       f    *file.File
-       Boxs []Box
-       buf  []byte
-}
-
-func NewReader(f *file.File) (*reader, error) {
-       if f.Config.AutoClose {
-               return nil, errors.New("file AutoClose must false")
-       }
-       return &reader{f: f}, nil
-}
-
-func (t *reader) getN(name string, n int) (ls []Box) {
-       for i := 0; i < len(t.Boxs); i++ {
-               box := t.Boxs[i]
-               if box.Name == name {
-                       ls = append(ls, box)
-                       if len(ls) >= n {
-                               return
-                       }
-               }
-       }
-       return
-}
-
-type BoxReader struct {
-       Buf []byte
-}
-
-func (t *BoxReader) I32(offset int) int32 {
-       return btoi32(t.Buf, offset)
-}
-func (t *BoxReader) I64(offset int) int64 {
-       return btoi64(t.Buf, offset)
-}
-
-func (t *reader) Read(box Box, size int) BoxReader {
-       if size == -1 {
-               t.bufChange(int(box.Size))
-       } else {
-               t.bufChange(size)
-       }
-       _ = t.f.SeekIndex(box.Index, file.AtOrigin)
-       _, _ = t.f.Read(t.buf)
-       return BoxReader{t.buf}
-}
-
-func (t *reader) bufChange(size int) {
-       if n := size - len(t.buf); n > 0 {
-               if size <= cap(t.buf) {
-                       t.buf = t.buf[:size]
-               } else {
-                       t.buf = append(t.buf, make([]byte, n)...)
-               }
-       } else if n < 0 {
-               t.buf = t.buf[:size]
-       }
-       clear(t.buf)
-}
-
-// 正常将返回io.EOF
-func (t *reader) Parse() error {
-       stat, e := t.f.Stat()
-       if e != nil {
-               return e
-       }
-
-       var (
-               b4          = make([]byte, 4)
-               b8          = make([]byte, 8)
-               parseInside = []string{"moov", "trak", "mdia", "minf", "stbl", "moof", "traf"}
-       )
-       for i := int64(0); i < stat.Size(); {
-               boxHeaderSize := 0
-               if n, e := t.f.Read(b4); e != nil {
-                       return e
-               } else {
-                       boxHeaderSize += n
-               }
-               size := int64(btoi32(b4, 0))
-               if n, e := t.f.Read(b4); e != nil {
-                       return e
-               } else {
-                       boxHeaderSize += n
-               }
-               name := string(b4)
-               if size == 1 {
-                       if n, e := t.f.Read(b8); e != nil {
-                               return e
-                       } else {
-                               boxHeaderSize += n
-                       }
-                       size = btoi64(b8, 0)
-               }
-               t.Boxs = append(t.Boxs, Box{
-                       Name:       name,
-                       Size:       size,
-                       Index:      i,
-                       HeaderSize: int64(boxHeaderSize),
-               })
-               if !slices.Contains(parseInside, name) {
-                       seedSize := size - int64(boxHeaderSize)
-                       if e := t.f.SeekIndex(seedSize, file.AtCurrent); e != nil {
-                               return e
-                       }
-                       i += size
-               } else {
-                       i += int64(boxHeaderSize)
-               }
-       }
-       return nil
-}
-
-type Track struct {
-       chunkSize   []int64
-       sampleCount []int32
-       dur         []int32
-       size        []int32
-}
-
-func (t *reader) ParseTrun() (tracks map[int32]*Track, err error) {
-       tracks = make(map[int32]*Track)
-
-       var (
-               b4  = make([]byte, 4)
-               b8  = make([]byte, 8)
-               b12 = make([]byte, 12)
-       )
-
-       for i := 0; i < len(t.Boxs); i++ {
-               box := t.Boxs[i]
-               if box.Name == "tfhd" {
-                       _ = t.f.SeekIndex(box.Index+box.HeaderSize, file.AtOrigin)
-
-                       if _, e := t.f.Read(b8); e != nil {
-                               err = e
-                               return
-                       }
-                       trackID := btoi32(b8, 4)
-                       defaultSampleDuration := int32(0)
-                       {
-                               var offset int64
-                               if b8[3]&0x01 == 0x01 {
-                                       offset += 8
-                               }
-                               if b8[3]&0x02 == 0x02 {
-                                       offset += 4
-                               }
-                               if b8[3]&0x08 == 0x08 {
-                                       _ = t.f.SeekIndex(offset, file.AtCurrent)
-                                       if _, e := t.f.Read(b4); e != nil {
-                                               err = e
-                                               return
-                                       }
-                               }
-                               defaultSampleDuration = btoi32(b4, 0)
-                       }
-
-                       trackO, ok := tracks[trackID]
-                       if !ok {
-                               tracks[trackID] = &Track{}
-                               trackO = tracks[trackID]
-                       }
-
-                       for ; i < len(t.Boxs); i++ {
-                               box := t.Boxs[i]
-                               if box.Name == "trun" {
-                                       _ = t.f.SeekIndex(box.Index+box.HeaderSize, file.AtOrigin)
-                                       if _, e := t.f.Read(b8); e != nil {
-                                               err = e
-                                               return
-                                       }
-
-                                       _ = t.f.SeekIndex(8, file.AtCurrent)
-
-                                       var chunkSize int64
-                                       if bytes.Equal(b8[:4], []byte{0x01, 0x00, 0x0b, 0x05}) {
-                                               sampleCount := btoi32(b8, 4)
-                                               if sampleCount*12 != int32(box.Size-24) {
-                                                       err = errors.New("wrong trun trunSize not match sampleCount")
-                                                       return
-                                               }
-                                               trackO.sampleCount = append(trackO.sampleCount, sampleCount)
-                                               for i := int32(0); i < sampleCount; i++ {
-                                                       if _, e := t.f.Read(b12); e != nil {
-                                                               err = e
-                                                               return
-                                                       }
-                                                       trackO.dur = append(trackO.dur, btoi32(b12, 0))
-                                                       trackO.size = append(trackO.size, btoi32(b12, 4))
-                                                       chunkSize += int64(btoi32(b12, 4))
-                                               }
-                                       } else if bytes.Equal(b8[:4], []byte{0x01, 0x00, 0x02, 0x05}) {
-                                               sampleCount := btoi32(b8, 4)
-                                               if sampleCount*4 != int32(box.Size-24) {
-                                                       err = errors.New("wrong trun trunSize not match sampleCount")
-                                                       return
-                                               }
-                                               trackO.sampleCount = append(trackO.sampleCount, sampleCount)
-                                               for i := int32(0); i < sampleCount; i++ {
-                                                       if _, e := t.f.Read(b4); e != nil {
-                                                               err = e
-                                                               return
-                                                       }
-                                                       trackO.dur = append(trackO.dur, defaultSampleDuration)
-                                                       trackO.size = append(trackO.size, btoi32(b4, 0))
-                                                       chunkSize += int64(btoi32(b4, 0))
-                                               }
-                                       } else {
-                                               err = fmt.Errorf("wrong trun tr_flag(%v)", b8[:4])
-                                               return
-                                       }
-                                       trackO.chunkSize = append(trackO.chunkSize, chunkSize)
-
-                                       break
-                               }
-                       }
-               }
-       }
-
-       return
-}
diff --git a/Reply/F/fmp4Tomp4/reader_test.go b/Reply/F/fmp4Tomp4/reader_test.go
deleted file mode 100644 (file)
index 5f4bb4c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package fmp4Tomp4
-
-// func Test_parse(t *testing.T) {
-//     var read = reader{
-//             f: file.New("/codefile/testdata/0.mp4", 0, false),
-//     }
-//     if e := read.Parse(); e != nil && !errors.Is(e, io.EOF) {
-//             t.Fatal(e)
-//     }
-//     t.Log(len(read.Boxs))
-
-//     m, e := read.ParseTrun()
-//     t.Log(m)
-//     t.Log(e)
-//     // for i := 0; i < len(read.boxs); i++ {
-//     //      t.Log(read.boxs[i].name)
-//     // }
-// }
diff --git a/Reply/F/fmp4Tomp4/writer.go b/Reply/F/fmp4Tomp4/writer.go
deleted file mode 100644 (file)
index 2e4edc4..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-package fmp4Tomp4
-
-import (
-       "errors"
-       "fmt"
-
-       file "github.com/qydysky/part/file"
-       pio "github.com/qydysky/part/io"
-)
-
-var (
-       ErrFileAutoClose = errors.New("file AutoClose must false")
-       ErrSeed          = errors.New("ErrSeed")
-       ErrWrite         = errors.New("ErrWrite")
-)
-
-type boxWriter struct {
-       f  *file.File
-       wn int64
-       e  error
-       p  *boxWriter
-}
-
-func NewBoxWriter(f *file.File) (t *boxWriter, err error) {
-       if f.Config.AutoClose {
-               return nil, ErrFileAutoClose
-       }
-       t = &boxWriter{f: f}
-       return
-}
-
-func (t *boxWriter) Box(name string) (tc *boxWriter) {
-       if t.e != nil {
-               return
-       }
-       tc = &boxWriter{f: t.f, p: t, e: t.e}
-       tc.Write([]byte{0, 0, 0, 1})
-       tc.Write([]byte(name))
-       tc.wn = 0
-       tc.Write(make([]byte, 8))
-       return
-}
-
-func (t *boxWriter) Write(b []byte) (tc *boxWriter) {
-       if t.e != nil {
-               return t
-       }
-       n := 0
-       n, t.e = t.f.Write(b, false)
-       t.wn += int64(n)
-       return t
-}
-
-func (t *boxWriter) CopyFrom(f *file.File, size uint64) (tc *boxWriter) {
-       if t.e != nil {
-               return t
-       }
-       t.e = f.CopyTo(t.f, pio.CopyConfig{MaxByte: size}, false)
-       t.wn += int64(size)
-       return t
-}
-
-func (t *boxWriter) Close() error {
-       if t.e != nil {
-               return t.e
-       }
-       t.e = t.f.SeekIndex(-t.wn, file.AtCurrent)
-       if t.e != nil {
-               return errors.Join(ErrSeed, t.e, fmt.Errorf("Arg %v", -t.wn))
-       }
-       _, t.e = t.f.Write(itob64(t.wn), false)
-       if t.e != nil {
-               return errors.Join(ErrWrite, t.e, fmt.Errorf("Arg %v", -t.wn))
-       }
-       t.e = t.f.SeekIndex(t.wn-8, file.AtCurrent)
-       if t.p != nil {
-               t.p.wn += t.wn
-       }
-       return t.e
-}
diff --git a/Reply/F/fmp4Tomp4/writer_test.go b/Reply/F/fmp4Tomp4/writer_test.go
deleted file mode 100644 (file)
index 25ed19e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package fmp4Tomp4
-
-// func Test_w(t *testing.T) {
-//     tf := file.New("1.mp4", 0, false)
-//     if tf.IsExist() {
-//             _ = tf.Delete()
-//     }
-//     defer tf.Close()
-
-//     w, e := NewBoxWriter(tf)
-//     if e != nil {
-//             t.Fatal(e)
-//     }
-
-//     // ftyp
-//     {
-//             ftyp := w.Box("ftyp")
-//             ftyp.Write([]byte("isom"))
-//             ftyp.Write(itob32(512))
-//             ftyp.Write([]byte("isom"))
-//             ftyp.Write([]byte("iso2"))
-//             ftyp.Write([]byte("avc1"))
-//             ftyp.Write([]byte("mp41"))
-//             if e := ftyp.Close(); e != nil {
-//                     t.Fatal(e)
-//             }
-//     }
-// }
index d579ced68e73f9acf30a47ce655c75ee056f8cc8..6ffea3f0c8878b61b72c49e17c11acfe8bd3a714 100644 (file)
@@ -9,19 +9,8 @@ import (
        comp "github.com/qydysky/part/component"
 )
 
-type Sign struct {
-       // 下播总结
-       sumup func(ctx context.Context, ptr *c.Common) error
-}
-
-func init() {
-       sign := Sign{
-               sumup: sumup,
-       }
-       if e := comp.Put[c.Common](comp.Sign[Sign](`sumup`), sign.sumup); e != nil {
-               panic(e)
-       }
-}
+// *c.Common
+var Sumup = comp.NewComp(sumup)
 
 func sumup(ctx context.Context, ptr *c.Common) error {
        dura := time.Since(ptr.Live_Start_Time).Round(time.Second)
diff --git a/Reply/F/reSetMp4TimeStamp/reSetMp4TimeStamp.go b/Reply/F/reSetMp4TimeStamp/reSetMp4TimeStamp.go
deleted file mode 100644 (file)
index 4222e17..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-package reSetMp4TimeStamp
-
-import (
-       "context"
-       "errors"
-       "fmt"
-       "io"
-       "time"
-
-       comp "github.com/qydysky/part/component"
-       file "github.com/qydysky/part/file"
-)
-
-// 直接保存下来的mp4在chrome上无法直接播放
-//
-// https://serverfault.com/questions/738881/chrome-makes-way-too-many-requests-22000-while-downloading-mp4-video-34mb
-type Sign struct {
-       // 重设mp4的时间戳
-       resetTS func(ctx context.Context, ptr *string) error
-}
-
-func init() {
-       sign := Sign{
-               resetTS: resetTS,
-       }
-       if e := comp.Put[string](comp.Sign[Sign](`resetTS`), sign.resetTS); e != nil {
-               panic(e)
-       }
-}
-
-func resetTS(ctx context.Context, ptr *string) error {
-       be := time.Now()
-       fmt.Println("resetTS")
-       defer func() { fmt.Printf("resetTS fin (%v)\n", time.Since(be)) }()
-
-       f := file.New(*ptr+"0.mp4", 0, false)
-       if !f.IsExist() {
-               return nil
-       }
-       defer f.Close()
-
-       var (
-               byte4  = make([]byte, 4)
-               byte16 = make([]byte, 16)
-               bgdts  = make(map[int32]int64)
-               eddts  = make(map[int32]int64)
-               zdts   = make(map[int32]*guessDts)
-               // timescale = make(map[int32]int64)
-       )
-
-       for {
-               if e := f.SeekUntil([]byte("tkhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
-                       if errors.Is(e, file.ErrMaxReadSizeReach) {
-                               break
-                       }
-                       if errors.Is(e, io.EOF) {
-                               break
-                       }
-                       return e
-               }
-               _ = f.SeekIndex(16, file.AtCurrent)
-               if _, e := f.Read(byte4); e != nil {
-                       return e
-               }
-               trackId := btoi32(byte4, 0)
-
-               bgdts[trackId] = -1
-               eddts[trackId] = 0
-               zdts[trackId] = &guessDts{0, 1}
-       }
-
-       // _ = f.SeekIndex(0, file.AtOrigin)
-       // for {
-       //      if e := f.SeekUntil([]byte("tkhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
-       //              if errors.Is(e, file.ErrMaxReadSizeReach) {
-       //                      break
-       //              }
-       //              if errors.Is(e, io.EOF) {
-       //                      break
-       //              }
-       //              return e
-       //      }
-       //      _ = f.SeekIndex(16, file.AtCurrent)
-       //      if _, e := f.Read(byte4); e != nil {
-       //              return e
-       //      }
-       //      trackId := btoi32(byte4, 0)
-
-       //      if e := f.SeekUntil([]byte("mdhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
-       //              if errors.Is(e, file.ErrMaxReadSizeReach) {
-       //                      break
-       //              }
-       //              if errors.Is(e, io.EOF) {
-       //                      break
-       //              }
-       //              return e
-       //      }
-       //      _ = f.SeekIndex(16, file.AtCurrent)
-       //      if _, e := f.Read(byte4); e != nil {
-       //              return e
-       //      }
-
-       //      timescale[trackId] = int64(btoi32(byte4, 0))
-       // }
-
-       // rewrite dts
-       {
-               _ = f.SeekIndex(0, file.AtOrigin)
-               for {
-                       if e := f.SeekUntil([]byte("tfhd"), file.AtCurrent, 1<<17, 1<<20); e != nil {
-                               if errors.Is(e, file.ErrMaxReadSizeReach) {
-                                       continue
-                               }
-                               if errors.Is(e, io.EOF) {
-                                       break
-                               }
-                               return e
-                       }
-                       _ = f.SeekIndex(8, file.AtCurrent)
-                       if _, e := f.Read(byte4); e != nil {
-                               return e
-                       }
-                       trackID := btoi32(byte4, 0)
-
-                       if e := f.SeekUntil([]byte("tfdt"), file.AtCurrent, 1<<17, 1<<20); e != nil {
-                               if errors.Is(e, file.ErrMaxReadSizeReach) {
-                                       continue
-                               }
-                               if errors.Is(e, io.EOF) {
-                                       break
-                               }
-                               return e
-                       }
-                       if _, e := f.Read(byte16); e != nil {
-                               return e
-                       }
-                       switch byte16[4] {
-                       case 0:
-                               ts := int64(btoi32(byte16, 12))
-                               if e := f.SeekIndex(-4, file.AtCurrent); e != nil {
-                                       return e
-                               }
-                               if bgdts[trackID] == -1 {
-                                       bgdts[trackID] = ts
-                               }
-                               if _, e := f.Write(itob32(int32(ts-bgdts[trackID])), false); e != nil {
-                                       return e
-                               }
-                               eddts[trackID] = ts
-                       case 1:
-                               ts := btoi64(byte16, 8)
-                               if e := f.SeekIndex(-8, file.AtCurrent); e != nil {
-                                       return e
-                               }
-                               if bgdts[trackID] == -1 {
-                                       bgdts[trackID] = ts
-                               }
-                               if _, e := f.Write(itob64(ts-bgdts[trackID]), false); e != nil {
-                                       return e
-                               }
-                               eddts[trackID] = ts
-                       default:
-                               return fmt.Errorf("unknow tfdt version %x", byte16[8])
-                       }
-               }
-       }
-
-       // var duration int32
-       // // for k, v := range bgdts {
-       // //   duration = int32((eddts[k] - v) / timescale[k])
-       // //   break
-       // // }
-
-       // _ = f.SeekIndex(0, file.AtOrigin)
-       // {
-       //      if e := f.SeekUntil([]byte("moov"), file.AtCurrent, 1<<17, 1<<22); e != nil {
-       //              return e
-       //      }
-       // }
-
-       // // write mvhd
-       // _ = f.SeekIndex(0, file.AtOrigin)
-       // {
-       //      if e := f.SeekUntil([]byte("mvhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
-       //              return e
-       //      }
-       //      _ = f.SeekIndex(20, file.AtCurrent)
-       //      if _, e := f.Write(itob32(duration), false); e != nil {
-       //              return e
-       //      }
-       // }
-
-       // // write tkhd mdhd
-       // _ = f.SeekIndex(0, file.AtOrigin)
-       // for {
-       //      if e := f.SeekUntil([]byte("tkhd"), file.AtCurrent, 1<<17, 1<<20); e != nil {
-       //              if errors.Is(e, file.ErrMaxReadSizeReach) {
-       //                      break
-       //              }
-       //              if errors.Is(e, io.EOF) {
-       //                      break
-       //              }
-       //              return e
-       //      }
-       //      _ = f.SeekIndex(24, file.AtCurrent)
-       //      if _, e := f.Write(itob32(duration), false); e != nil {
-       //              return e
-       //      }
-
-       //      if e := f.SeekUntil([]byte("mdhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
-       //              if errors.Is(e, file.ErrMaxReadSizeReach) {
-       //                      continue
-       //              }
-       //              if errors.Is(e, io.EOF) {
-       //                      break
-       //              }
-       //              return e
-       //      }
-       //      _ = f.SeekIndex(20, file.AtCurrent)
-       //      if _, e := f.Write(itob32(duration), false); e != nil {
-       //              return e
-       //      }
-       // }
-       return nil
-}
-
-type guessDts struct {
-       zdts  int64
-       count int64
-}
-
-func btoi64(b []byte, offset int) int64 {
-       s := 8
-       bu := make([]byte, s)
-       l := len(b) - offset
-       if l > s {
-               l = s
-       }
-       for i := 0; i < s && i < l; i++ {
-               bu[i+s-l] = b[offset+i]
-       }
-
-       //binary.BigEndian.Uint64
-       return int64(uint64(bu[7]) | uint64(bu[6])<<8 | uint64(bu[5])<<16 | uint64(bu[4])<<24 |
-               uint64(bu[3])<<32 | uint64(bu[2])<<40 | uint64(bu[1])<<48 | uint64(bu[0])<<56)
-}
-
-func btoi32(b []byte, offset int) int32 {
-       s := 4
-       bu := make([]byte, s)
-       l := len(b) - offset
-       if l > s {
-               l = s
-       }
-       for i := 0; i < s && i < l; i++ {
-               bu[i+s-l] = b[offset+i]
-       }
-
-       //binary.BigEndian.Uint32
-       return int32((uint32(bu[3]) | uint32(bu[2])<<8 | uint32(bu[1])<<16 | uint32(bu[0])<<24))
-}
-
-func itob64(v int64) []byte {
-       //binary.BigEndian.PutUint64
-       b := make([]byte, 8)
-       b[0] = byte(v >> 56)
-       b[1] = byte(v >> 48)
-       b[2] = byte(v >> 40)
-       b[3] = byte(v >> 32)
-       b[4] = byte(v >> 24)
-       b[5] = byte(v >> 16)
-       b[6] = byte(v >> 8)
-       b[7] = byte(v)
-       return b
-}
-
-func itob32(v int32) []byte {
-       //binary.BigEndian.PutUint32
-       b := make([]byte, 4)
-       b[0] = byte(v >> 24)
-       b[1] = byte(v >> 16)
-       b[2] = byte(v >> 8)
-       b[3] = byte(v)
-       return b
-}
diff --git a/Reply/F/recStartEnd/recStartEnd.go b/Reply/F/recStartEnd/recStartEnd.go
new file mode 100644 (file)
index 0000000..699c5a2
--- /dev/null
@@ -0,0 +1,166 @@
+package recStartEnd
+
+import (
+       "context"
+       "errors"
+       "fmt"
+       "math"
+       "time"
+
+       c "github.com/qydysky/bili_danmu/CV"
+       comp "github.com/qydysky/part/component"
+       log "github.com/qydysky/part/log"
+       "golang.org/x/exp/slices"
+)
+
+var (
+       InitF         = comp.NewComp(initf)
+       RecStartCheck = comp.NewComp(recStartCheck)
+       LoopCheck     = comp.NewComp(loopCheck)
+)
+
+type dur struct {
+       start int
+       end   int
+}
+
+var (
+       logg        *log.Log_interface
+       roomSetting map[int][]dur
+       timePoints  []int
+)
+
+func initf(ctx context.Context, ptr *c.Common) (err error) {
+       if list, ok := ptr.K_v.LoadV("指定房间录制区间").([]any); ok {
+               logg = ptr.Log.Base("功能", "指定房间录制区间")
+               defer func() {
+                       if err != nil {
+                               clear(roomSetting)
+                               clear(timePoints)
+                       }
+               }()
+               if roomSetting == nil {
+                       roomSetting = make(map[int][]dur)
+               }
+               clear(roomSetting)
+               for _, v := range list {
+                       if vm, ok := v.(map[string]any); ok {
+                               if roomid, ok := vm["roomid"].(float64); ok && int(roomid) > 0 {
+                                       var durs []dur
+                                       if sts, ok := vm["fromTo"].([]any); ok {
+                                               for _, v := range sts {
+                                                       if vm, ok := v.(map[string]any); ok {
+                                                               var durv dur
+                                                               if start, ok := vm["start"].(string); ok {
+                                                                       if tt, e := time.Parse(time.TimeOnly, start); e != nil {
+                                                                               err = e
+                                                                               return
+                                                                       } else {
+                                                                               durv.start = tt.Hour()*3600 + tt.Minute()*60 + tt.Second() + 1
+                                                                               timePoints = append(timePoints, durv.start)
+                                                                       }
+                                                               }
+                                                               if end, ok := vm["end"].(string); ok {
+                                                                       if tt, e := time.Parse(time.TimeOnly, end); e != nil {
+                                                                               err = e
+                                                                               return
+                                                                       } else {
+                                                                               durv.end = tt.Hour()*3600 + tt.Minute()*60 + tt.Second() + 1
+                                                                               timePoints = append(timePoints, durv.end)
+                                                                       }
+                                                               }
+                                                               durs = append(durs, durv)
+                                                       }
+                                               }
+                                       }
+                                       logg.L(`T: `, "加载规则", fmt.Sprintf("%d %d条", int(roomid), len(durs)))
+                                       roomSetting[int(roomid)] = durs
+                               }
+                       }
+               }
+               slices.Sort(timePoints)
+       }
+       return nil
+}
+
+func recStartCheck(ctx context.Context, ptr *c.Common) error {
+       if setting, ok := roomSetting[ptr.Roomid]; ok {
+               now := time.Now()
+               t := now.Hour()*3600 + now.Minute()*60 + now.Second() + 1
+               for _, v := range setting {
+                       if v.start != 0 && v.end != 0 && t <= v.end && t >= v.start {
+                               return nil
+                       }
+               }
+               return errors.New("当前不在设定时间段内")
+       }
+       return nil
+}
+
+type StreamCtl struct {
+       C     *c.Common
+       State func(int) bool
+       Start func(int)
+       End   func(int)
+       Cut   func(int)
+}
+
+var streamCtl StreamCtl
+
+func loopCheck(ctx context.Context, ptr StreamCtl) error {
+       streamCtl = ptr
+       setNextFunc()
+       return nil
+}
+
+func setNextFunc() {
+       if len(timePoints) == 0 {
+               return
+       }
+
+       now := time.Now()
+       t := now.Hour()*3600 + now.Minute()*60 + now.Second() + 1
+
+       var tmp []int
+       for i := 0; i < len(timePoints); i++ {
+               if t > timePoints[i] {
+                       tmp = append(tmp, timePoints[i]+60*60*24-t)
+               } else {
+                       tmp = append(tmp, timePoints[i]-t)
+               }
+       }
+       slices.Sort(tmp)
+
+       // logg.L(`T: `, "下个时间点", time.Now().Add(time.Second*time.Duration(tmp[0])).Format(time.DateTime))
+
+       time.AfterFunc(time.Second*time.Duration(tmp[0]), func() {
+               if streamCtl.C.Liveing {
+                       if setting, ok := roomSetting[streamCtl.C.Roomid]; ok {
+                               now := time.Now()
+                               t := now.Hour()*3600 + now.Minute()*60 + now.Second() + 1
+                               for _, v := range setting {
+                                       if v.start != 0 && math.Abs(float64(t-v.start)) < 5 {
+                                               if streamCtl.State(streamCtl.C.Roomid) {
+                                                       logg.L(`T: `, "切片", streamCtl.C.Roomid)
+                                                       streamCtl.Cut(streamCtl.C.Roomid)
+                                               } else {
+                                                       logg.L(`T: `, "开始", streamCtl.C.Roomid)
+                                                       streamCtl.Start(streamCtl.C.Roomid)
+                                               }
+                                               time.Sleep(time.Second * 5)
+                                               break
+                                       }
+                                       if v.end != 0 && math.Abs(float64(t-v.end)) < 5 {
+                                               if streamCtl.State(streamCtl.C.Roomid) {
+                                                       logg.L(`T: `, "结束", streamCtl.C.Roomid)
+                                                       streamCtl.End(streamCtl.C.Roomid)
+                                               }
+                                               time.Sleep(time.Second * 5)
+                                               break
+                                       }
+                               }
+                       }
+               }
+               setNextFunc()
+       })
+}
index ee3005fdc5f25bebf6a42b4b109d99e5b7187119..1acf3bb595427b1f11cdce68d054cea97af487de 100644 (file)
@@ -13,10 +13,11 @@ import (
        brotli "github.com/andybalholm/brotli"
        c "github.com/qydysky/bili_danmu/CV"
        F "github.com/qydysky/bili_danmu/F"
+       "github.com/qydysky/bili_danmu/Reply/F/liveOver"
+       "github.com/qydysky/bili_danmu/Reply/F/recStartEnd"
        ws_msg "github.com/qydysky/bili_danmu/Reply/ws_msg"
        send "github.com/qydysky/bili_danmu/Send"
        p "github.com/qydysky/part"
-       comp "github.com/qydysky/part/component"
        mq "github.com/qydysky/part/msgq"
        pstrings "github.com/qydysky/part/strings"
 )
@@ -772,7 +773,7 @@ func (replyF) preparing(s string) {
                        StreamOStop(roomId)
                        // 下播总结
                        type empty struct{}
-                       if e := comp.Run(comp.Sign[empty](`preparing`), context.Background(), c.C); e != nil {
+                       if e := liveOver.Sumup.Run(context.Background(), c.C); e != nil {
                                msglog.L(`E: `, e)
                        }
                }
@@ -804,7 +805,15 @@ func (replyF) live(s string) {
                        if v, ok := c.C.K_v.LoadV(`仅保存当前直播间流`).(bool); ok && v {
                                StreamOStop(-2) //停止其他房间录制
                        }
-                       StreamOStart(c.C.Roomid)
+                       if e := recStartEnd.RecStartCheck.Run(context.Background(), c.C); e == nil {
+                               if StreamOStatus(c.C.Roomid) {
+                                       StreamOCut(c.C.Roomid)
+                               } else {
+                                       StreamOStart(c.C.Roomid)
+                               }
+                       } else {
+                               msglog.L(`W: `, "房间", type_item.Roomid, e)
+                       }
                        //有时不返回弹幕 开播刷新弹幕
                        c.C.Danmu_Main_mq.Push_tag(`flash_room`, nil)
                }()
index 3823438798e6f497ec3615cf48ca94a530d3af3d..d8a74e314561d1fa928feff822393418963b812c 100644 (file)
@@ -15,6 +15,7 @@ import (
        c "github.com/qydysky/bili_danmu/CV"
        F "github.com/qydysky/bili_danmu/F"
        reply "github.com/qydysky/bili_danmu/Reply"
+       "github.com/qydysky/bili_danmu/Reply/F/recStartEnd"
        send "github.com/qydysky/bili_danmu/Send"
        Cmd "github.com/qydysky/bili_danmu/cmd"
        sys "github.com/qydysky/part/sys"
@@ -87,6 +88,10 @@ func Start() {
                F.Dosign()
                // 附加功能 savetojson
                reply.SaveToJson.Init()
+               // 指定房间录制区间
+               if err := recStartEnd.InitF.Run(context.Background(), c.C); err != nil {
+                       danmulog.Base("功能", "指定房间录制区间").L(`E: `, err)
+               }
 
                //使用带tag的消息队列在功能间传递消息
                {
@@ -285,9 +290,20 @@ func Start() {
                                        reply.Danmuji_auto()
                                }
                                { //附加功能 进房间发送弹幕 直播流保存 每日签到
+                                       _ = recStartEnd.LoopCheck.Run(context.Background(), recStartEnd.StreamCtl{
+                                               C:     c.C,
+                                               State: reply.StreamOStatus,
+                                               Start: reply.StreamOStart,
+                                               End:   reply.StreamOStop,
+                                               Cut:   func(i int) { reply.StreamOCut(i) },
+                                       })
                                        go F.Dosign()
                                        go reply.Entry_danmu()
-                                       go reply.StreamOStart(c.C.Roomid)
+                                       if e := recStartEnd.RecStartCheck.Run(context.Background(), c.C); e == nil {
+                                               go reply.StreamOStart(c.C.Roomid)
+                                       } else {
+                                               danmulog.Base("功能", "指定房间录制区间").L(`I: `, c.C.Roomid, e)
+                                       }
                                        go F.RoomEntryAction(c.C.Roomid)
                                }
 
index c217672c2b5ea3485c6569580041853a83fda641..531e4550b276ca20874d794a5e47f42b15c32e87 100644 (file)
             "after":["ffmpeg","-i","0.{type}","-y","-c","copy","1.{type}"]
         }
     ],
+    "指定房间录制区间-help":"指定roomid的房间在指定时间段内将会开启录制.start时检查是否在直播,是则开始录制,如已在录制则切片.end时停止录制.在开播时,若在start与end之间,则录制,5s内只能触发一个fromTo",
+    "指定房间录制区间":[
+        {
+            "roomid":0,
+            "fromTo":[
+                {
+                    "start": "12:01:00",
+                    "end": "12:03:00"
+                },
+                {
+                    "start": "12:02:00"
+                }
+            ]
+        }
+    ],
     "Web服务地址-help":"填写本程序各组件所用的服务地址 例0.0.0.0:10000 为空时不启动Web服务",
     "Web服务地址":"0.0.0.0:10000",
     "Web服务连接限制-help": "限制回放连接数,<0无限制,=0禁止,>0最大数量",
diff --git a/go.mod b/go.mod
index c89d018367bc8684066f1b17540135423e7e549f..64df0093948e74e516ce047bddc6df75623c18c4 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.2.0
-       github.com/qydysky/part v0.28.1-0.20231109160627-cb7ab257995b
+       github.com/qydysky/part v0.28.1-0.20231118041002-d67071eadd31
        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.14.0
diff --git a/go.sum b/go.sum
index fa1df2a5016de2a10fbbde55d2dd184cb0da5b9f..1374feaa49be0c1299b54093f7d92f2cc9c2e841 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -35,8 +35,8 @@ github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
 github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
 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.20231109160627-cb7ab257995b h1:nKmP2PJdgpFBVWl9O92zKNS9k7MgBGXUGH0jdXpd7Xo=
-github.com/qydysky/part v0.28.1-0.20231109160627-cb7ab257995b/go.mod h1:twb1IuSmUJ3hllGLwWTBjXRkHjsgmiYi3B9H2ENgIf0=
+github.com/qydysky/part v0.28.1-0.20231118041002-d67071eadd31 h1:JDZ3yCv4bO1WQP05Le1KwhQL4uopNASbmb6Aovr9yd4=
+github.com/qydysky/part v0.28.1-0.20231118041002-d67071eadd31/go.mod h1:NyKyjpBCSjcHtKlC+fL5lCidm57UCnwEgufiBDs5yxA=
 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=