"net/http"
"net/http/pprof"
"net/url"
- "os"
- "path"
"sort"
"strconv"
"strings"
F "github.com/qydysky/bili_danmu/F"
_ "github.com/qydysky/bili_danmu/Reply/F"
"github.com/qydysky/bili_danmu/Reply/F/danmuXml"
+ videoInfo "github.com/qydysky/bili_danmu/Reply/F/videoInfo"
send "github.com/qydysky/bili_danmu/Send"
p "github.com/qydysky/part"
if v, ok := streamO.Load(roomid); ok {
if !pctx.Done(v.(*M4SStream).Status) {
if len(title) != 0 {
- v.(*M4SStream).common.Title = title[0]
+ v.(*M4SStream).Common().Title = title[0]
}
- v.(*M4SStream).msg.Push_tag(`cut`, v.(*M4SStream))
+ v.(*M4SStream).Cut()
flog.L(`I: `, `已切片 `+strconv.Itoa(roomid))
}
}
})
}
-// 录播目录信息
-type paf struct {
- Uname string `json:"uname"`
- UpUid int `json:"upUid"`
- Roomid int `json:"roomid"`
- Qn string `json:"qn"`
- Name string `json:"name"`
- StartT string `json:"startT"`
- EndT string `json:"endT"`
- Path string `json:"path"`
- CurrentSavePath string `json:"-"`
- Format string `json:"format"`
- StartLiveT string `json:"startLiveT"`
-}
-
-// 获取录播目录信息
-func getRecInfo(dirpath string) (pathInfo paf, err error) {
- dirf := file.New(dirpath, 0, true)
- defer dirf.Close()
- if dirf.IsDir() {
- // 从文件夹获取信息
- {
- dirfName := path.Base(dirf.File().Name())
- if len(dirfName) > 20 {
- pathInfo = paf{Name: dirfName[20:], StartT: dirfName[:19], Path: dirfName}
- }
- mp4f := file.New(dirpath+string(os.PathSeparator)+"0.mp4", 0, true)
- if mp4f.IsExist() {
- pathInfo.Format = "mp4"
- } else {
- pathInfo.Format = "flv"
- }
- }
- // 从0.json获取信息
- {
- json0 := file.New(dirpath+string(os.PathSeparator)+"0.json", 0, true)
- if !json0.IsExist() {
- return
- }
- defer json0.Close()
- if data, e := json0.ReadAll(1<<8, 1<<16); e != nil && !errors.Is(e, io.EOF) {
- err = e
- return
- } else {
- if e := json.Unmarshal(data, &pathInfo); e != nil {
- err = e
- return
- }
- }
- }
- }
- return
-}
-
func init() {
flog := flog.Base_add(`直播Web服务`)
if path, ok := c.C.K_v.LoadV(`直播Web服务路径`).(string); ok {
}
w = cache.Cache(path+"filePath", time.Second*5, w)
- var filePaths []paf
+ var filePaths []*videoInfo.Paf
// 获取当前房间的
var currentStreamO *M4SStream
}
return true
})
- if currentStreamO != nil && currentStreamO.Common().Liveing {
- filePaths = append(filePaths, paf{
- Name: "Now: " + currentStreamO.Common().Title,
- Path: "now",
- Qn: c.C.Qn[currentStreamO.Common().Live_qn],
- Uname: currentStreamO.Common().Uname,
- Format: currentStreamO.stream_type,
- StartT: time.Now().Format(time.DateTime),
- StartLiveT: currentStreamO.Common().Live_Start_Time.Format(time.DateTime),
- })
- }
+ // if currentStreamO != nil && currentStreamO.Common().Liveing {
+ // filePaths = append(filePaths, struct{
+ // Name: "Now: " + currentStreamO.Common().Title,
+ // Path: "now",
+ // Qn: c.C.Qn[currentStreamO.Common().Live_qn],
+ // Uname: currentStreamO.Common().Uname,
+ // Format: currentStreamO.stream_type,
+ // StartT: time.Now().Format(time.DateTime),
+ // StartLiveT: currentStreamO.Common().Live_Start_Time.Format(time.DateTime),
+ // })
+ // }
if v, ok := c.C.K_v.LoadV(`直播流保存位置`).(string); ok && v != "" {
dir := file.New(v, 0, true)
return
} else {
for i, n := 0, len(fs); i < n; i++ {
- if filePath, e := getRecInfo((fs[i])); e != nil {
- c.ResStruct{Code: -1, Message: e.Error(), Data: nil}.Write(w)
- return
+ if filePath, e := videoInfo.Get.Run(context.Background(), fs[i]); e != nil {
+ flog.L(`W: `, fs[i], e)
+ continue
} else {
if t, e := time.Parse("2006_01_02-15_04_05", filePath.StartT); e == nil {
filePath.StartT = t.Format(time.DateTime)
}
+ if currentStreamO != nil &&
+ currentStreamO.Common().Liveing &&
+ strings.Contains(currentStreamO.GetSavePath(), filePath.Path) {
+ filePath.Name = "Now:" + filePath.Name
+ filePath.Path = "now"
+ }
filePaths = append(filePaths, filePath)
}
}
}
-
sort.Slice(filePaths, func(i, j int) bool {
return filePaths[i].StartT > filePaths[j].StartT
})
w.WriteHeader(http.StatusNotFound)
return
} else if !file.New(v+"0.xml", 0, true).IsExist() {
- if e := danmuXml.DanmuXml.Run(context.Background(), &v); e != nil {
+ if _, e := danmuXml.DanmuXml.Run(context.Background(), &v); e != nil {
msglog.L(`E: `, e)
}
}
w.WriteHeader(http.StatusNotFound)
return
}
- if e := danmuXml.DanmuXml.Run(context.Background(), &v); e != nil {
+ if _, e := danmuXml.DanmuXml.Run(context.Background(), &v); e != nil {
msglog.L(`E: `, e)
}
}
f.L(`I: `, `结束`)
// 弹幕录制结束
- if e := danmuXml.DanmuXml.Run(context.Background(), &filePath); e != nil {
+ if _, e := danmuXml.DanmuXml.Run(context.Background(), &filePath); e != nil {
msglog.L(`E: `, e)
}
C *c.Common
}
-func initf(ctx context.Context, ptr DanmuReLiveTriger) error {
+func initf(ctx context.Context, ptr DanmuReLiveTriger) (any, error) {
l = make(map[string]*regexp.Regexp)
if v, ok := ptr.C.K_v.LoadV(`指定弹幕重启录制`).([]any); ok && len(v) > 0 {
logg = ptr.C.Log.Base("指定弹幕重启录制")
if uid != "" && danmu != "" {
if reg, e := regexp.Compile(danmu); e != nil {
clear(l)
- return e
+ return nil, e
} else {
l[uid] = reg
}
logg.L(`T: `, `加载`, len(l), `条规则`)
}
}
- return nil
+ return nil, nil
}
type Danmu struct {
Uid, Msg string
}
-func check(ctx context.Context, item Danmu) error {
+func check(ctx context.Context, item Danmu) (any, error) {
if reg, ok := l[item.Uid]; ok {
if ss := reg.FindStringSubmatch(item.Msg); len(ss) > 0 {
if reload.CompareAndSwap(false, true) {
}
}
}
- return nil
+ return nil, nil
}
Time float64 `json:"time"`
}
-func toXml(ctx context.Context, path *string) error {
+func toXml(ctx context.Context, path *string) (any, error) {
d := danmu{
Chatserver: "chat.bilibili.com",
Chatid: 0,
output, err := xml.MarshalIndent(d, "", " ")
if err != nil {
- return err
+ return nil, err
}
f := file.New((*path)+"0.xml", 0, false)
defer f.Close()
if _, err := f.Write([]byte(xml.Header), true); err != nil {
- return err
+ return nil, err
}
if _, err := f.Write(output, true); err != nil {
- return err
+ return nil, err
}
- return nil
+ return nil, nil
}
once sync.Once
)
-func start(ctx context.Context, file string) error {
+func start(ctx context.Context, file string) (any, error) {
if file == "" {
- return nil
+ return nil, nil
}
go once.Do(
func() {
pgo.Close()
}
})
- return nil
+ return nil, nil
}
// *c.Common
var Sumup = comp.NewComp(sumup)
-func sumup(ctx context.Context, ptr *c.Common) error {
+func sumup(ctx context.Context, ptr *c.Common) (any, error) {
dura := time.Since(ptr.Live_Start_Time).Round(time.Second)
if ptr.Live_Start_Time.IsZero() {
ptr.Log.Base(`功能`, `下播总结`).L(`I: `, fmt.Sprintf("%d 未直播", ptr.Roomid))
ptr.Log.Base(`功能`, `下播总结`).L(`I: `, fmt.Sprintf("%d 时长 %s 营收 %.2f元 %.2f元/分 人数 %d人 %.2f人/分", ptr.Roomid, dura, ptr.Rev, yperm, ptr.Watched, pperm))
}
- return nil
+ return nil, nil
}
timePoints []int
)
-func initf(ctx context.Context, ptr *c.Common) (err error) {
+func initf(ctx context.Context, ptr *c.Common) (_ any, err error) {
if list, ok := ptr.K_v.LoadV("指定房间录制区间").([]any); ok {
logg = ptr.Log.Base("功能", "指定房间录制区间")
defer func() {
}
slices.Sort(timePoints)
}
- return nil
+ return nil, nil
}
-func recStartCheck(ctx context.Context, ptr *c.Common) error {
+func recStartCheck(ctx context.Context, ptr *c.Common) (any, error) {
if setting, ok := roomSetting[ptr.Roomid]; ok {
now := time.Now()
t := now.Hour()*3600 + now.Minute()*60 + now.Second() + 1
if v.start != 0 && v.end != 0 {
hasSpace = true
if t <= v.end && t >= v.start {
- return nil
+ return nil, nil
}
}
}
if hasSpace {
- return errors.New("当前不在设定时间段内")
+ return nil, errors.New("当前不在设定时间段内")
}
}
- return nil
+ return nil, nil
}
type StreamCtl struct {
var streamCtl StreamCtl
-func loopCheck(ctx context.Context, ptr StreamCtl) error {
+func loopCheck(ctx context.Context, ptr StreamCtl) (any, error) {
streamCtl = ptr
setNextFunc()
- return nil
+ return nil, nil
}
func setNextFunc() {
--- /dev/null
+package videoInfo
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "io"
+ "os"
+ "path"
+ "time"
+
+ c "github.com/qydysky/bili_danmu/CV"
+ component "github.com/qydysky/part/component"
+ pctx "github.com/qydysky/part/ctx"
+ file "github.com/qydysky/part/file"
+)
+
+var (
+ Save = component.NewComp(save)
+ Get = component.NewComp(get)
+)
+
+type Info interface {
+ Common() *c.Common
+ GetStreamType() string
+ GetSavePath() string
+}
+
+type Paf struct {
+ Uname string `json:"uname"`
+ UpUid int `json:"upUid"`
+ Roomid int `json:"roomid"`
+ Qn string `json:"qn"`
+ Name string `json:"name"`
+ StartT string `json:"startT"`
+ EndT string `json:"endT"`
+ Path string `json:"path"`
+ CurrentSavePath string `json:"-"`
+ Format string `json:"format"`
+ StartLiveT string `json:"startLiveT"`
+}
+
+func save(ctx context.Context, i Info) (*Paf, error) {
+ infop := _newPaf(i.Common(), i.GetSavePath(), i.GetStreamType())
+ if e := _save(infop); e != nil {
+ return nil, e
+ }
+
+ go func(ctx context.Context, info Info, infop *Paf) {
+ logger := info.Common().Log.Base_add("videoInfo")
+ ctx1, done1 := pctx.WaitCtx(ctx)
+ defer done1()
+ for {
+ select {
+ case <-ctx1.Done():
+ infop.EndT = time.Now().Format(time.DateTime)
+ if e := _save(infop); e != nil {
+ logger.L(`E: `, e)
+ return
+ }
+ return
+ case <-time.After(time.Minute):
+ if infop.Name != info.Common().Title {
+ infop.Name = info.Common().Title
+ if e := _save(infop); e != nil {
+ logger.L(`E: `, e)
+ return
+ }
+ }
+ }
+ }
+ }(ctx, i, infop)
+
+ return nil, nil
+}
+
+func get(ctx context.Context, savepath string) (*Paf, error) {
+ var d Paf
+ dirf := file.New(savepath, 0, true)
+ defer dirf.Close()
+ if dirf.IsDir() {
+ // 从文件夹获取信息
+ {
+ dirfName := path.Base(dirf.File().Name())
+ if len(dirfName) > 20 {
+ d = Paf{Name: dirfName[20:], StartT: dirfName[:19], Path: dirfName}
+ }
+ mp4f := file.New(savepath+string(os.PathSeparator)+"0.mp4", 0, true)
+ if mp4f.IsExist() {
+ d.Format = "mp4"
+ } else {
+ d.Format = "flv"
+ }
+ }
+ // 从0.json获取信息
+ {
+ json0 := file.New(savepath+string(os.PathSeparator)+"0.json", 0, true)
+ if !json0.IsExist() {
+ return &d, nil
+ }
+ defer json0.Close()
+ if data, e := json0.ReadAll(1<<8, 1<<16); e != nil && !errors.Is(e, io.EOF) {
+ return &d, e
+ } else {
+ if e := json.Unmarshal(data, &d); e != nil {
+ return &d, e
+ }
+ d.CurrentSavePath = d.Path + "/0." + d.Format
+ }
+ }
+ }
+ return &d, nil
+}
+
+func _save(pathInfo *Paf) error {
+ fj := file.New(pathInfo.CurrentSavePath+"0.json", 0, true)
+ if fj.IsExist() {
+ if err := fj.Delete(); err != nil {
+ return err
+ }
+ }
+ if pathInfoJson, err := json.Marshal(pathInfo); err != nil {
+ return err
+ } else if _, err := fj.Write(pathInfoJson, true); err != nil {
+ return err
+ }
+ return nil
+}
+
+func _newPaf(common *c.Common, savePath, streamType string) *Paf {
+ return &Paf{
+ Uname: common.Uname,
+ UpUid: common.UpUid,
+ Roomid: common.Roomid,
+ Qn: c.C.Qn[common.Live_qn],
+ Name: common.Title,
+ StartT: time.Now().Format(time.DateTime),
+ Path: path.Base(savePath),
+ CurrentSavePath: savePath,
+ Format: streamType,
+ StartLiveT: common.Live_Start_Time.Format(time.DateTime),
+ }
+}
"testing"
c "github.com/qydysky/bili_danmu/CV"
+ videoInfo "github.com/qydysky/bili_danmu/Reply/F/videoInfo"
psql "github.com/qydysky/part/sql"
)
}
func Test_getRecInfo(t *testing.T) {
- pathInfo, err := getRecInfo("testdata/live/2023_07_10-14_49_10-22259479-10000-644c3e-vfv")
+ pathInfo, err := videoInfo.Get.Run(context.Background(), "testdata/live/2023_07_10-14_49_10-22259479-10000-644c3e-vfv")
if err != nil {
t.Fatal(err)
}
msglog.L(`E: `, e)
}
- change := c.C.AreaID != type_item.Data.AreaID || c.C.Title != type_item.Data.Title
+ if type_item.Data.AreaID != 0 {
+ c.C.AreaID = type_item.Data.AreaID
+ }
+ if type_item.Data.ParentAreaID != 0 {
+ c.C.ParentAreaID = type_item.Data.ParentAreaID
+ }
+ if type_item.Data.Title != "" {
+ c.C.Title = type_item.Data.Title
+ }
- if c.C.Title != type_item.Data.Title {
- StreamOCut(c.C.Roomid, type_item.Data.Title)
- } else if c.C.AreaID == type_item.Data.AreaID {
+ StreamOCut(c.C.Roomid, type_item.Data.Title)
+
+ if c.C.Title == type_item.Data.Title && c.C.AreaID == type_item.Data.AreaID {
// 直播间标题引入审核机制,触发审核时会接收到一个roomchange但标题不变
cancle := make(chan struct{})
roomChangeFC.FlashWithCallback(func() {
case <-time.After(time.Second * 30):
F.Get(c.C).Get(`Title`)
if c.C.Roomid == roomid && c.C.Title != oldTitle {
- StreamOCut(c.C.Roomid, c.C.Title)
var sh = []any{"房间改变", c.C.Title}
Gui_show(Itos(sh), "0room")
msglog.Base_add("房").L(`I: `, sh...)
}
}
}(c.C.Roomid, c.C.Title)
+ return
}
- if type_item.Data.AreaID != 0 {
- c.C.AreaID = type_item.Data.AreaID
- }
- if type_item.Data.ParentAreaID != 0 {
- c.C.ParentAreaID = type_item.Data.ParentAreaID
- }
-
- var sh = []interface{}{"房间改变"}
- if type_item.Data.Title != "" {
- sh = append(sh, type_item.Data.Title)
- c.C.Title = type_item.Data.Title
- }
- if type_item.Data.AreaName != "" {
- sh = append(sh, type_item.Data.AreaName)
- }
-
- if change {
- Gui_show(Itos(sh), "0room")
- msglog.Base_add("房").L(`I: `, sh...)
- }
+ var sh = []any{"房间改变", type_item.Data.Title, type_item.Data.AreaName}
+ Gui_show(Itos(sh), "0room")
+ msglog.Base_add("房").L(`I: `, sh...)
}
// Msg-超管警告
var roomId, _ = strconv.Atoi(type_item.Roomid)
StreamOStop(roomId)
// 下播总结
- if e := liveOver.Sumup.Run(context.Background(), c.C); e != nil {
+ if _, e := liveOver.Sumup.Run(context.Background(), c.C); e != nil {
msglog.L(`E: `, e)
}
}
if v, ok := c.C.K_v.LoadV(`仅保存当前直播间流`).(bool); ok && v {
StreamOStop(-2) //停止其他房间录制
}
- if e := recStartEnd.RecStartCheck.Run(context.Background(), c.C); e == nil {
+ if _, e := recStartEnd.RecStartCheck.Run(context.Background(), c.C); e == nil {
if StreamOStatus(c.C.Roomid) {
StreamOCut(c.C.Roomid)
} else {
saveDanmuToDB.init(c.C)
saveDanmuToDB.danmu(item)
// 对指定弹幕重新录制
- _ = danmuReLiveTriger.Check.Run(context.Background(), danmuReLiveTriger.Danmu{Uid: item.uid, Msg: item.msg})
+ _, _ = danmuReLiveTriger.Check.Run(context.Background(), danmuReLiveTriger.Danmu{Uid: item.uid, Msg: item.msg})
// 语言tts 私信
{
if item.uid != "" {
"context"
"crypto/md5"
"encoding/base64"
- "encoding/json"
"errors"
"fmt"
"io"
"net/url"
"os"
"os/exec"
- "path"
"path/filepath"
"strconv"
"strings"
c "github.com/qydysky/bili_danmu/CV"
F "github.com/qydysky/bili_danmu/F"
+ videoInfo "github.com/qydysky/bili_danmu/Reply/F/videoInfo"
pctx "github.com/qydysky/part/ctx"
pe "github.com/qydysky/part/errors"
file "github.com/qydysky/part/file"
return
}
+func (t *M4SStream) GetStreamType() string {
+ return t.stream_type
+}
+
+func (t *M4SStream) GetSavePath() string {
+ return t.Current_save_path
+}
+
func (t *M4SStream) Start() bool {
// 清晰度-1 or 路径存在问题 不保存
if t.config.want_qn == -1 || t.config.save_path == "" {
ms.getSavepath()
- var pathInfo = paf{
- Uname: ms.common.Uname,
- UpUid: ms.common.UpUid,
- Roomid: ms.common.Roomid,
- Qn: c.C.Qn[ms.common.Live_qn],
- Name: ms.common.Title,
- StartT: time.Now().Format(time.DateTime),
- Path: path.Base(ms.Current_save_path),
- CurrentSavePath: ms.Current_save_path,
- Format: ms.stream_type,
- StartLiveT: ms.common.Live_Start_Time.Format(time.DateTime),
- }
-
l := ms.log.Base_add(`文件保存`)
startf := func(_ *M4SStream) error {
l.L(`T: `, `开始`)
return nil
}
stopf := func(_ *M4SStream) error {
- // savestate
- {
- fj := file.New(pathInfo.CurrentSavePath+"0.json", 0, true)
- if fj.IsExist() {
- if err := fj.Delete(); err != nil {
- l.L(`E: `, err)
- }
- }
- pathInfo.EndT = time.Now().Format(time.DateTime)
- if pathInfoJson, err := json.Marshal(pathInfo); err != nil {
- l.L(`E: `, err)
- } else if _, err := fj.Write(pathInfoJson, true); err != nil {
- l.L(`E: `, err)
- }
- }
l.L(`T: `, `结束`)
return nil
}
}
// savestate
- {
-
- fj := file.New(pathInfo.CurrentSavePath+"0.json", 0, true)
- if fj.IsExist() {
- if err := fj.Delete(); err != nil {
- l.L(`E: `, err)
- }
- }
- if pathInfoJson, err := json.Marshal(pathInfo); err != nil {
- l.L(`E: `, err)
- } else if _, err := fj.Write(pathInfoJson, true); err != nil {
- l.L(`E: `, err)
- }
- fj.Close()
+ if e, _ := videoInfo.Save.Run(contextC, ms); e != nil {
+ l.L(`E: `, e)
}
- go StartRecDanmu(contextC, pathInfo.CurrentSavePath) //保存弹幕
- go Ass_f(contextC, pathInfo.CurrentSavePath, pathInfo.CurrentSavePath+"0", time.Now()) //开始ass
+ go StartRecDanmu(contextC, ms.GetSavePath()) //保存弹幕
+ go Ass_f(contextC, ms.GetSavePath(), ms.GetSavePath()+"0", time.Now()) //开始ass
startT := time.Now()
- if e := ms.PusherToFile(contextC, pathInfo.CurrentSavePath+`0.`+pathInfo.Format, startf, stopf); e != nil {
+ if e := ms.PusherToFile(contextC, ms.GetSavePath()+`0.`+ms.GetStreamType(), startf, stopf); e != nil {
l.L(`E: `, e)
}
duration := time.Since(startT)
l := l.Base(`录制回调`)
for i := 0; i < len(v); i++ {
if vm, ok := v[i].(map[string]any); ok {
- if roomid, ok := vm["roomid"].(float64); ok && int(roomid) == pathInfo.Roomid {
+ if roomid, ok := vm["roomid"].(float64); ok && int(roomid) == ms.common.Roomid {
var (
durationS, _ = vm["durationS"].(float64)
after, _ = vm["after"].([]any)
var cmds []string
for i := 0; i < len(after); i++ {
if cmd, ok := after[i].(string); ok && cmd != "" {
- cmds = append(cmds, strings.ReplaceAll(cmd, "{type}", pathInfo.Format))
+ cmds = append(cmds, strings.ReplaceAll(cmd, "{type}", ms.GetStreamType()))
}
}
cmd := exec.Command(cmds[0], cmds[1:]...)
- cmd.Dir = pathInfo.CurrentSavePath
+ cmd.Dir = ms.GetSavePath()
l.L(`I: `, "启动", cmd.Args)
if e := cmd.Run(); e != nil {
l.L(`E: `, e)
t.log.L(`I: `, `结束`)
}
+func (t *M4SStream) Cut() {
+ t.msg.Push_tag(`cut`, t)
+}
+
// 保存到文件
func (t *M4SStream) PusherToFile(contextC context.Context, filepath string, startFunc func(*M4SStream) error, stopFunc func(*M4SStream) error) error {
f := file.New(filepath, 0, false)
// 附加功能 savetojson
reply.SaveToJson.Init()
// 指定房间录制区间
- if err := recStartEnd.InitF.Run(mainCtx, c.C); err != nil {
+ if _, err := recStartEnd.InitF.Run(mainCtx, c.C); err != nil {
danmulog.Base("功能", "指定房间录制区间").L(`E: `, err)
} else {
- _ = recStartEnd.LoopCheck.Run(mainCtx, recStartEnd.StreamCtl{
+ _, _ = recStartEnd.LoopCheck.Run(mainCtx, recStartEnd.StreamCtl{
C: c.C,
State: reply.StreamOStatus,
Start: reply.StreamOStart,
})
}
// 指定弹幕重启录制
- if err := danmuReLiveTriger.Init.Run(mainCtx, danmuReLiveTriger.DanmuReLiveTriger{
+ if _, err := danmuReLiveTriger.Init.Run(mainCtx, danmuReLiveTriger.DanmuReLiveTriger{
StreamCut: reply.StreamOCut,
C: c.C,
}); err != nil {
}
// pgo gen
if file, ok := c.C.K_v.LoadV("生成pgo").(string); ok {
- if e := genCpuPprof.Start.Run(mainCtx, file); e != nil {
+ if _, e := genCpuPprof.Start.Run(mainCtx, file); e != nil {
danmulog.Base("功能", "生成pgo").L(`E: `, e)
}
}
{ //附加功能 进房间发送弹幕 直播流保存 每日签到
go F.Dosign()
go reply.Entry_danmu()
- if e := recStartEnd.RecStartCheck.Run(mainCtx, c.C); e == nil {
+ if _, e := recStartEnd.RecStartCheck.Run(mainCtx, c.C); e == nil {
go reply.StreamOStart(c.C.Roomid)
} else {
danmulog.Base("功能", "指定房间录制区间").L(`I: `, c.C.Roomid, e)
require (
github.com/gotk3/gotk3 v0.6.2
github.com/mdp/qrterminal/v3 v3.2.0
- github.com/qydysky/part v0.28.20240115133204
+ github.com/qydysky/part v0.28.20240121080746
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
require (
github.com/google/uuid v1.5.0
- golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc
+ golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
)
require (
lukechampine.com/uint128 v1.3.0 // indirect
modernc.org/cc/v3 v3.41.0 // indirect
modernc.org/ccgo/v3 v3.16.15 // indirect
- modernc.org/libc v1.39.0 // indirect
+ modernc.org/libc v1.40.6 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
modernc.org/opt v0.1.3 // indirect
)
require (
- github.com/andybalholm/brotli v1.0.6
+ github.com/andybalholm/brotli v1.1.0
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/lib/pq v1.10.9
- github.com/miekg/dns v1.1.57 // indirect
+ github.com/miekg/dns v1.1.58 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/mod v0.14.0 // indirect
- golang.org/x/net v0.19.0 // indirect
+ golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
- golang.org/x/tools v0.16.1 // indirect
+ golang.org/x/tools v0.17.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/sqlite v1.28.0
rsc.io/qr v0.2.0 // indirect
-github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
-github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
+github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mdp/qrterminal/v3 v3.2.0 h1:qteQMXO3oyTK4IHwj2mWsKYYRBOp1Pj2WRYFYYNTCdk=
github.com/mdp/qrterminal/v3 v3.2.0/go.mod h1:XGGuua4Lefrl7TLEsSONiD+UEjQXJZ4mPzF+gWYIJkk=
-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/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
+github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
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.20240115133204 h1:z4vnZoSc+zdgziEHsYzXt9Ou4/Bx/bL/OUxSm007HNs=
-github.com/qydysky/part v0.28.20240115133204/go.mod h1:NyKyjpBCSjcHtKlC+fL5lCidm57UCnwEgufiBDs5yxA=
+github.com/qydysky/part v0.28.20240121080746 h1:UP+d1R9oD0/SN32FUk4/V+2bQbOICv/8rxQ6FRtZT0c=
+github.com/qydysky/part v0.28.20240121080746/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=
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
-golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
-golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
+golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
+golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
-golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
-golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
-golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
+golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
+golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
-golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
+golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
+golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
-modernc.org/libc v1.39.0 h1:/v8cVz/qd6qrT2tmDgpLgFV2ujUkgX3TpXFVGki0ODs=
-modernc.org/libc v1.39.0/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE=
+modernc.org/libc v1.40.6 h1:141JHq3SjhOOCjECBgD4K8VgTFOy19CnHwroC08DAig=
+modernc.org/libc v1.40.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=