~/bend-docscommunity

rtmp_core.bend checks

raw source on the hub · import 0x2355f41b6f5561f50104a75ccca27cf7/rtmp_core.bend as Rtmp_core

RTMP (Adobe's specification of 2012): the pure half of the client.

- the handshake's bytes; - the chunk stream: a message is cut into chunks, each after a header that says which chunk stream it is on and, in one of four sizes, what changed since that stream's last message; - the control messages and the commands (AMF0) a player sends; - what a message from the server means to a player; - FLV, the file the audio, video and data messages are written to as they are: a tag is a message with another header.

4 imports
import Base
import ./bytes.bend as B
import ./amf.bend as A
import ./rtsp_core.bend as C

Types

type Shake source · line 31 · raw

Data

type Where source · line 129 · raw

Data

Where a URL's path sends us: the application to connect to, and the stream to play in it (the last part of the path, with the query).

type Lane source · line 204 · raw

Data

A chunk stream's last header: the timestamp, the 3-byte field it came in (a delta but in a type 0 header; FFFFFF says the real value is in 4 more bytes), the message's size, type and stream; and the message under way: the bytes it has, its pieces last first.

type Dec source · line 209 · raw

Data

The decoder: the size of the server's chunks, and its chunk streams.

type Step source · line 214 · raw

Data

A step of the decoder: nothing whole in the buffer; a chunk taken that ends no message; or a message.

type Ev source · line 366 · raw

Data

Idle: more bytes are needed. Skip: nothing to act on. Result and Error answer a command. Start, Over and Refused are the stream's status. Media is audio (8), video (9) or the metadata (18). Ping asks for a pong with the same bytes.

type Tag source · line 475 · raw

Data

A media message as a session gives it: audio (8), video (9) or the metadata (18), its time in ms, and the data in the form an FLV tag holds (flv.bend takes frames out of it).

Definitions

def Rtmp.noise source · line 19 · raw

@n:Nat -> @+x:U32 -> @acc:List<&2, U32> -> List<&2, U32>

def Rtmp.hello source · line 28 · raw

@seed:U32 -> List<&2, U32>

C0 and C1: version 3, then 1536 bytes: a time, four zeros, and 1528 bytes of anything (here a sequence grown from the seed).

def Rtmp.shake.s2 source · line 35 · raw

@c:0x2355f41b6f5561f50104a75ccca27cf7/bytes.Cut -> @s1:List<&2, U32> -> Shake

def Rtmp.shake.s1 source · line 42 · raw

@c:0x2355f41b6f5561f50104a75ccca27cf7/bytes.Cut -> Shake

def Rtmp.shake source · line 52 · raw

@buf:List<&2, U32> -> Shake

The server's S0, S1 and S2 (1 + 1536 + 1536 bytes): C2 is S1 sent back, and what follows them is the chunk stream. Early when they are not all here yet.

def Rtmp.parts source · line 63 · raw

@fuel:Nat -> @c:0x2355f41b6f5561f50104a75ccca27cf7/bytes.Cut -> @+sep:List<&2, U32> -> @+size:Nat -> @acc:List<&2, U32> -> List<&2, U32>

The pieces of a payload, the separator between them.

def Rtmp.ext source · line 74 · raw

@big:Bool -> @ts:U32 -> List<&2, U32>

def Rtmp.message source · line 85 · raw

@+cs:U32 -> @typ:U32 -> @sid:U32 -> @+ts:U32 -> @+payload:List<&2, U32> -> @+size:U32 -> List<&2, U32>

A message as chunks of at most size bytes on chunk stream cs (2 to 63): the first after a full header (type 0), the others after a one-byte one (type 3). A timestamp that does not fit 3 bytes goes as FFFFFF there and in 4 bytes after each header.

def Rtmp.out source · line 97 · raw

U32

The chunk size this client announces and then writes with (the protocol starts at 128).

def Rtmp.control source · line 102 · raw

@typ:U32 -> @data:List<&2, U32> -> List<&2, U32>

Protocol control (on chunk stream 2, message stream 0; they are smaller than any chunk size).

def Rtmp.chunk_size source · line 106 · raw

@n:U32 -> List<&2, U32>

Set Chunk Size (1).

def Rtmp.ack source · line 110 · raw

@n:U32 -> List<&2, U32>

Acknowledgement (3): the bytes received so far.

def Rtmp.buffer source · line 114 · raw

@sid:U32 -> @ms:U32 -> List<&2, U32>

User control (4): event 3 is Set Buffer Length, 7 the answer to a ping.

def Rtmp.pong source · line 117 · raw

@data:List<&2, U32> -> List<&2, U32>

def Rtmp.command source · line 121 · raw

@cs:U32 -> @sid:U32 -> @ts:List<&2, 0x2355f41b6f5561f50104a75ccca27cf7/amf.Tok> -> List<&2, U32>

A command (20) of AMF0 values.

def Where.end source · line 132 · raw

@has:Bool -> @app:String -> @seg:String -> Where

def Where.slash source · line 139 · raw

@has:Bool -> @app:String -> @seg:String -> String

def Where.go source · line 147 · raw

@s:String -> @+has:Bool -> @+app:String -> @+seg:String -> @+query:Bool -> Where

app and seg are kept reversed; a "/" before the query ends a part.

def Where.of source · line 156 · raw

@path:String -> Where

def Where.app source · line 163 · raw

@w:Where -> String

def Where.stream source · line 167 · raw

@w:Where -> String

def Rtmp.connect source · line 174 · raw

@+app:String -> @host:String -> @port:U32 -> List<&2, U32>

connect, transaction 1: the application, its URL, and the codecs of enhanced RTMP this client reads (H.265), which a server sends only to a client that names them.

def Rtmp.create source · line 189 · raw

List<&2, U32>

createStream, transaction 2: its result carries the stream's id.

def Rtmp.play source · line 193 · raw

@+sid:U32 -> @stream:String -> List<&2, U32>

play on the stream, and how much the server may send ahead.

def Dec.new source · line 219 · raw

Dec

def Lane.find source · line 222 · raw

@cs:List<&2, Lane> -> @+id:U32 -> Lane

def Lane.drop source · line 230 · raw

@cs:List<&2, Lane> -> @+id:U32 -> List<&2, Lane>

def Rtmp.done source · line 240 · raw

@full:Bool -> @id:U32 -> @+ts:U32 -> @field:U32 -> @len:U32 -> @+typ:U32 -> @+sid:U32 -> @got:U32 -> @parts:List<&2, List<&2, U32>> -> @+size:U32 -> @others:List<&2, Lane> -> @rest:List<&2, U32> -> Step

The message is whole, or not yet.

def Rtmp.data source · line 252 · raw

@c:0x2355f41b6f5561f50104a75ccca27cf7/bytes.Cut -> @+n:U32 -> @ch:Lane -> @size:U32 -> @others:List<&2, Lane> -> Step

def Rtmp.body source · line 264 · raw

@+v:U32 -> @abs:Bool -> @fresh:Bool -> @ch:Lane -> @r:List<&2, U32> -> @+size:U32 -> @others:List<&2, Lane> -> Step

The chunk's data: up to the chunk size of what the message lacks. A chunk that starts a message moves the timestamp by v, or to v after a type 0 header.

def Rtmp.time source · line 272 · raw

@big:Bool -> @+field:U32 -> @abs:Bool -> @fresh:Bool -> @ch:Lane -> @r:List<&2, U32> -> @size:U32 -> @others:List<&2, Lane> -> Step

def Lane.field source · line 282 · raw

@ch:Lane -> U32

def Lane.fresh source · line 286 · raw

@ch:Lane -> Bool

def Lane.with source · line 292 · raw

@kind:Nat -> @ch:Lane -> @+h:List<&2, U32> -> Lane

The header a chunk brings: all of it (type 0), without the stream (1), the time only (2); a new header starts a message over.

def Rtmp.timed source · line 306 · raw

@+ch:Lane -> @abs:Bool -> @fresh:Bool -> @r:List<&2, U32> -> @size:U32 -> @others:List<&2, Lane> -> Step

def Rtmp.header source · line 311 · raw

@c:0x2355f41b6f5561f50104a75ccca27cf7/bytes.Cut -> @+kind:Nat -> @ch:Lane -> @size:U32 -> @others:List<&2, Lane> -> Step

def Rtmp.format source · line 320 · raw

@fmt:Nat -> @+ch:Lane -> @r:List<&2, U32> -> @size:U32 -> @others:List<&2, Lane> -> Step

def Rtmp.stream source · line 332 · raw

@fmt:U32 -> @+id:U32 -> @r:List<&2, U32> -> @st:Dec -> Step

def Rtmp.basic source · line 338 · raw

@zero:Bool -> @one:Bool -> @cs:U32 -> @fmt:U32 -> @t:List<&2, U32> -> @st:Dec -> Step

The chunk stream's number: 6 bits, or in 1 or 2 more bytes when they say 0 or 1.

def Rtmp.chunk source · line 351 · raw

@st:Dec -> @buf:List<&2, U32> -> Step

One chunk off the buffer.

def Ev.words source · line 376 · raw

@+code:String -> @+desc:String -> String

def Ev.status.of source · line 379 · raw

@bad:Bool -> @end:Bool -> @code:String -> @desc:String -> @st:Dec -> @rest:List<&2, U32> -> Ev

def Ev.status source · line 390 · raw

@+code:String -> @desc:String -> @st:Dec -> @rest:List<&2, U32> -> Ev

An onStatus: the stream ended, was refused, or goes on.

def Ev.named source · line 396 · raw

@res:Bool -> @err:Bool -> @status:Bool -> @+ts:List<&2, 0x2355f41b6f5561f50104a75ccca27cf7/amf.Tok> -> @st:Dec -> @rest:List<&2, U32> -> Ev

def Ev.command source · line 408 · raw

@+ts:List<&2, 0x2355f41b6f5561f50104a75ccca27cf7/amf.Tok> -> @st:Dec -> @rest:List<&2, U32> -> Ev

def Ev.user source · line 414 · raw

@p:List<&2, U32> -> @st:Dec -> @rest:List<&2, U32> -> Ev

A user control message: event 6 is a ping; the rest is news.

def Ev.data source · line 424 · raw

@yes:Bool -> @p:List<&2, U32> -> List<&2, U32>

A data message as a file wants it: servers pass on the publisher's "@setDataFrame" in front of "onMetaData", and a reader of FLV expects the name first.

def Ev.script source · line 434 · raw

@p:List<&2, U32> -> @ts:U32 -> @st:Dec -> @rest:List<&2, U32> -> Ev

Of the data messages only the metadata goes to the file: servers also send their own notes as data (a sample-access flag, a status), and a reader of FLV takes each for a stream of its own.

def Ev.typed source · line 441 · raw

@media:Bool -> @data:Bool -> @cmd:Bool -> @user:Bool -> @typ:U32 -> @ts:U32 -> @p:List<&2, U32> -> @st:Dec -> @rest:List<&2, U32> -> Ev

def Ev.of source · line 455 · raw

@s:Step -> Ev

def Rtmp.event source · line 466 · raw

@st:Dec -> @buf:List<&2, U32> -> Ev

The next event of a buffer.

def Flv.header source · line 480 · raw

List<&2, U32>

The file's header (audio and video both announced), and the size of the tag before the first, which is none.

def Flv.tag source · line 485 · raw

@typ:U32 -> @+ts:U32 -> @+data:List<&2, U32> -> List<&2, U32>

A tag: the type, the data's size, the timestamp (its top byte last), stream 0, the data, and the tag's whole size after it.

def Flv.of source · line 491 · raw

@t:Tag -> List<&2, U32>

A tag's bytes in a file.