diff --git a/example/qiaopin/config.yaml b/example/qiaopin/config.yaml new file mode 100644 index 0000000..52f2a6a --- /dev/null +++ b/example/qiaopin/config.yaml @@ -0,0 +1,51 @@ +global: + loglevel: trace + http: :8080 + tcp: :50052 +rtsp: + tcp: + listenaddr: :8554 +# pull: + #live/kqnmg3ikb: rtsp://192.168.4.101:8554/main + # live/h264: rtsp://localhost:6554/h264.mp4 + # live/h265: rtsp://localhost:6554/h265.mp4 +# + + +webrtc: + enable: false +rtmp: + tcp: + listenaddr: :11935 + + +logrotate: + level: trace + #formatter: 2006-01-02T15:04 # 分钟 + formatter: 2006-01-02T15 # 小时 +mp4: + # enable: false + delpart: 0 # -1表示不删除,0表示第0个,1表示第1个,比如 live/test ,0 就是删除 live,以此类推。如果大于分段,则不删除 + # pull: + # record/test: record/live/test?start=2024-09-12T10:25:00 + publish: + delayclosetimeout: 1s + onpub: + record: + ^live.*: + fragment: 10s + filepath: record/$0 +# +#transcode: +# onpub: +# transform: +# live/kqnmg3ikb: +# output: +# - target: "srt://push.arbor3d.cn:9000?streamid=#!::h=push.arbor3d.cn,r=live/fnewr85ca,txSecret=f5ee9cb891501d63328571c86f279ab0,txTime=68DFF300" +# conf: -c:v hevc_nvmpi -b:v 3M -maxrate 4M -bufsize 2M -g 30 -an -s 2560x1280 -r 24 +# live/test: +# input: +# mode: rtmp +# output: +# - target: "rtmp://127.0.0.1:11935/live/test/h265" +# conf: -c:v hevc -b:v 3M -maxrate 4M -bufsize 2M -g 30 -an -s 320x240 -r 24 diff --git a/example/qiaopin/main.go b/example/qiaopin/main.go new file mode 100644 index 0000000..014d34f --- /dev/null +++ b/example/qiaopin/main.go @@ -0,0 +1,97 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "os" + "path/filepath" + "strings" + "time" + + "gopkg.in/yaml.v3" + m7s "m7s.live/pro" + _ "m7s.live/pro/plugin/console" + _ "m7s.live/pro/plugin/debug" + _ "m7s.live/pro/plugin/flv" + _ "m7s.live/pro/plugin/gb28181" + _ "m7s.live/pro/plugin/logrotate" + _ "m7s.live/pro/plugin/monitor" + _ "m7s.live/pro/plugin/mp4" + mp4 "m7s.live/pro/plugin/mp4/pkg" + _ "m7s.live/pro/plugin/preview" + _ "m7s.live/pro/plugin/rtmp" + _ "m7s.live/pro/plugin/rtsp" + _ "m7s.live/pro/plugin/sei" + _ "m7s.live/pro/plugin/srt" + _ "m7s.live/pro/plugin/stress" + _ "m7s.live/pro/plugin/transcode" + _ "m7s.live/pro/plugin/webrtc" +) + +func getValue(yamlData map[string]interface{}, keys ...string) interface{} { + current := yamlData + + for _, key := range keys { + if value, exists := current[key]; exists { + switch v := value.(type) { + case map[string]interface{}: + current = v + default: + return v // 返回找到的值 + } + } else { + return nil // 如果节点不存在,返回 nil + } + } + + return nil // 如果没有找到,返回 nil +} + +func main() { + conf := flag.String("c", "config.yaml", "config file") + flag.Parse() + // job.StreamPath live/test/001 + // job.FilePath record/live/test/001 + + confData, err := os.ReadFile(*conf) + if err != nil { + panic(err) + } + var confMap map[string]any + err = yaml.Unmarshal(confData, &confMap) + if err != nil { + panic(err) + } + delPart := -1 + delPartVal := getValue(confMap, "mp4", "delpart") + if tmp, ok := delPartVal.(int); ok { + delPart = tmp + } + println(delPart) + + mp4.CustomFileName = func(job *m7s.RecordJob) string { + + fileDir := strings.ReplaceAll(job.FilePath, job.StreamPath, "") + if err := os.MkdirAll(fileDir, 0755); err != nil { + log.Default().Printf("创建目录失败:%s", err) + return fmt.Sprintf("%s_%s%s", job.StreamPath, time.Now().Local().Format("2006-01-02-15-04-05"), ".mp4") + } + + var recordName string + + streamParts := strings.Split(job.StreamPath, "/") + if delPart >= 0 && delPart < len(streamParts) { + // 删除第i个元素 + streamParts = append(streamParts[:delPart], streamParts[delPart+1:]...) + } + + recordName = strings.Join(streamParts, "_") + recordName = fmt.Sprintf("%s_%s%s", recordName, time.Now().Local().Format("2006-01-02-15-04-05"), ".mp4") + recordName = filepath.Join(fileDir, recordName) + return recordName + } + // ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(time.Second*100)) + m7s.Run(context.Background(), *conf) +}