|
|
@ -9,11 +9,13 @@
|
|
|
|
package main
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
"encoding/hex"
|
|
|
|
|
|
|
|
"flag"
|
|
|
|
"flag"
|
|
|
|
|
|
|
|
"os"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/q191201771/lal/pkg/base"
|
|
|
|
"github.com/q191201771/lal/pkg/base"
|
|
|
|
"github.com/q191201771/lal/pkg/httpflv"
|
|
|
|
"github.com/q191201771/lal/pkg/httpflv"
|
|
|
|
|
|
|
|
"github.com/q191201771/lal/pkg/rtmp"
|
|
|
|
|
|
|
|
"github.com/q191201771/naza/pkg/bele"
|
|
|
|
"github.com/q191201771/naza/pkg/nazalog"
|
|
|
|
"github.com/q191201771/naza/pkg/nazalog"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
@ -30,27 +32,74 @@ func main() {
|
|
|
|
defer nazalog.Sync()
|
|
|
|
defer nazalog.Sync()
|
|
|
|
base.LogoutStartInfo()
|
|
|
|
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()
|
|
|
|
session := httpflv.NewPullSession()
|
|
|
|
err := session.Pull(url, func(tag httpflv.Tag) {
|
|
|
|
err = session.Pull(url, func(tag httpflv.Tag) {
|
|
|
|
switch tag.Header.Type {
|
|
|
|
if tag.Header.Type == httpflv.TagTypeMetadata {
|
|
|
|
case httpflv.TagTypeMetadata:
|
|
|
|
// 根据metadata填写flv头
|
|
|
|
nazalog.Info(hex.Dump(tag.Payload()))
|
|
|
|
opa, err := rtmp.ParseMetadata(tag.Payload())
|
|
|
|
case httpflv.TagTypeAudio:
|
|
|
|
if err != nil {
|
|
|
|
case httpflv.TagTypeVideo:
|
|
|
|
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)
|
|
|
|
nazalog.Assert(nil, err)
|
|
|
|
err = <-session.WaitChan()
|
|
|
|
err = <-session.WaitChan()
|
|
|
|
nazalog.Assert(nil, err)
|
|
|
|
nazalog.Assert(nil, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func parseFlag() string {
|
|
|
|
func parseFlag() (url, flvfile string) {
|
|
|
|
url := flag.String("i", "", "specify http-flv url")
|
|
|
|
i := flag.String("i", "", "specify http-flv url")
|
|
|
|
|
|
|
|
o := flag.String("o", "", "specify output flv file")
|
|
|
|
flag.Parse()
|
|
|
|
flag.Parse()
|
|
|
|
if *url == "" {
|
|
|
|
if *i == "" || *o == "" {
|
|
|
|
flag.Usage()
|
|
|
|
flag.Usage()
|
|
|
|
base.OsExitAndWaitPressIfWindows(1)
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|