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/pkg/rtmp/stream.go

118 lines
2.8 KiB
Go

// Copyright 2019, Chef. All rights reserved.
// https://github.com/q191201771/lal
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package rtmp
import (
"encoding/hex"
"fmt"
"github.com/q191201771/naza/pkg/nazabytes"
"github.com/q191201771/lal/pkg/base"
"github.com/q191201771/naza/pkg/nazalog"
)
// ----- Stream --------------------------------------------------------------------------------------------------------
type Stream struct {
header base.RtmpHeader
msg StreamMsg
timestamp uint32 // 注意是rtmp chunk协议header中的时间戳可能是绝对的也可能是相对的。上层不应该使用这个字段而应该使用Header.TimestampAbs
}
func NewStream() *Stream {
return &Stream{
msg: StreamMsg{
buff: nazabytes.NewBuffer(initMsgLen),
},
}
}
// 序列化成可读字符串,一般用于发生错误时打印日志
func (stream *Stream) toDebugString() string {
return fmt.Sprintf("header=%+v, b=%s, hex=%s",
stream.header, stream.msg.buff.DebugString(), hex.Dump(stream.msg.buff.Peek(4096)))
}
func (stream *Stream) toAvMsg() base.RtmpMsg {
// TODO chef: 考虑可能出现header中的len和buf的大小不一致的情况
if stream.header.MsgLen != uint32(stream.msg.buff.Len()) {
nazalog.Errorf("toAvMsg. headerMsgLen=%d, bufLen=%d", stream.header.MsgLen, stream.msg.buff.Len())
}
return base.RtmpMsg{
Header: stream.header,
Payload: stream.msg.buff.Bytes(),
}
}
// ----- StreamMsg -----------------------------------------------------------------------------------------------------
type StreamMsg struct {
buff *nazabytes.Buffer
}
// 确保可写空间,如果不够会扩容
func (msg *StreamMsg) Grow(n uint32) {
msg.buff.Grow(int(n))
}
func (msg *StreamMsg) Len() uint32 {
return uint32(msg.buff.Len())
}
func (msg *StreamMsg) Flush(n uint32) {
msg.buff.Flush(int(n))
}
func (msg *StreamMsg) Skip(n uint32) {
msg.buff.Skip(int(n))
}
func (msg *StreamMsg) Reset() {
msg.buff.Reset()
}
func (msg *StreamMsg) peekStringWithType() (string, error) {
str, _, err := Amf0.ReadString(msg.buff.Bytes())
return str, err
}
func (msg *StreamMsg) readStringWithType() (string, error) {
str, l, err := Amf0.ReadString(msg.buff.Bytes())
if err == nil {
msg.Skip(uint32(l))
}
return str, err
}
func (msg *StreamMsg) readNumberWithType() (int, error) {
val, l, err := Amf0.ReadNumber(msg.buff.Bytes())
if err == nil {
msg.Skip(uint32(l))
}
return int(val), err
}
func (msg *StreamMsg) readObjectWithType() (ObjectPairArray, error) {
opa, l, err := Amf0.ReadObject(msg.buff.Bytes())
if err == nil {
msg.Skip(uint32(l))
}
return opa, err
}
func (msg *StreamMsg) readNull() error {
l, err := Amf0.ReadNull(msg.buff.Bytes())
if err == nil {
msg.Skip(uint32(l))
}
return err
}