|
|
|
@ -2,18 +2,19 @@ package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"flag"
|
|
|
|
|
"fmt"
|
|
|
|
|
"github.com/q191201771/lal/pkg/httpflv"
|
|
|
|
|
"github.com/q191201771/lal/pkg/rtmp"
|
|
|
|
|
"github.com/q191201771/nezha/pkg/errors"
|
|
|
|
|
"github.com/q191201771/nezha/pkg/bininfo"
|
|
|
|
|
"github.com/q191201771/nezha/pkg/log"
|
|
|
|
|
"io"
|
|
|
|
|
"os"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 将flv文件通过rtmp协议推送至rtmp服务器
|
|
|
|
|
//rtmp推流客户端,输入是本地flv文件,文件推送完毕后,可循环推送(rtmp push流并不断开)
|
|
|
|
|
//
|
|
|
|
|
// -r 表示当文件推送完毕后,是否循环推送(rtmp push流并不断开)
|
|
|
|
|
// -r 为1时表示当文件推送完毕后,是否循环推送(rtmp push流并不断开)
|
|
|
|
|
//
|
|
|
|
|
// Usage:
|
|
|
|
|
// ./bin/flvfile2rtmppush -r 1 -i /tmp/test.flv -o rtmp://push.xxx.com/live/testttt
|
|
|
|
@ -23,13 +24,15 @@ func main() {
|
|
|
|
|
|
|
|
|
|
flvFileName, rtmpPushURL, isRecursive := parseFlag()
|
|
|
|
|
|
|
|
|
|
log.Info(bininfo.StringifySingleLine())
|
|
|
|
|
|
|
|
|
|
ps := rtmp.NewPushSession(rtmp.PushSessionTimeout{
|
|
|
|
|
ConnectTimeoutMS:3000,
|
|
|
|
|
PushTimeoutMS:5000,
|
|
|
|
|
WriteAVTimeoutMS:10000,
|
|
|
|
|
ConnectTimeoutMS: 3000,
|
|
|
|
|
PushTimeoutMS: 5000,
|
|
|
|
|
WriteAVTimeoutMS: 10000,
|
|
|
|
|
})
|
|
|
|
|
err = ps.Push(rtmpPushURL)
|
|
|
|
|
errors.PanicIfErrorOccur(err)
|
|
|
|
|
log.FatalIfErrorNotNil(err)
|
|
|
|
|
log.Infof("push succ. url=%s", rtmpPushURL)
|
|
|
|
|
|
|
|
|
|
var totalBaseTS uint32
|
|
|
|
@ -43,11 +46,11 @@ func main() {
|
|
|
|
|
|
|
|
|
|
var ffr httpflv.FlvFileReader
|
|
|
|
|
err = ffr.Open(flvFileName)
|
|
|
|
|
errors.PanicIfErrorOccur(err)
|
|
|
|
|
log.FatalIfErrorNotNil(err)
|
|
|
|
|
log.Infof("open succ. filename=%s", flvFileName)
|
|
|
|
|
|
|
|
|
|
flvHeader, err := ffr.ReadFlvHeader()
|
|
|
|
|
errors.PanicIfErrorOccur(err)
|
|
|
|
|
log.FatalIfErrorNotNil(err)
|
|
|
|
|
log.Infof("read flv header succ. %v", flvHeader)
|
|
|
|
|
|
|
|
|
|
hasReadThisBaseTS = false
|
|
|
|
@ -58,7 +61,7 @@ func main() {
|
|
|
|
|
log.Info("EOF")
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
errors.PanicIfErrorOccur(err)
|
|
|
|
|
log.FatalIfErrorNotNil(err)
|
|
|
|
|
|
|
|
|
|
// TODO chef: 转换代码放入lal某个包中
|
|
|
|
|
var h rtmp.Header
|
|
|
|
@ -81,7 +84,7 @@ func main() {
|
|
|
|
|
//log.Debugf("CHEFERASEME write metadata.")
|
|
|
|
|
chunks := rtmp.Message2Chunks(tag.Raw[11:11+h.MsgLen], &h, rtmp.LocalChunkSize)
|
|
|
|
|
err = ps.TmpWrite(chunks)
|
|
|
|
|
errors.PanicIfErrorOccur(err)
|
|
|
|
|
log.FatalIfErrorNotNil(err)
|
|
|
|
|
} else {
|
|
|
|
|
// noop
|
|
|
|
|
}
|
|
|
|
@ -114,7 +117,7 @@ func main() {
|
|
|
|
|
time.Sleep(time.Duration(diff) * time.Millisecond)
|
|
|
|
|
//log.Debug("send")
|
|
|
|
|
err = ps.TmpWrite(chunks)
|
|
|
|
|
errors.PanicIfErrorOccur(err)
|
|
|
|
|
log.FatalIfErrorNotNil(err)
|
|
|
|
|
prevTS = h.Timestamp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -128,10 +131,15 @@ func main() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseFlag() (string, string, bool) {
|
|
|
|
|
v := flag.Bool("v", false, "show bin info")
|
|
|
|
|
i := flag.String("i", "", "specify flv file")
|
|
|
|
|
o := flag.String("o", "", "specify rtmp push url")
|
|
|
|
|
r := flag.Bool("r", false, "recursive push if reach end of file")
|
|
|
|
|
flag.Parse()
|
|
|
|
|
if *v {
|
|
|
|
|
_, _ = fmt.Fprint(os.Stderr, bininfo.StringifyMultiLine())
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
if *i == "" || *o == "" {
|
|
|
|
|
flag.Usage()
|
|
|
|
|
os.Exit(1)
|
|
|
|
|