123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- package record
- import (
- _ "embed"
- "errors"
- "io"
- "sync"
- . "m7s.live/engine/v4"
- "m7s.live/engine/v4/codec"
- "m7s.live/engine/v4/config"
- "m7s.live/engine/v4/util"
- )
- type RecordConfig struct {
- DefaultYaml
- config.Subscribe
- Flv Record
- Mp4 Record
- Hls Record
- Raw Record
- RawAudio Record
- recordings sync.Map
- }
- //go:embed default.yaml
- var defaultYaml DefaultYaml
- var ErrRecordExist = errors.New("recorder exist")
- var RecordPluginConfig = &RecordConfig{
- DefaultYaml: defaultYaml,
- Flv: Record{
- Path: "record/flv",
- Ext: ".flv",
- GetDurationFn: getFLVDuration,
- },
- Mp4: Record{
- Path: "record/mp4",
- Ext: ".mp4",
- },
- Hls: Record{
- Path: "record/hls",
- Ext: ".m3u8",
- },
- Raw: Record{
- Path: "record/raw",
- Ext: ".", // 默认h264扩展名为.h264,h265扩展名为.h265
- },
- RawAudio: Record{
- Path: "record/raw",
- Ext: ".", // 默认aac扩展名为.aac,pcma扩展名为.pcma,pcmu扩展名为.pcmu
- },
- }
- var plugin = InstallPlugin(RecordPluginConfig)
- func (conf *RecordConfig) OnEvent(event any) {
- switch v := event.(type) {
- case FirstConfig, config.Config:
- conf.Flv.Init()
- conf.Mp4.Init()
- conf.Hls.Init()
- conf.Raw.Init()
- conf.RawAudio.Init()
- case SEclose:
- streamPath := v.Target.Path
- delete(conf.Flv.recording, streamPath)
- delete(conf.Mp4.recording, streamPath)
- delete(conf.Hls.recording, streamPath)
- delete(conf.Raw.recording, streamPath)
- delete(conf.RawAudio.recording, streamPath)
- case SEpublish:
- streamPath := v.Target.Path
- if conf.Flv.NeedRecord(streamPath) {
- var flv FLVRecorder
- conf.Flv.recording[streamPath] = &flv
- go flv.Start(streamPath)
- }
- if conf.Mp4.NeedRecord(streamPath) {
- recoder := NewMP4Recorder()
- conf.Mp4.recording[streamPath] = recoder
- go recoder.Start(streamPath)
- }
- if conf.Hls.NeedRecord(streamPath) {
- var hls HLSRecorder
- conf.Hls.recording[streamPath] = &hls
- go hls.Start(streamPath)
- }
- if conf.Raw.NeedRecord(streamPath) {
- var raw RawRecorder
- conf.Raw.recording[streamPath] = &raw
- go raw.Start(streamPath)
- }
- if conf.RawAudio.NeedRecord(streamPath) {
- var raw RawRecorder
- raw.IsAudio = true
- conf.RawAudio.recording[streamPath] = &raw
- go raw.Start(streamPath)
- }
- }
- }
- func (conf *RecordConfig) getRecorderConfigByType(t string) (recorder *Record) {
- switch t {
- case "flv":
- recorder = &conf.Flv
- case "mp4":
- recorder = &conf.Mp4
- case "hls":
- recorder = &conf.Hls
- case "raw":
- recorder = &conf.Raw
- case "raw_audio":
- recorder = &conf.RawAudio
- }
- return
- }
- func getFLVDuration(file io.ReadSeeker) uint32 {
- _, err := file.Seek(-4, io.SeekEnd)
- if err == nil {
- var tagSize uint32
- if tagSize, err = util.ReadByteToUint32(file, true); err == nil {
- _, err = file.Seek(-int64(tagSize)-4, io.SeekEnd)
- if err == nil {
- _, timestamp, _, err := codec.ReadFLVTag(file)
- if err == nil {
- return timestamp
- }
- }
- }
- }
- return 0
- }
|