rtmp

package
v0.0.0-...-b4eff69 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2021 License: Apache-2.0, MIT Imports: 23 Imported by: 0

README

RTMP

The RTMP package (and it's subordinate packages) are dual licensed with both Apache2 and MIT licenses.

This code is a working fork of github.com/gwuhaolin/livego and as part of the original MIT license we are distributing this license.

Refactoring

I am currently refactoring a lot of this library to make it more extensible.

I plan on adding unit tests, and adding some better idomatic Go practices.

I have no longterm plans for this, and will maintain the original license and host the source code here.

Original credit goes to the original author.

Documentation

Index

Constants

View Source
const (

	// TimeoutDurationSeconds is the timeout used for all
	// connection timeouts.
	TimeoutDurationSeconds time.Duration = 1 * time.Second

	DefaultRTMPChunkSizeBytes             uint32 = 128
	DefaultRTMPChunkSizeBytesLarge        uint32 = DefaultRTMPChunkSizeBytes * 64
	DefaultWindowAcknowledgementSizeBytes uint32 = 2500000
	DefaultPeerBandwidthSizeBytes         uint32 = 2500000
	DefaultMaximumPoolSizeBytes           int    = 1024 * 1024 * 512
	DefaultConnBufferSizeBytes            int    = 1024 * 1024 * 512
	DefaultServerFMSVersion               string = "FMS/3,0,1,123"

	ClientMethodPlay    ClientMethod = "play"
	ClientMethodPublish ClientMethod = "publish"

	PublishCommandLive   string = "live"
	PublishCommandRecord string = "record"
	PublishCommandAppend string = "append"

	CommandConnect         string = "connect"
	CommandCreateStream    string = "createStream"
	CommandPlay            string = "play"
	CommandPublish         string = "publish"
	CommandDeleteStream    string = "deleteStream"
	CommandGetStreamLength string = "getStreamLength"

	CommandReleaseStream  string = "releaseStream"
	CommandFCPublish      string = "FCPublish"
	CommandFCUnpublish    string = "FCUnpublish"
	CommandFCSubscribe    string = "FCSubscribe"
	CommandFCUnsubscribed string = "FCUnsubscribe"

	CommandType_Result  = "_result"
	CommandType_Error   = "_error"
	CommandTypeOnStatus = "onStatus"

	CommandNetStreamPublishStart   = "NetStream.Publish.Start"
	CommandNetStreamPublishNotify  = "NetStream.Publish.Notify"
	CommandNetStreamPlayStart      = "NetStream.Play.Start"
	CommandNetStreamPlayReset      = "NetStream.Play.Reset"
	CommandNetStreamDataStart      = "NetStream.Data.Start"
	CommandNetStreamConnectSuccess = "NetConnection.Connect.Success"
	CommandOnBWDone                = "CommandOnBWDone"

	DataMessageOnMetaData = "onMetaData"

	StreamBegin      uint32 = 0
	StreamEOF        uint32 = 1
	StreamDry        uint32 = 2
	SetBufferLen     uint32 = 3
	StreamIsRecorded uint32 = 4

	UserMessagePingRequest  uint32 = 6
	UserMessagePingResponse uint32 = 7

	DefaultProtocol          string = "tcp"
	DefaultLocalHost         string = "localhost"
	DefaultLo                string = "127.0.0.1"
	DefaultLocalPort         string = "1935"
	DefaultScheme            string = "rtmp"
	DefaultRTMPApp           string = "twinx"
	DefaultGenerateKeyLength int    = 20
	DefaultGenerateKeyPrefix string = "twinx_"
	StreamKeyRandomBytePool  string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

	TAG_AUDIO                   uint32 = 8
	TAG_VIDEO                   uint32 = 9
	TAG_SCRIPTDATAAMF0          uint32 = 18
	TAG_SCRIPTDATAAMF3          uint32 = 0xf
	MetadatAMF0                 uint8  = 0x12
	MetadataAMF3                uint8  = 0xf
	SOUND_MP3                   uint8  = 2
	SOUND_NELLYMOSER_16KHZ_MONO uint8  = 4
	SOUND_NELLYMOSER_8KHZ_MONO  uint8  = 5
	SOUND_NELLYMOSER            uint8  = 6
	SOUND_ALAW                  uint8  = 7
	SOUND_MULAW                 uint8  = 8
	SOUND_AAC                   uint8  = 10
	SOUND_SPEEX                 uint8  = 11
	SOUND_5_5Khz                uint8  = 0
	SOUND_11Khz                 uint8  = 1
	SOUND_22Khz                 uint8  = 2
	SOUND_44Khz                 uint8  = 3
	SOUND_8BIT                  uint8  = 0
	SOUND_16BIT                 uint8  = 1
	SOUND_MONO                  uint8  = 0
	SOUND_STEREO                uint8  = 1
	AAC_SEQHDR                  uint8  = 0
	AAC_RAW                     uint8  = 1
	AVC_SEQHDR                  uint8  = 0
	AVC_NALU                    uint8  = 1
	AVC_EOS                     uint8  = 2
	FRAME_KEY                   uint8  = 1
	FRAME_INTER                 uint8  = 2
	VIDEO_H264                  uint8  = 7
)
View Source
const (
	ConnInfoKeyApp         string = "app"
	ConnInfoKeyType        string = "type"
	ConnInfoKeyTcURL       string = "tcUrl"
	ConnInfoKeyFlashVer    string = "flashVer"
	ConnInfoKeySWFURL      string = "swfUrl"
	ConnInfoObjectEncoding string = "objectEncoding"
)
View Source
const (
	ConnRespFMSVer       string = "fmsVer"
	ConnRespCapabilities string = "capabilities"
)
View Source
const (
	ConnEventLevel          string = "level"
	ConnEventCode           string = "code"
	ConnEventDescription    string = "description"
	ConnEventObjectEncoding string = "objectEncoding"
	ConnEventStatus         string = "status"
)
View Source
const (
	SetChunkSizeMessage   string = "setChunkSize"
	SetChunkSizeMessageID uint32 = 1

	AbortMessage   string = "abort"
	AbortMessageID uint32 = 2

	AcknowledgementMessage   string = "acknowledgement"
	AcknowledgementMessageID uint32 = 3

	WindowAcknowledgementSizeMessage   string = "windowAcknowledgementSize"
	WindowAcknowledgementSizeMessageID uint32 = 5

	SetPeerBandwidthMessage   string = "setPeerBandwidth"
	SetPeerBandwidthMessageID uint32 = 6

	UserControlMessage   string = "userControl"
	UserControlMessageID uint32 = 4

	CommandMessage       string = "command"
	CommandMessageAMF3ID uint32 = 17
	CommandMessageAMF0ID uint32 = 20

	DataMessage       string = "data"
	DataMessageAMF3ID uint32 = 15
	DataMessageAMF0ID uint32 = 18

	SharedObjectMessage       string = "sharedObject"
	SharedObjectMessageAMF3ID uint32 = 16
	SharedObjectMessageAMF0ID uint32 = 19

	AudioMessage   string = "audio"
	AudioMessageID uint32 = 8

	VideoMessage   string = "video"
	VideoMessageID uint32 = 9

	AggregateMessage   string = "aggregate"
	AggregateMessageID uint32 = 22

	// UnknownMessageID should never happen, but we default
	// all unknown message type IDs to this string
	UnknownMessageID = "UNKNOWN"
)
View Source
const (
	// MaximumPacketQueueRecords
	//
	// Similar to how HTTP-based transmission protocols like
	// HLS and DASH behave, RTMP too, breaks a multimedia
	// stream into fragments that are usually:
	//  - 64 bytes for audio
	//  - 128 bytes for video
	//
	// The size of the fragments can be negotiated between the client and the server.
	MaximumPacketQueueRecords int = 1024

	// SaveStaticMediaTimeIntervalMilliseconds
	//
	// The time delay (in MS) between saving static media
	SaveStaticMediaTimeIntervalMilliseconds int64 = 5000

	ReadTimeout  int = 10
	WriteTimeout int = 10
)
View Source
const (
	CommandConnectWellKnownID float64 = 1
)

Variables

View Source
var (
	HandshakeClientKey = []byte{
		'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
		'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ',
		'0', '0', '1',
		0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1,
		0x02, 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB,
		0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE,
	}
	HandshakeServerKey = []byte{
		'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
		'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
		'S', 'e', 'r', 'v', 'e', 'r', ' ',
		'0', '0', '1',
		0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1,
		0x02, 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB,
		0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE,
	}

	HandshakeClientPartial30 []byte = HandshakeClientKey[:30]
	HandshakeServerPartial36 []byte = HandshakeServerKey[:36]
)
View Source
var (
	DefaultUnimplementedError = errors.New("**UNIMPLEMENTED**")
)
View Source
var RoomKeys = &RoomKeysType{
	localCache: cache.New(cache.NoExpiration, 0),
}
View Source
var (
	WellKnownClosedClientError = errors.New("closed 🛑 client: EOF")
)

Functions

func CheckAppName

func CheckAppName(appname string) bool

func GetStaticPushUrlList

func GetStaticPushUrlList(appname string) ([]string, bool)

func PrintMetrics

func PrintMetrics(duration time.Duration)

Types

type Application

type Application struct {
	Appname    string   `mapstructure:"appname"`
	Live       bool     `mapstructure:"live"`
	Hls        bool     `mapstructure:"hls"`
	Flv        bool     `mapstructure:"flv"`
	Api        bool     `mapstructure:"api"`
	StaticPush []string `mapstructure:"static_push"`
}

type ChunkStream

type ChunkStream struct {
	// Timestamp of the message. This field can transport 4
	// bytes.
	Timestamp uint32

	// Length of the message payload. If the message header cannot
	// be elided, it should be included in the length. This field
	// occupies 3 bytes in the chunk header.
	Length uint32

	// A range of type IDs are reserved for protocol control
	// messages. These messages which propagate information are handled
	// by both RTMP Chunk Stream protocol and the higher-level protocol.
	// All other type IDs are available for use by the higher-level
	// protocol, and treated as opaque values by RTMP Chunk Stream. In
	// fact, nothing in RTMP Chunk Stream requires these values to be
	// used as a type; all (non-protocol) messages could be of the same
	// type, or the application could use this field to distinguish
	// simultaneous tracks rather than types. This field occupies 1 byte
	// in the chunk header.
	TypeID uint32

	// The message stream ID can be any arbitrary value.
	// Different message streams multiplexed onto the same chunk stream
	// are demultiplexed based on their message stream IDs. Beyond that,
	// as far as RTMP Chunk Stream is concerned, this is an opaque value.
	// This field occupies 4 bytes in the chunk header in little endian
	// format.
	StreamID uint32

	// Data is the set of bytes in the Chunk. The chunk payload.
	Data []byte

	Format uint32
	CSID   uint32
	// contains filtered or unexported fields
}

ChunkStream

5.1.

The format of a message that can be split into chunks to support multiplexing depends on a higher level protocol. The message format SHOULD however contain the following fields which are necessary for creating the chunks.

type ChunkStreamReader

type ChunkStreamReader interface {
	Read(x *ChunkStream) error
	NextChunk() (*ChunkStream, error)
}

type ChunkStreamRouter

type ChunkStreamRouter interface {
	// RoutePackets just reads packets and calls Route()
	RoutePackets() error

	Route(x *ChunkStream) error
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient() *Client

func (*Client) Client

func (c *Client) Client() *ClientConn

func (*Client) Dial

func (c *Client) Dial(address string) error

func (*Client) Play

func (c *Client) Play() error

func (*Client) Publish

func (c *Client) Publish() error

type ClientConn

type ClientConn struct {
	// contains filtered or unexported fields
}

func NewClientConn

func NewClientConn() *ClientConn

func (*ClientConn) Close

func (cc *ClientConn) Close()

func (*ClientConn) Dial

func (cc *ClientConn) Dial(address string) error

func (*ClientConn) Flush

func (cc *ClientConn) Flush() error

func (*ClientConn) GetStreamId

func (cc *ClientConn) GetStreamId() uint32

func (*ClientConn) LogDecodeBatch

func (cc *ClientConn) LogDecodeBatch(r io.Reader, ver amf.Version) (ret []interface{}, err error)

func (*ClientConn) NextChunk

func (cc *ClientConn) NextChunk() (*ChunkStream, error)

func (*ClientConn) Play

func (cc *ClientConn) Play() error

Play will attempt to start a Play stream with a configured server.

func (*ClientConn) Publish

func (cc *ClientConn) Publish() error

Publish will hang and attempt to start a Publish stream with a configured server.

func (*ClientConn) Read

func (cc *ClientConn) Read(c *ChunkStream) (err error)

func (*ClientConn) Route

func (cc *ClientConn) Route(x *ChunkStream) error

func (*ClientConn) RoutePackets

func (cc *ClientConn) RoutePackets() error

func (*ClientConn) Write

func (cc *ClientConn) Write(c *ChunkStream) error

type ClientMethod

type ClientMethod string

type CompliantMember

type CompliantMember interface {
	// contains filtered or unexported methods
}

CompliantMember is a member that validates that both servers and clients have associated methods to respond to each other.

This allows a clearer understanding of communication between the entities and ensures that we always offer support for both server and client functionality.

This is this packages interpretation of the RTMP spec, and our guarantees about our server and client code.

We us "RX" and "TX" to identify the direction of packets.

RX = Receive  : Packets coming from a remote to this process
TX = Transmit : Packets sending to a remote from this process

type Conn

type Conn struct {
	net.Conn
	URLAddr
	// contains filtered or unexported fields
}

Conn

Conn is the base type for all RTMP connections. Conn is embedded with native Go types

  • net.Conn
  • net.Addr
  • url.URL

Both ClientConn and ServerConn are extensions of base Conn

func NewConn

func NewConn(c net.Conn) *Conn

func (*Conn) Close

func (conn *Conn) Close()

func (*Conn) Flush

func (conn *Conn) Flush() error

func (*Conn) HandshakeClient

func (conn *Conn) HandshakeClient() (err error)

func (*Conn) HandshakeServer

func (conn *Conn) HandshakeServer() (err error)

func (*Conn) LocalAddr

func (conn *Conn) LocalAddr() net.Addr

func (*Conn) Read

func (conn *Conn) Read(c *ChunkStream) error

func (*Conn) RemoteAddr

func (conn *Conn) RemoteAddr() net.Addr

func (*Conn) SetDeadline

func (conn *Conn) SetDeadline(t time.Time) error

func (*Conn) Write

func (conn *Conn) Write(c *ChunkStream) error

type ConnEvent

type ConnEvent struct {
	Level          string `amf:"level"`
	Code           string `amf:"code"`
	Description    string `amf:"description"`
	ObjectEncoding int    `amf:"objectEncoding"`
}

func ConnEventMapToInstance

func ConnEventMapToInstance(i interface{}) (*ConnEvent, error)

type ConnResp

type ConnResp struct {
	FMSVer       string `amf:"fmsVer"`
	Capabilities int    `amf:"capabilities"`
}

type ConnectInfo

type ConnectInfo struct {
	App            string `amf:"app" json:"app"`
	FlashVer       string `amf:"flashVer" json:"flashVer"`
	SwfUrl         string `amf:"swfUrl" json:"swfUrl"`
	TcUrl          string `amf:"tcUrl" json:"tcUrl"`
	Fpad           bool   `amf:"fpad" json:"fpad"`
	AudioCodecs    int    `amf:"audioCodecs" json:"audioCodecs"`
	VideoCodecs    int    `amf:"videoCodecs" json:"videoCodecs"`
	VideoFunction  int    `amf:"videoFunction" json:"videoFunction"`
	PageUrl        string `amf:"pageUrl" json:"pageUrl"`
	ObjectEncoding int    `amf:"objectEncoding" json:"objectEncoding"`
}

ConnectInfo is the RTMP spec's parameters of the key value pairs passed during a connect command message

The following is the description of the name-value pairs used in Command

                   Object of the connect command.
+-----------+--------+-----------------------------+----------------+
| Property  |  Type  |        Description          | Example Value  |
+-----------+--------+-----------------------------+----------------+
|   app     | String | The Server application name |    testapp     |
|           |        | the client is connected to. |                |
+-----------+--------+-----------------------------+----------------+
| flashver  | String | Flash Player version. It is |    FMSc/1.0    |
|           |        | the same string as returned |                |
|           |        | by the ApplicationScript    |                |
|           |        | getversion () function.     |                |
+-----------+--------+-----------------------------+----------------+
|  swfUrl   | String | URL of the source SWF file  | file://C:/     |
|           |        | making the connection.      | FlvPlayer.swf  |
+-----------+--------+-----------------------------+----------------+
|  tcUrl    | String | URL of the Server.          | rtmp://local   |
|           |        | It has the following format.| host:1935/test |
|           |        | protocol://servername:port/ | app/instance1  |
|           |        | appName/appInstance         |                |
+-----------+--------+-----------------------------+----------------+
|  fpad     | Boolean| True if proxy is being used.| true or false  |
+-----------+--------+-----------------------------+----------------+
|audioCodecs| Number | Indicates what audio codecs | SUPPORT_SND    |
|           |        | the client supports.        | _MP3           |
+-----------+--------+-----------------------------+----------------+
|videoCodecs| Number | Indicates what video codecs | SUPPORT_VID    |
|           |        | are supported.              | _SORENSON      |
+-----------+--------+-----------------------------+----------------+
|videoFunct-| Number | Indicates what special video| SUPPORT_VID    |
|ion        |        | functions are supported.    | _CLIENT_SEEK   |
+-----------+--------+-----------------------------+----------------+
|  pageUrl  | String | URL of the web page from    | http://        |
|           |        | where the SWF file was      | somehost/      |
|           |        | loaded.                     | sample.html    |
+-----------+--------+-----------------------------+----------------+
| object    | Number | AMF encoding method.        |     AMF3       |
| Encoding  |        |                             |                |
+-----------+--------+-----------------------------+----------------+

func ConnectInfoMapToInstance

func ConnectInfoMapToInstance(i interface{}) (*ConnectInfo, error)

type JWT

type JWT struct {
	Secret    string `mapstructure:"secret"`
	Algorithm string `mapstructure:"algorithm"`
}

type Listener

type Listener struct {
	net.Listener
	// contains filtered or unexported fields
}

func Listen

func Listen(address string) (*Listener, error)

func (*Listener) Accept

func (l *Listener) Accept() (net.Conn, error)

func (*Listener) Addr

func (l *Listener) Addr() net.Addr

func (*Listener) Close

func (l *Listener) Close() error

func (*Listener) URLAddr

func (l *Listener) URLAddr() *URLAddr

type MessageID

type MessageID uint32

MessageID is the main "Message stream ID" for each packet sent over the RTMP protocol

3. Definitions Message stream ID: Each message has an ID associated with it to identify the message stream in which it is flowing.

type MetaData

type MetaData struct {
	V21             bool   `amf:"2.1" json:"2.1"`
	V31             bool   `amf:"3.1" json:"3.1"`
	V40             bool   `amf:"4.0" json:"4.0"`
	V41             bool   `amf:"4.1" json:"4.1"`
	V51             bool   `amf:"5.1" json:"5.1"`
	V71             bool   `amf:"7.1" json:"7.1"`
	AudioChannels   int    `amf:"audiochannels" json:"audiochannels"`
	AudioCodecID    int    `amf:"audiocodecid" json:"audiocodecid"`
	AudioDataRate   int    `amf:"audiodatarate" json:"audiodatarate"`
	AudioSampleRate int    `amf:"audiosamplerate" json:"audiosamplerate"`
	AudioSampleSize int    `amf:"audiosamplesize" json:"audiosamplesize"`
	Duration        int    `amf:"duration" json:"duration"`
	Encoder         string `amf:"encoder" json:"encoder"`
	FileSize        int    `amf:"filesize" json:"filesize"`
	FrameRate       int    `amf:"framerate" json:"framerate"`
	Height          int    `amf:"height" json:"height"`
	Stereo          bool   `amf:"stereo" json:"stereo"`
	VideoCodecID    int    `amf:"videocodecid" json:"videocodecid"`
	VideoDataRate   int    `amf:"videodatarate" json:"videodatarate"`
	Width           int    `amf:"width" json:"width"`
}

MetaData is found in clients such as OBS

Example map: 2.1:false 3.1:false 4.0:false 4.1:false 5.1:false 7.1:false audiochannels:2 audiocodecid:10 audiodatarate:160 audiosamplerate:48000 audiosamplesize:16 duration:0 encoder:obs-output module (libobs version 27.0.1-3) fileSize:0 framerate:30 height:720 stereo:true videocodecid:7 videodatarate:2500 width:1280

func MetaDataMapToInstance

func MetaDataMapToInstance(i interface{}) (*MetaData, error)

func VirtualOBSOutputClientMetadata

func VirtualOBSOutputClientMetadata() *MetaData

VirtualOBSOutputClientMetadata

A virtual metadata object that resembles common OBS configuration.

(map[2.1:false 3.1:false 4.0:false 4.1:false 5.1:false 7.1:false audiochannels:2 audiocodecid:10 audiodatarate:160 audiosamplerate:48000 audiosamplesize:16 duration:0 encoder:obs-output module (libobs version 27.0.1-3) fileSize:0 framerate:30 height:720 stereo:true videocodecid:7 videodatarate:2500 width:1280])

type Metrics

type Metrics struct {
	ServerAddrRX         string
	ServerTotalPacketsRX int
	ServerTotalBytesRX   int
	ServerPacketOffset   int
	ServerKeyHash        string
	PacketsPerSecond     float64
	StartTime            time.Time

	// Proxies is a map indexed on SafeURL()
	Proxies map[string]*ProxyMetrics

	sync.Mutex
}

Metrics is a data structure that will aggregate metrics about our RTMP connections, and streams.

func M

func M() *Metrics

M is a metrics singleton

func (*Metrics) String

func (metrics *Metrics) String() string

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

func NewPool

func NewPool() *Pool

func (*Pool) Get

func (pool *Pool) Get(size int) []byte

type ProxyMetrics

type ProxyMetrics struct {
	ProxyAddrTX         string
	ProxyTotalBytesTX   int
	ProxyTotalPacketsTX int
	ProxyKeyHash        string
}

func P

func P(name string) *ProxyMetrics

type PublishInfo

type PublishInfo struct {
	Name string
	Type string
}

type ReadWriter

type ReadWriter struct {
	*bufio.ReadWriter
	// contains filtered or unexported fields
}

func NewReadWriter

func NewReadWriter(rw io.ReadWriter, bufSize int) *ReadWriter

func (*ReadWriter) Flush

func (rw *ReadWriter) Flush() error

func (*ReadWriter) Read

func (rw *ReadWriter) Read(p []byte) (int, error)

func (*ReadWriter) ReadError

func (rw *ReadWriter) ReadError() error

func (*ReadWriter) ReadUintBE

func (rw *ReadWriter) ReadUintBE(n int) (uint32, error)

func (*ReadWriter) ReadUintLE

func (rw *ReadWriter) ReadUintLE(n int) (uint32, error)

func (*ReadWriter) Write

func (rw *ReadWriter) Write(p []byte) (int, error)

func (*ReadWriter) WriteError

func (rw *ReadWriter) WriteError() error

func (*ReadWriter) WriteUintBE

func (rw *ReadWriter) WriteUintBE(v uint32, n int) error

func (*ReadWriter) WriteUintLE

func (rw *ReadWriter) WriteUintLE(v uint32, n int) error

type RoomKeysType

type RoomKeysType struct {
	// contains filtered or unexported fields
}

func (*RoomKeysType) DeleteChannel

func (r *RoomKeysType) DeleteChannel(channel string) bool

func (*RoomKeysType) DeleteKey

func (r *RoomKeysType) DeleteKey(key string) bool

func (*RoomKeysType) GetChannel

func (r *RoomKeysType) GetChannel(key string) (channel string, err error)

func (*RoomKeysType) GetKey

func (r *RoomKeysType) GetKey(channel string) (newKey string, err error)

func (*RoomKeysType) SetKey

func (r *RoomKeysType) SetKey(channel string) (key string, err error)

type Server

type Server struct {
	// contains filtered or unexported fields
}

func NewServer

func NewServer() *Server

func (*Server) ListenAndServe

func (s *Server) ListenAndServe(raw string) error

func (*Server) PlayClient

func (s *Server) PlayClient(f *ServerConn)

func (*Server) Proxy

func (s *Server) Proxy(raw string) error

Proxy will configure forward addresses for the RTMP server.

Proxy can be called before or after Serve() and the backend server will be smart enough to sync clients.

func (*Server) ProxyClient

func (s *Server) ProxyClient(f *ClientConn) error

ProxyClient will add clients to this server.

Client forwarding is handled at the server level. We trust each subsequent stream to update to the configured clients as they are added.

func (*Server) PublishClient

func (s *Server) PublishClient(f *ServerConn)

func (*Server) Serve

func (s *Server) Serve(listener net.Listener) error

Serve

A blocking method that will listen for new connections and create subsequent go routines for new clients as they connect.

type ServerClientType

type ServerClientType int
const (
	PlayClient    ServerClientType = 1
	PublishClient ServerClientType = 2
)

type ServerConn

type ServerConn struct {
	// contains filtered or unexported fields
}

func NewServerConn

func NewServerConn(conn *Conn) *ServerConn

func (*ServerConn) Close

func (s *ServerConn) Close()

func (*ServerConn) Flush

func (s *ServerConn) Flush() error

func (*ServerConn) LogDecodeBatch

func (s *ServerConn) LogDecodeBatch(r io.Reader, ver amf.Version) ([]interface{}, error)

func (*ServerConn) NextChunk

func (s *ServerConn) NextChunk() (*ChunkStream, error)

NextChunk will read the next packet of data from the client, and will attempt to respond to the packet based on it's content and the appropriate response per the RTMP spec.

func (*ServerConn) Read

func (s *ServerConn) Read(packet *ChunkStream) (err error)

func (*ServerConn) Route

func (s *ServerConn) Route(x *ChunkStream) error

func (*ServerConn) RoutePackets

func (s *ServerConn) RoutePackets() error

RoutePackets will hang and route packets for this connection

func (*ServerConn) Write

func (s *ServerConn) Write(x *ChunkStream) error

type Stream

type Stream struct {
	URLAddr
	// contains filtered or unexported fields
}

func Multiplex

func Multiplex(key string) *Stream

Multiplex onto key

All bytes written to this key (the base key) will be multiplexed onto any configured proxy clients.

func NewStream

func NewStream(key string) *Stream

func (*Stream) AddConn

func (s *Stream) AddConn(c *Conn) error

func (*Stream) AddMetaData

func (s *Stream) AddMetaData(x *ChunkStream) error

func (*Stream) GetMetaData

func (s *Stream) GetMetaData() *ChunkStream

func (*Stream) RemoveConn

func (s *Stream) RemoveConn(c *Conn)

func (*Stream) SetChunkSize

func (s *Stream) SetChunkSize(chunkSize uint32)

func (*Stream) Write

func (s *Stream) Write(x *ChunkStream) error

[ Write ]

The almighty Write() method.

This method is effectively a single threaded Write() method.

If this blocks. All corresponding *Conn objects will also block.

type URLAddr

type URLAddr struct {
	url.URL
	net.Addr
	// contains filtered or unexported fields
}

URLAddr is a flexible RTMP address member that resembles url.URL.

func NewURLAddr

func NewURLAddr(raw string) (*URLAddr, error)

func (*URLAddr) App

func (a *URLAddr) App() string

App will return the first parameter of the path. Such as rtmp://host:port/app/key

func (*URLAddr) Host

func (a *URLAddr) Host() string

Host will return a net.Listener compatible host string as verbosely as possible. Given inputs such as:

localhost:
localhost:1935
:1935
:

We should see

localhost:1935

func (*URLAddr) Key

func (a *URLAddr) Key() string

Key should return the stream key for this instance of *rtmp.Addr All instances will generate a key if one is not provided.

func (*URLAddr) Network

func (a *URLAddr) Network() string

func (*URLAddr) NewConn

func (a *URLAddr) NewConn() (*Conn, error)

func (*URLAddr) NewNetConn

func (a *URLAddr) NewNetConn() (net.Conn, error)

func (*URLAddr) SafeKey

func (a *URLAddr) SafeKey() string

SafeKey is a sha256 of the stream key

func (*URLAddr) SafeURL

func (a *URLAddr) SafeURL() string

SafeURL will log the StreamURL() without the key.

rtmp://localhost:1935/app/[obfuscated]

func (*URLAddr) Scheme

func (a *URLAddr) Scheme() string

Scheme should always return DefaultScheme "rtmp://"

func (*URLAddr) StreamURL

func (a *URLAddr) StreamURL() string

StreamURL is a resolvable stream URL that can be played, published, or proxied.

rtmp://localhost:1935/app/key

func (*URLAddr) String

func (a *URLAddr) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL