peacock

webrtc chunked video streaming

video playback

the webm video is decomposed into a header and a list of clusters.

we depend on the new MediaSource API, which is available in Chrome and can be enabled in Firefox Nightly in about://flags

there's a nice write-up of MediaSource at html5-demos, and ioncannon.net has some discussion on the segmentation of a webm video, though we partition more precisely based on webm structure into its codec-level clusters.

webrtc/p2p distribution

streams

in the case of a livestream, many peers want to watch a live broadcast simultaneously. the goal is to deliver clusters in realtime: it should take longer to watch a cluster than to deliver it through the network.

the protocol is push-based: a peer initiates a stream with either another peer or the server, and then will receive buffers until the connection is terminated.

static video files

for static video files (or live-rewinding a stream), peers can request arbitrary clusters, or ranges of clusters.

here the protocol is pull-based: a peer requests a specific cluster from the server or from another peer. in this case, peers must be aware of exactly which clusters are available from other peers.

timing

the quality of results is judged by the ability for large numbers of peers to play video without disruption to the stream.

protocol

peer to peer

{type: "stream-request", streamtime:} // if streamtime is given, start with clusters thereafter (otherwise start with header + new clusters)
{type: "stream-response", accept: (true,false), peertime:}
{type: "stream-cluster", peertime:, streamtime:}
[ArrayBuffer()]

a peer can approximate the speed of a connection by comparing the time a cluster is received with the "peertime" attribute specifying when it was sent (relation between the peers' clocks can be roughly ascertained by comparing the "peertime" of "stream-response" to the client time when sending the "stream-request" and receiving that message.

peer to server

{type: "join-stream", stream: }
{type: "leave-stream" }
//from:0 == server, speed in kB/s
{type: "got-cluster", from:, size:, speed:, streamtime:}
{type: "request-more-peers" }
{type: "tracking-request" }
{type: "offer", to:, data:}
{type: "answer", to:, data:}
{type: "icecandidate", to:, data:}

the server can use data from got-cluster to model the in- and outbound bandwidth of peers to predict which ones have the capacity to stream to additional peers.

by issuing a "tracking-request," a client can subscribe to all of the cluster-request activities.

server to peer

{type: "peers", peers: [ ]}
{type: "offer", to:, from:, data:}
{type: "answer", to:, from:, data:}
{type: "icecandidate", to:, from:, data:}
// the "to" field alerts a peer to their own Id
{type: "availability", to:, clusters: {timecode: [peerid, ..], }}
// sent repeatedly after "tracking-request" is issued
{type: "got-cluster", from:, to:, size:, speed:, streamtime:}

git clone git://git.numm.org/peacock

snapshot: peacock.zip

files