mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-04 07:56:33 +08:00
101 lines
1.9 KiB
Go
101 lines
1.9 KiB
Go
package rtmpt
|
|
|
|
import (
|
|
"bufio"
|
|
"errors"
|
|
"github.com/deepch/vdk/av"
|
|
"github.com/deepch/vdk/codec/h264parser"
|
|
"github.com/deepch/vdk/format/flv/flvio"
|
|
"github.com/deepch/vdk/utils/bits/pio"
|
|
"io"
|
|
"net/http"
|
|
)
|
|
|
|
func Dial(uri string) (*Conn, error) {
|
|
req, err := http.NewRequest("GET", uri, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
c := Conn{
|
|
conn: res.Body,
|
|
reader: bufio.NewReaderSize(res.Body, pio.RecommendBufioSize),
|
|
buf: make([]byte, 256),
|
|
}
|
|
|
|
if _, err = io.ReadFull(c.reader, c.buf[:flvio.FileHeaderLength]); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
flags, n, err := flvio.ParseFileHeader(c.buf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if flags&flvio.FILE_HAS_VIDEO == 0 {
|
|
return nil, errors.New("not supported")
|
|
}
|
|
|
|
if _, err = c.reader.Discard(n); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &c, nil
|
|
}
|
|
|
|
type Conn struct {
|
|
conn io.ReadCloser
|
|
reader *bufio.Reader
|
|
buf []byte
|
|
}
|
|
|
|
func (c *Conn) Streams() ([]av.CodecData, error) {
|
|
for {
|
|
tag, _, err := flvio.ReadTag(c.reader, c.buf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if tag.Type != flvio.TAG_VIDEO || tag.AVCPacketType != flvio.AAC_SEQHDR {
|
|
continue
|
|
}
|
|
|
|
stream, err := h264parser.NewCodecDataFromAVCDecoderConfRecord(tag.Data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return []av.CodecData{stream}, nil
|
|
}
|
|
}
|
|
|
|
func (c *Conn) ReadPacket() (av.Packet, error) {
|
|
for {
|
|
tag, ts, err := flvio.ReadTag(c.reader, c.buf)
|
|
if err != nil {
|
|
return av.Packet{}, err
|
|
}
|
|
|
|
if tag.Type != flvio.TAG_VIDEO || tag.AVCPacketType != flvio.AVC_NALU {
|
|
continue
|
|
}
|
|
|
|
return av.Packet{
|
|
Idx: 0,
|
|
Data: tag.Data,
|
|
CompositionTime: flvio.TsToTime(tag.CompositionTime),
|
|
IsKeyFrame: tag.FrameType == flvio.FRAME_KEY,
|
|
Time: flvio.TsToTime(ts),
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
func (c *Conn) Close() (err error) {
|
|
return c.conn.Close()
|
|
}
|