gortmp

package module
v0.0.0-...-9015df6 Latest Latest
Warning

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

Go to latest
Published: Sep 24, 2015 License: MIT Imports: 20 Imported by: 0

README

GoRTMP, revised edition

====== Codeship Status for berndfo/gortmp

RTMP protocol implementation.

Spec:

Dependencies

depends solely on

Running the server:

start the standalone server

go run src/github.com/berndfo/gortmp/server/main/server.go

the server listens on the default RTMP port 1935.

the server will accept client connections for either 'publish' or 'play' netstreams. if the publish mode is 'record' or 'append' it will write the stream to FLV files in the local file system.

the server exposes runtime variables on localhost via the URL http://localhost:8000/debug/vars.

Running a publishing client:

if you want to publish a FLV file named myvideo.flv to the server, run

go run src/github.com/berndfo/gortmp/demo/publisher/rtmp_publisher.go -FLV myvideo.flv -Stream myvideo

optionally, specify the server URL by appending for example

-URL rtmp://localhost:1935/stream

Documentation

Overview

RTMP protocol golang implementation

Copyright 2013, zhangpeihao All rights reserved.

Index

Constants

View Source
const (
	CLIENT_CONN_STATUS_CLOSE            = uint(0)
	CLIENT_CONN_STATUS_HANDSHAKE_OK     = uint(1)
	CLIENT_CONN_STATUS_CONNECT          = uint(2)
	CLIENT_CONN_STATUS_CONNECT_OK       = uint(3)
	CLIENT_CONN_STATUS_CREATE_STREAM    = uint(4)
	CLIENT_CONN_STATUS_CREATE_STREAM_OK = uint(5)
)
View Source
const (
	HEADER_FMT_FULL                   = 0x00
	HEADER_FMT_SAME_STREAM            = 0x01
	HEADER_FMT_SAME_LENGTH_AND_STREAM = 0x02
	HEADER_FMT_CONTINUATION           = 0x03
)

Chunk Message Header - "fmt" field values

View Source
const (
	RESULT_CONNECT_OK            = "NetConnection.Connect.Success"
	RESULT_CONNECT_REJECTED      = "NetConnection.Connect.Rejected"
	RESULT_CONNECT_OK_DESC       = "Connection succeeded."
	RESULT_CONNECT_REJECTED_DESC = "[ AccessManager.Reject ] : [ code=400 ] : "
	NETSTREAM_PLAY_START         = "NetStream.Play.Start"
	NETSTREAM_PLAY_RESET         = "NetStream.Play.Reset"
	NETSTREAM_PUBLISH_START      = "NetStream.Publish.Start"
)

Result codes

View Source
const (
	CS_ID_PROTOCOL_CONTROL = uint32(2)
	CS_ID_COMMAND          = uint32(3)
	CS_ID_USER_CONTROL     = uint32(4)
)

Chunk stream ID

View Source
const (

	// The value of the chunk size is carried as 4-byte message payload. A
	// default value exists for chunk size, but if the sender wants to
	// change this value it notifies the peer about it through this
	// protocol message. For example, a client wants to send 131 bytes of
	// data and the chunk size is at its default value of 128. So every
	// message from the client gets split into two chunks. The client can
	// choose to change the chunk size to 131 so that every message get
	// split into two chunks. The client MUST send this protocol message to
	// the server to notify that the chunk size is set to 131 bytes.
	// The maximum chunk size can be 65536 bytes. Chunk size is maintained
	// independently for server to client communication and client to server
	// communication.
	//
	//  0                   1                   2                   3
	//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// |                          chunk size (4 bytes)                 |
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// Figure 2 Pay load for the protocol message ‘Set Chunk Size’
	//
	// chunk size: 32 bits
	//   This field holds the new chunk size, which will be used for all
	//   future chunks sent by this chunk stream.
	SET_CHUNK_SIZE = uint8(1)

	// Abort Message
	//
	// Protocol control message 2, Abort Message, is used to notify the peer
	// if it is waiting for chunks to complete a message, then to discard
	// the partially received message over a chunk stream and abort
	// processing of that message. The peer receives the chunk stream ID of
	// the message to be discarded as payload of this protocol message. This
	// message is sent when the sender has sent part of a message, but wants
	// to tell the receiver that the rest of the message will not be sent.
	//
	//  0                   1                   2                   3
	//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// |                        chunk stream id (4 bytes)              |
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// Figure 3 Pay load for the protocol message ‘Abort Message’.
	//
	//
	// chunk stream ID: 32 bits
	//   This field holds the chunk stream ID, whose message is to be
	//   discarded.
	ABORT_MESSAGE = uint8(2)

	// Acknowledgement
	//
	// The client or the server sends the acknowledgment to the peer after
	// receiving bytes equal to the window size. The window size is the
	// maximum number of bytes that the sender sends without receiving
	// acknowledgment from the receiver. The server sends the window size to
	// the client after application connects. This message specifies the
	// sequence number, which is the number of the bytes received so far.
	//  0                   1                   2                   3
	//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// |                        sequence number (4 bytes)              |
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// Figure 4 Pay load for the protocol message ‘Acknowledgement’.
	//
	// sequence number: 32 bits
	//   This field holds the number of bytes received so far.
	ACKNOWLEDGEMENT = uint8(3)

	// User Control Message
	//
	// The client or the server sends this message to notify the peer about
	// the user control events. This message carries Event type and Event
	// data.
	// +------------------------------+-------------------------
	// |     Event Type ( 2- bytes ) | Event Data
	// +------------------------------+-------------------------
	// Figure 5 Pay load for the ‘User Control Message’.
	//
	//
	// The first 2 bytes of the message data are used to identify the Event
	// type. Event type is followed by Event data. Size of Event data field
	// is variable.
	USER_CONTROL_MESSAGE = uint8(4)

	// Window Acknowledgement Size
	//
	// The client or the server sends this message to inform the peer which
	// window size to use when sending acknowledgment. For example, a server
	// expects acknowledgment from the client every time the server sends
	// bytes equivalent to the window size. The server updates the client
	// about its window size after successful processing of a connect
	// request from the client.
	//
	//  0                   1                   2                   3
	//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// |                   Acknowledgement Window size (4 bytes)       |
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// Figure 6 Pay load for ‘Window Acknowledgement Size’.
	WINDOW_ACKNOWLEDGEMENT_SIZE = uint8(5)

	// Set Peer Bandwidth
	//
	// The client or the server sends this message to update the output
	// bandwidth of the peer. The output bandwidth value is the same as the
	// window size for the peer. The peer sends ‘Window Acknowledgement
	// Size’ back if its present window size is different from the one
	// received in the message.
	//  0                   1                   2                   3
	//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// |                   Acknowledgement Window size                 |
	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	// | Limit type    |
	// +-+-+-+-+-+-+-+-+
	// Figure 7 Pay load for ‘Set Peer Bandwidth’
	//
	// The sender can mark this message hard (0), soft (1), or dynamic (2)
	// using the Limit type field. In a hard (0) request, the peer must send
	// the data in the provided bandwidth. In a soft (1) request, the
	// bandwidth is at the discretion of the peer and the sender can limit
	// the bandwidth. In a dynamic (2) request, the bandwidth can be hard or
	// soft.
	SET_PEER_BANDWIDTH = uint8(6)

	// Audio message
	//
	// The client or the server sends this message to send audio data to the
	// peer. The message type value of 8 is reserved for audio messages.
	AUDIO_TYPE = uint8(8)

	// Video message
	//
	// The client or the server sends this message to send video data to the
	// peer. The message type value of 9 is reserved for video messages.
	// These messages are large and can delay the sending of other type of
	// messages. To avoid such a situation, the video message is assigned
	// the lowest priority.
	VIDEO_TYPE = uint8(9)

	// Aggregate message
	//
	// An aggregate message is a single message that contains a list of sub-
	// messages. The message type value of 22 is reserved for aggregate
	// messages.
	AGGREGATE_MESSAGE_TYPE = uint8(22)

	// Shared object message
	//
	// A shared object is a Flash object (a collection of name value pairs)
	// that are in synchronization across multiple clients, instances, and
	// so on. The message types kMsgContainer=19 for AMF0 and
	// kMsgContainerEx=16 for AMF3 are reserved for shared object events.
	// Each message can contain multiple events.
	SHARED_OBJECT_AMF0 = uint8(19)
	SHARED_OBJECT_AMF3 = uint8(16)

	// Data message
	//
	// The client or the server sends this message to send Metadata or any
	// user data to the peer. Metadata includes details about the
	// data(audio, video etc.) like creation time, duration, theme and so
	// on. These messages have been assigned message type value of 18 for
	// AMF0 and message type value of 15 for AMF3.
	DATA_AMF0 = uint8(18)
	DATA_AMF3 = uint8(15)

	// Command message
	//
	// Command messages carry the AMF-encoded commands between the client
	// and the server. These messages have been assigned message type value
	// of 20 for AMF0 encoding and message type value of 17 for AMF3
	// encoding. These messages are sent to perform some operations like
	// connect, createStream, publish, play, pause on the peer. Command
	// messages like onstatus, result etc. are used to inform the sender
	// about the status of the requested commands. A command message
	// consists of command name, transaction ID, and command object that
	// contains related parameters. A client or a server can request Remote
	// Procedure Calls (RPC) over streams that are communicated using the
	// command messages to the peer.
	COMMAND_AMF0 = uint8(20)
	COMMAND_AMF3 = uint8(17) // Keng-die!!! Just ignore one byte before AMF0.
)

Message type

View Source
const (
	EVENT_STREAM_BEGIN       = uint16(0)
	EVENT_STREAM_EOF         = uint16(1)
	EVENT_STREAM_DRY         = uint16(2)
	EVENT_SET_BUFFER_LENGTH  = uint16(3)
	EVENT_STREAM_IS_RECORDED = uint16(4)
	EVENT_PING_REQUEST       = uint16(6)
	EVENT_PING_RESPONSE      = uint16(7)
	EVENT_REQUEST_VERIFY     = uint16(0x1a)
	EVENT_RESPOND_VERIFY     = uint16(0x1b)
	EVENT_BUFFER_EMPTY       = uint16(0x1f)
	EVENT_BUFFER_READY       = uint16(0x20)
)
View Source
const (
	BINDWIDTH_LIMIT_HARD    = uint8(0)
	BINDWIDTH_LIMIT_SOFT    = uint8(1)
	BINDWIDTH_LIMIT_DYNAMIC = uint8(2)
)
View Source
const (
	MAX_TIMESTAMP                     = uint32(2000000000)
	AUTO_TIMESTAMP                    = uint32(0XFFFFFFFF)
	DEFAULT_HIGH_PRIORITY_BUFFER_SIZE = 2048
	DEFAULT_CHUNK_SIZE                = uint32(128)
	DEFAULT_WINDOW_SIZE               = 2500000
	DEFAULT_CAPABILITIES              = float64(15)
	DEFAULT_AUDIO_CODECS              = float64(4071)
	DEFAULT_VIDEO_CODECS              = float64(252)
	FMS_CAPBILITIES                   = uint32(255)
	FMS_MODE                          = uint32(2)
	SET_PEER_BANDWIDTH_HARD           = byte(0)
	SET_PEER_BANDWIDTH_SOFT           = byte(1)
	SET_PEER_BANDWIDTH_DYNAMIC        = byte(2)
)
View Source
const (
	RTMP_SIG_SIZE          = 1536
	RTMP_LARGE_HEADER_SIZE = 12
	SHA256_DIGEST_LENGTH   = 32
	RTMP_DEFAULT_CHUNKSIZE = 128
)
View Source
const (
	SERVER_CONN_STATUS_CLOSE            = uint(0)
	SERVER_CONN_STATUS_CONNECT_OK       = uint(1)
	SERVER_CONN_STATUS_CREATE_STREAM_OK = uint(2)
)
View Source
const (
	MS_ID_CONTROL_STREAM = uint32(0)
)

Chunk stream ID

View Source
const (
	RTMP_LOG_NAME = "rtmp"
)
View Source
const UPSTREAM_DEFAULT_CHANNEL_SIZE int = 10000

Variables

View Source
var (
	//	FLASH_PLAYER_VERSION = []byte{0x0A, 0x00, 0x2D, 0x02}
	FLASH_PLAYER_VERSION = []byte{0x09, 0x00, 0x7C, 0x02}
	//FLASH_PLAYER_VERSION = []byte{0x80, 0x00, 0x07, 0x02}
	//FLASH_PLAYER_VERSION_STRING = "LNX 10,0,32,18"
	FLASH_PLAYER_VERSION_STRING = "LNX 9,0,124,2"
	//FLASH_PLAYER_VERSION_STRING = "WIN 11,5,502,146"
	SWF_URL_STRING     = "http://localhost/1.swf"
	PAGE_URL_STRING    = "http://localhost/1.html"
	MIN_BUFFER_LENGTH  = uint32(256)
	FMS_VERSION        = []byte{0x04, 0x05, 0x00, 0x01}
	FMS_VERSION_STRING = "4,5,0,297"
)
View Source
var (
	GENUINE_FMS_KEY = []byte{
		0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20,
		0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c,
		0x61, 0x73, 0x68, 0x20, 0x4d, 0x65, 0x64, 0x69,
		0x61, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
		0x20, 0x30, 0x30, 0x31,
		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,
	}
	GENUINE_FP_KEY = []byte{
		0x47, 0x65, 0x6E, 0x75, 0x69, 0x6E, 0x65, 0x20,
		0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x46, 0x6C,
		0x61, 0x73, 0x68, 0x20, 0x50, 0x6C, 0x61, 0x79,
		0x65, 0x72, 0x20, 0x30, 0x30, 0x31,
		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,
	}
)
View Source
var DebugLog bool = false
View Source
var DefaultObjectEncoding uint = amf.AMF0
View Source
var DoDumpBuffer bool = true
View Source
var DownstreamClosed error = errors.New("DownstreamClosed")
View Source
var ErrorNameAlreadyExists error = errors.New("NameAlreadyExists")
View Source
var StreamNotExists error = errors.New("StreamNotExists")

Functions

func CalcDHPos

func CalcDHPos(buf []byte, offset uint32, mod_val uint32, add_val uint32) (digest_pos uint32)

func CalcDigestPos

func CalcDigestPos(buf []byte, offset uint32, mod_val uint32, add_val uint32) (digest_pos uint32)

func CheckError

func CheckError(err error, name string)

Check error

If error panic

func CopyNToNetwork

func CopyNToNetwork(dst Writer, src Reader, n int64, chunkStreamId uint32) (written int64, err error)

Copy bytes to network

func CreateRandomBlock

func CreateRandomBlock(size uint) []byte

func DumpBuffer

func DumpBuffer(name string, data []byte, ind int)

Dump buffer

func FlushToNetwork

func FlushToNetwork(w *bufio.Writer, chunkStreamId uint32) (err error)

func GetTimestamp

func GetTimestamp() uint32

Get timestamp

func HMACsha256

func HMACsha256(msgBytes []byte, key []byte) ([]byte, error)

func Handshake

func Handshake(c net.Conn, br *bufio.Reader, bw *bufio.Writer, timeout time.Duration) (err error)

func ImprintWithDigest

func ImprintWithDigest(buf []byte, key []byte) uint32

func ReadAtLeastN

func ReadAtLeastN(r Reader, chunkStreamId uint32, buf []byte, min int) (n int, err error)

Reads at least min bytes

func ReadBasicHeader

func ReadBasicHeader(rbuf Reader) (readBytesCount int, fmt uint8, chunkStreamId uint32, err error)

Read Basic Header for chunk stream

func ReadByteFromNetwork

func ReadByteFromNetwork(r Reader, chunkStreamId uint32) (b byte, err error)

Read byte from network

func ReceiveStreamMessage

func ReceiveStreamMessage(stream ServerStream, message *Message) bool

func RegisterDownstream

func RegisterDownstream(name string, downstream NetStreamDownstream) error

func RegisterNewNetStream

func RegisterNewNetStream(name string, streamType string, serverStream ServerStream) (upstream NetStreamUpstream, dispatcher *NetStreamDispatchingHandler, err error)

func SHandshake

func SHandshake(c net.Conn, br *bufio.Reader, bw *bufio.Writer, timeout time.Duration) (err error)

func StatusDisplay

func StatusDisplay(status uint) string

func UnregisterDownstream

func UnregisterDownstream(name string, removedDownstream NetStreamDownstream) error

func ValidateDigest

func ValidateDigest(buf []byte, offset uint32, key []byte) uint32

func WriteToNetwork

func WriteToNetwork(w Writer, data []byte, chunkStreamId uint32) (written int, err error)

Types

type ClientChunkStream

type ClientChunkStream struct {
	ID uint32
	// contains filtered or unexported fields
}

Chunk stream

A logical channel of communication that allows flow of chunks in a particular direction. The chunk stream can travel from the client to the server and reverse.

func NewClientChunkStream

func NewClientChunkStream(id uint32) *ClientChunkStream

func (*ClientChunkStream) GetTimestamp

func (chunkStream *ClientChunkStream) GetTimestamp() uint32

func (*ClientChunkStream) NewClientHeader

func (chunkStream *ClientChunkStream) NewClientHeader(message *Message) *Header

type ClientConn

type ClientConn interface {
	// Connect an appliction on FMS after handshake.
	Connect(extendedParameters ...interface{}) (err error)
	// Create a stream
	CreateStream() (err error)
	// Close a connection
	Close()
	// URL to connect
	URL() string
	// Connection status
	Status() (uint, error)
	// Send a message
	Send(message *Message) error
	// Calls a command or method on Flash Media Server
	// or on an application server running Flash Remoting.
	Call(name string, customParameters ...interface{}) (err error)
	// Get network connect instance
	Conn() Conn
}

func Dial

func Dial(url string, handler ClientConnHandler, maxChannelNumber int) (ClientConn, error)

Connect to FMS server, and finish handshake process

func NewClientConn

func NewClientConn(c net.Conn, url string, handler ClientConnHandler, maxChannelNumber int) (ClientConn, error)

Connect to FMS server, and finish handshake process

type ClientConnHandler

type ClientConnHandler interface {
	ConnHandler
	// When connection status changed
	OnStatus(obConn ClientConn)
	// On stream created
	OnStreamCreated(obConn ClientConn, stream ClientStream)
}

A handler for outbound client connection

type ClientPlayStream

type ClientPlayStream interface {
	// Play
	Play(streamName string, start, duration float32, reset bool) (err error)
	// Seeks the kerframe closedst to the specified location.
	Seek(offset uint32)
}

A play stream

type ClientPublishStream

type ClientPublishStream interface {
	// Publish
	Publish(name, t string) (err error)
	// Send audio data
	SendAudioData(data []byte) error
	// Send video data
	SendVideoData(data []byte) error
}

A publish stream

type ClientStream

type ClientStream interface {
	ClientPublishStream
	ClientPlayStream
	// ID
	ID() uint32
	// Pause
	Pause() error
	// Resume
	Resume() error
	// Close
	Close()
	// Received messages
	Received(message *Message) (handlered bool)
	// Attach handler
	Attach(handler ClientStreamHandler)
	// Publish audio data
	PublishAudioData(data []byte, deltaTimestamp uint32) error
	// Publish video data
	PublishVideoData(data []byte, deltaTimestamp uint32) error
	// Publish data
	PublishData(dataType uint8, data []byte, deltaTimestamp uint32) error
	// Call
	Call(name string, customParameters ...interface{}) error
}

A RTMP logical stream, client-side view

type ClientStreamHandler

type ClientStreamHandler interface {
	OnPlayStart(stream ClientStream)
	OnPublishStart(stream ClientStream)
}

type Command

type Command struct {
	IsFlex        bool
	Name          string
	TransactionID uint32
	Objects       []interface{}
}

Command

Command messages carry the AMF encoded commands between the client and the server. A client or a server can request Remote Procedure Calls (RPC) over streams that are communicated using the command messages to the peer.

func (*Command) Dump

func (cmd *Command) Dump(name string) string

func (*Command) LogDump

func (cmd *Command) LogDump(name string)

func (*Command) Object

func (cmd *Command) Object(i int) (obj interface{}, exists bool)

func (*Command) ObjectBool

func (cmd *Command) ObjectBool(i int) (flag bool, exists bool)

func (*Command) ObjectLen

func (cmd *Command) ObjectLen() int

func (*Command) ObjectNumber

func (cmd *Command) ObjectNumber(i int) (number float64, exists bool)

func (*Command) ObjectObject

func (cmd *Command) ObjectObject(i int) (amfObj amf.Object, exists bool)

func (*Command) ObjectString

func (cmd *Command) ObjectString(i int) (str string, exists bool)

func (*Command) Write

func (cmd *Command) Write(w Writer) (err error)

type Conn

type Conn interface {
	Id() string
	Close()
	Send(message *Message) error
	CreateChunkStream(ID uint32) (*ClientChunkStream, error)
	CloseChunkStream(ID uint32)
	NewTransactionID() uint32
	CreateMediaChunkStream() (*ClientChunkStream, error)
	CloseMediaChunkStream(id uint32)
	SetStreamBufferSize(streamId uint32, size uint32)
	ClientChunkStream(id uint32) (chunkStream *ClientChunkStream, found bool)
	ServerChunkStream(id uint32) (chunkStream *ServerChunkStream, found bool)
	SetWindowAcknowledgementSize(inWindowSize uint32, outWindowSize uint32)
	SetPeerBandwidth(peerBandwidth uint32, limitType byte)
	SetChunkSize(chunkSize uint32)
	SendUserControlMessage(eventId uint16)
}

Conn

Common connection functions

func NewConn

func NewConn(c net.Conn, br *bufio.Reader, bw *bufio.Writer, handler ConnHandler, maxChannelNumber int) Conn

Create new connection

type ConnHandler

type ConnHandler interface {
	// Received message
	OnConnMessageReceived(conn Conn, message *Message)
	// Received command
	OnReceivedRtmpCommand(conn Conn, command *Command)
	// Connection closed
	OnClosed(conn Conn)
}

Connection handler

type HandshakeResult

type HandshakeResult struct {
	ProtoVersion byte
	Epoch        uint32
	PeerVersion  [4]byte
}
type Header struct {
	// Basic Header
	Fmt           uint8
	ChunkStreamID uint32

	// Chunk Message Header
	Timestamp       uint32
	MessageLength   uint32
	MessageTypeID   uint8
	MessageStreamID uint32

	// Extended Timestamp
	ExtendedTimestamp uint32
}

RTMP Chunk Header

The header is broken down into three parts:

| Basic header|Chunk Msg Header|Extended Time Stamp| Chunk Data |

Chunk basic header: 1 to 3 bytes

This field encodes the chunk stream ID and the chunk type. Chunk type determines the format of the encoded message header. The length depends entirely on the chunk stream ID, which is a variable-length field.

Chunk message header: 0, 3, 7, or 11 bytes

This field encodes information about the message being sent (whether in whole or in part). The length can be determined using the chunk type specified in the chunk header.

Extended timestamp: 0 or 4 bytes

This field MUST be sent when the normal timsestamp is set to 0xffffff, it MUST NOT be sent if the normal timestamp is set to anything else. So for values less than 0xffffff the normal timestamp field SHOULD be used in which case the extended timestamp MUST NOT be present. For values greater than or equal to 0xffffff the normal timestamp field MUST NOT be used and MUST be set to 0xffffff and the extended timestamp MUST be sent.

func (*Header) Dump

func (header *Header) Dump(name string)

func (*Header) FmtDisplay

func (header *Header) FmtDisplay() string

func (*Header) ReadMessageHeader

func (header *Header) ReadMessageHeader(rbuf Reader, fmt uint8, csid uint32, lastheader *Header) (readBytesCount int, err error)

Read Message header for chunk stream

func (*Header) RealTimestamp

func (header *Header) RealTimestamp() uint32

func (*Header) Write

func (header *Header) Write(wbuf Writer) (n int, err error)

Encode header into io.Writer

type Message

type Message struct {
	Timestamp         uint32
	ChunkStreamID     uint32
	Size              uint32
	Type              uint8
	MessageStreamID   uint32
	Buf               *bytes.Buffer
	IsInbound         bool
	AbsoluteTimestamp uint32
}

Message

The different types of messages that are exchanged between the server and the client include audio messages for sending the audio data, video messages for sending video data, data messages for sending any user data, shared object messages, and command messages.

func CopyToStream

func CopyToStream(stream ServerStream, messageIn *Message) *Message

func NewMessage

func NewMessage(csid uint32, typ uint8, msid uint32, ts uint32, data []byte) *Message

func (*Message) Dump

func (message *Message) Dump(name string) string

func (*Message) LogDump

func (message *Message) LogDump(name string)

func (*Message) Remain

func (message *Message) Remain() uint32

The length of remain data to read

func (*Message) TypeDisplay

func (message *Message) TypeDisplay() string

type NetStreamDispatchingHandler

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

implements ServerStreamHandler

func (*NetStreamDispatchingHandler) Close

func (handler *NetStreamDispatchingHandler) Close()

func (*NetStreamDispatchingHandler) OnAudioData

func (handler *NetStreamDispatchingHandler) OnAudioData(stream ServerStream, audio *Message)

func (*NetStreamDispatchingHandler) OnPlayStart

func (handler *NetStreamDispatchingHandler) OnPlayStart(stream ServerStream, name string, peerName string, start float64, duration float64, flushPrevPlaylist bool)

func (*NetStreamDispatchingHandler) OnPublishStart

func (handler *NetStreamDispatchingHandler) OnPublishStart(stream ServerStream, publishingName string, publishingType string)

func (*NetStreamDispatchingHandler) OnReceiveAudio

func (handler *NetStreamDispatchingHandler) OnReceiveAudio(stream ServerStream, on bool)

func (*NetStreamDispatchingHandler) OnReceiveVideo

func (handler *NetStreamDispatchingHandler) OnReceiveVideo(stream ServerStream, on bool)

func (*NetStreamDispatchingHandler) OnVideoData

func (handler *NetStreamDispatchingHandler) OnVideoData(stream ServerStream, video *Message)

type NetStreamDownstream

type NetStreamDownstream interface {
	Info() NetStreamInfo
	PushDownstream(*Message) error
}

func CreateFileRecorder

func CreateFileRecorder(filename string, info NetStreamInfo) (nsd NetStreamDownstream, err error)

func CreateRollingFileRecorder

func CreateRollingFileRecorder(info NetStreamInfo) (nsd NetStreamDownstream, err error)

type NetStreamInfo

type NetStreamInfo struct {
	Name   string
	Type   string // "live", "record" or "append"
	Stream ServerStream
}

func FindNetStream

func FindNetStream(name string) (info NetStreamInfo, exists bool)

type NetStreamUpstream

type NetStreamUpstream interface {
	Info() NetStreamInfo
	Upstream() <-chan *Message
}

type Reader

type Reader interface {
	Read(p []byte) (n int, err error)
	ReadByte() (c byte, err error)
}

type RtmpURL

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

func ParseURL

func ParseURL(url string) (rtmpURL RtmpURL, err error)

Parse url

To connect to Flash Media Server, pass the URI of the application on the server. Use the following syntax (items in brackets are optional):

protocol://host[:port]/[appname[/instanceName]]

func (*RtmpURL) App

func (rtmpUrl *RtmpURL) App() string

type Server

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

func NewServer

func NewServer(network string, bindAddress string, handler ServerHandler) (*Server, error)

Create a new server.

func (*Server) Close

func (server *Server) Close()

Close listener.

func (*Server) Handshake

func (server *Server) Handshake(c net.Conn, serverConnEstablishedChan chan<- ServerConn, serverConnLostChan chan<- ServerConn)

func (*Server) OnConnectAuth

func (server *Server) OnConnectAuth(conn ServerConn, connectReq *Command) bool

On received connect request

type ServerAuthHandler

type ServerAuthHandler interface {
	OnConnectAuth(srvConn ServerConn, connectReq *Command) bool
}

A handler for inbound connection

type ServerChunkStream

type ServerChunkStream struct {
	ID uint32
	// contains filtered or unexported fields
}

func NewServerChunkStream

func NewServerChunkStream(id uint32) *ServerChunkStream

type ServerConn

type ServerConn interface {
	// Close a connection
	Close()
	// Connection status
	Status() (uint, error)
	// Send a message
	Send(message *Message) error
	// Calls a command or method on Flash Media Server
	// or on an application server running Flash Remoting.
	Call(customParameters ...interface{}) (err error)
	// Get network connect instance
	Conn() Conn
	// Attach handler
	Attach(handler ServerConnHandler)
	// Get connect request
	ConnectRequest() *Command
}

func NewServerConn

func NewServerConn(c net.Conn, br *bufio.Reader, bw *bufio.Writer,
	authHandler ServerAuthHandler, maxChannelNumber int, serverConnLostChan chan<- ServerConn) (ServerConn, error)

type ServerConnHandler

type ServerConnHandler interface {
	ConnHandler
	// When connection status changed
	OnStatus(srvConn ServerConn)
	// On stream created
	OnStreamCreated(srvConn ServerConn, stream ServerStream)
	// On stream closed
	OnStreamClosed(srvConn ServerConn, stream ServerStream)
}

A handler for inbound connection

type ServerHandler

type ServerHandler interface {
	NewConnection(conn ServerConn, connectReq *Command, server *Server) bool
}

type ServerStream

type ServerStream interface {
	Conn() ServerConn
	// ID
	ID() uint32
	// ChunkStreamID
	ChunkStreamID() uint32
	// StreamName
	StreamName() string
	SetStreamName(string)

	Handlers() []ServerStreamHandler

	// Close
	Close()
	// Received messages
	StreamMessageReceiver() chan<- *Message
	// Attach handler
	Attach(handler ServerStreamHandler)
	// Send audio data
	SendAudioData(data []byte, deltaTimestamp uint32) error
	// Send video data
	SendVideoData(data []byte, deltaTimestamp uint32) error
	// Send data
	SendData(dataType uint8, data []byte, deltaTimestamp uint32) error
}

A RTMP logical stream, server-side view

type ServerStreamHandler

type ServerStreamHandler interface {
	OnPlayStart(stream ServerStream, name string, peerName string, start float64, duration float64, flushPrevPlaylist bool)
	OnPublishStart(stream ServerStream, publishingName string, publishingType string)
	// client asks to start/stop receiving audio
	OnReceiveAudio(stream ServerStream, on bool)
	// client asks to start/stop receiving video
	OnReceiveVideo(stream ServerStream, on bool)

	// client sends audio stream data
	OnAudioData(stream ServerStream, audio *Message)
	// client sends video stream data
	OnVideoData(stream ServerStream, video *Message)

	Close()
}

type Writer

type Writer interface {
	Write(p []byte) (nn int, err error)
	WriteByte(c byte) error
}

Directories

Path Synopsis
demo

Jump to

Keyboard shortcuts

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