You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lal/app/flvfile2rtmppush/flvfile2rtmppush.go

104 lines
2.3 KiB
Go

package main
import (
"flag"
"github.com/q191201771/lal/pkg/httpflv"
"github.com/q191201771/lal/pkg/rtmp"
"github.com/q191201771/nezha/pkg/errors"
"github.com/q191201771/nezha/pkg/log"
"io"
"os"
"time"
)
// 将flv文件通过rtmp协议推送至rtmp服务器
//
// -r 表示当文件推送完毕后,是否循环推送
//
// Usage:
// ./bin/flvfile2rtmppush -r 1 -i /tmp/test.flv -o rtmp://push.xxx.com/live/testttt
func main() {
var err error
flvFileName, rtmpPushURL, isRecursive := parseFlag()
ps := rtmp.NewPushSession(5000)
err = ps.Push(rtmpPushURL)
errors.PanicIfErrorOccur(err)
log.Infof("push succ.")
var baseTS int
var prevTS int
for {
var ffr httpflv.FlvFileReader
err = ffr.Open(flvFileName)
errors.PanicIfErrorOccur(err)
log.Infof("open succ.")
flvHeader, err := ffr.ReadFlvHeader()
errors.PanicIfErrorOccur(err)
log.Infof("read flv header succ. %v", flvHeader)
for {
tag, err := ffr.ReadTag()
if err == io.EOF {
log.Info("EOF")
break
}
errors.PanicIfErrorOccur(err)
// TODO chef: 转换代码放入lal某个包中
var h rtmp.Header
h.MsgLen = int(tag.Header.DataSize) //len(tag.Raw)-httpflv.TagHeaderSize
h.Timestamp = int(tag.Header.Timestamp) + int(baseTS)
h.MsgTypeID = int(tag.Header.T)
h.MsgStreamID = rtmp.MSID1
switch tag.Header.T {
case httpflv.TagTypeMetadata:
h.CSID = rtmp.CSIDAMF
case httpflv.TagTypeAudio:
h.CSID = rtmp.CSIDAudio
case httpflv.TagTypeVideo:
h.CSID = rtmp.CSIDVideo
}
var diff int
if h.Timestamp >= prevTS {
diff = int(h.Timestamp) - prevTS
} else {
h.Timestamp = prevTS
}
chunks := rtmp.Message2Chunks(tag.Raw[11:11+h.MsgLen], &h, rtmp.LocalChunkSize)
log.Debugf("before send. diff=%d, ts=%d, prevTS=%d", diff, h.Timestamp, prevTS)
time.Sleep(time.Duration(diff) * time.Millisecond)
log.Debug("send")
err = ps.TmpWrite(chunks)
errors.PanicIfErrorOccur(err)
prevTS = h.Timestamp
}
baseTS = prevTS + 1
ffr.Dispose()
if !isRecursive {
break
}
}
}
func parseFlag() (string, string, bool) {
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 *i == "" || *o == "" {
flag.Usage()
os.Exit(1)
}
return *i, *o, *r
}