diff --git a/main.go b/main.go index 66198bd..73dcb1a 100644 --- a/main.go +++ b/main.go @@ -18,8 +18,9 @@ var config struct { ListenAddrTLS string CertFile string KeyFile string + AutoPullList map[string]string } -var streamPathReg = regexp.MustCompile("/(hdl/)?((.+)(\\.flv)|(.+))") +var streamPathReg = regexp.MustCompile(`/(hdl/)?((.+)(\.flv)|(.+))`) func init() { InstallPlugin(&PluginConfig{ @@ -37,6 +38,11 @@ func run() { utils.Print(Green("HDL start reuse gateway port")) http.HandleFunc("/hdl/", HDLHandler) } + for streamPath, url := range config.AutoPullList { + if err := PullStream(streamPath, url); err != nil { + utils.Println(err) + } + } } func HDLHandler(w http.ResponseWriter, r *http.Request) { diff --git a/pull.go b/pull.go new file mode 100644 index 0000000..2df227a --- /dev/null +++ b/pull.go @@ -0,0 +1,51 @@ +package hdl + +import ( + "errors" + "io" + "net/http" + "time" + + . "github.com/Monibuca/engine/v3" + "github.com/Monibuca/utils/v3/codec" +) + +func PullStream(streamPath, url string) error { + if res, err := http.Get(url); err == nil { + stream := Stream{ + Type: "HDL Pull", + StreamPath: streamPath, + } + if stream.Publish() { + defer stream.Close() + head := make([]byte, len(codec.FLVHeader)) + io.ReadFull(res.Body, head) + var lastTime uint32 + at := stream.NewAudioTrack(0) + vt := stream.NewVideoTrack(0) + for { + if t, timestamp, payload, err := codec.ReadFLVTag(res.Body); err == nil { + switch t { + case codec.FLV_TAG_TYPE_AUDIO: + at.PushByteStream(timestamp, payload) + case codec.FLV_TAG_TYPE_VIDEO: + if timestamp != 0 { + if lastTime == 0 { + lastTime = timestamp + } + } + vt.PushByteStream(timestamp, payload) + time.Sleep(time.Duration(timestamp-lastTime) * time.Millisecond) + lastTime = timestamp + } + } else { + return err + } + } + } else { + return errors.New("Bad Name") + } + } else { + return err + } +}