diff --git a/app/demo/pullhttpflv/pullhttpflv.go b/app/demo/pullhttpflv/pullhttpflv.go index fe6f51b..d7689d6 100644 --- a/app/demo/pullhttpflv/pullhttpflv.go +++ b/app/demo/pullhttpflv/pullhttpflv.go @@ -9,11 +9,13 @@ package main import ( - "encoding/hex" "flag" + "os" "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/httpflv" + "github.com/q191201771/lal/pkg/rtmp" + "github.com/q191201771/naza/pkg/bele" "github.com/q191201771/naza/pkg/nazalog" ) @@ -30,27 +32,74 @@ func main() { defer nazalog.Sync() base.LogoutStartInfo() - url := parseFlag() + url, flvname := parseFlag() + flvfile, err := os.Create(flvname) + if err != nil { + nazalog.Errorf("create flv file failed, err=%+v", err) + return + } + + defer flvfile.Close() + session := httpflv.NewPullSession() - err := session.Pull(url, func(tag httpflv.Tag) { - switch tag.Header.Type { - case httpflv.TagTypeMetadata: - nazalog.Info(hex.Dump(tag.Payload())) - case httpflv.TagTypeAudio: - case httpflv.TagTypeVideo: + err = session.Pull(url, func(tag httpflv.Tag) { + if tag.Header.Type == httpflv.TagTypeMetadata { + // 根据metadata填写flv头 + opa, err := rtmp.ParseMetadata(tag.Payload()) + if err != nil { + nazalog.Errorf("ParseMetadata failed, err=%+v", err) + return + } + + b := make([]byte, 13) + var flags uint8 + + audiocodecid := opa.Find("audiocodecid") + videocodecid := opa.Find("videocodecid") + if audiocodecid != 0 { + flags |= 0x04 + } + + if videocodecid != 0 { + flags |= 0x01 + } + + writeFlvHeader(b, flags) + flvfile.Write(b) } + + nazalog.Infof("tag Type:%d, tag Size:%d", tag.Header.Type, tag.Header.DataSize) + + flvfile.Write(tag.Raw) }) nazalog.Assert(nil, err) err = <-session.WaitChan() nazalog.Assert(nil, err) } -func parseFlag() string { - url := flag.String("i", "", "specify http-flv url") +func parseFlag() (url, flvfile string) { + i := flag.String("i", "", "specify http-flv url") + o := flag.String("o", "", "specify output flv file") flag.Parse() - if *url == "" { + if *i == "" || *o == "" { flag.Usage() base.OsExitAndWaitPressIfWindows(1) } - return *url + return *i, *o +} + +func writeFlvHeader(b []byte, flags uint8) { + + // 'FLV', version 1 + bele.BePutUint32(b, 0x464c5601) + b[4] = flags + + // DataOffset: UI32 Offset in bytes from start of file to start of body (that is, size of header) + // The DataOffset field usually has a value of 9 for FLV version 1. + bele.BePutUint32(b[5:9], 9) + + // PreviousTagSize0: UI32 Always 0 + bele.BePutUint32(b[9:13], 0) + + return }