Counter-Strike: Global Offensive Broadcast

From Valve Developer Community
Jump to: navigation, search
Dead End - Icon.png
This article has no links to other VDC articles. Please help improve this article by adding links that are relevant to the context within the existing text.
January 2024

Counter-Strike: Global Offensive Broadcast is an alternative distribution method for GOTV spectators. It is based on HTTP as the transport protocol and implementations must follow a set of defined standards. It is built around 3-second "fragments" that contain GOTV data for the client to consume. Each fragment is identified by a number unique to the broadcast and increments sequentially.

Enabling Broadcasting in srcds

Enabling broadcasting on the server is as simple as setting a few cvars:

tv_broadcast_url - the base endpoint address to which data will be sent. Example:

 tv_broadcast_url "http://gotv-ingest.example.com"

tv_broadcast_origin_auth - arbitrary string that is sent with requests to the broadcast URL in a header named "X-Origin-Auth"

 tv_broadcast_origin_auth "SuperSecureStringDoNotShare"

tv_broadcast - enable or disable broadcasting (0 or 1)

 tv_broadcast 1

Receiving Gameplay Data from the Server

To receive data from the gameserver, an API will need to listen on the following URLs:

  /{token}/{fragment_number}/start
  /{token}/{fragment_number}/full?tick=1882
  /{token}/{fragment_number}/delta?endtick=2144

The token is part of all requests from the gameserver to the URL endpoints and contains both the Steam ID of the gameserver and a "master cookie" to disambiguate requests. It is in the format of:

 sSTEAMIDtMASTERCOOKIE

For example:

 s845489096165654t8799308478907

START request

When broadcasting is enabled on the server, the gameserver will first send a /start request to the endpoint. The query string will contain information about the broadcast that must be persisted. In addition, the content of the request should be persisted so that it can be made available to clients. The query string for the request has the following parameters:

  • tick - the starting tick of the broadcast
  • tps - the tickrate of the GOTV broadcast
  • map - the name of the map
  • protocol - the protocol version (currently 4)

So in our example, the following URL would be hit when the broadcast starts:

http://gotv-ingest.example.com/s845489096165654t8799308478907/1/start

(where 1 is the fragment number).

FULL request

Ex: http://gotv-ingest.example.com/s845489096165654t8799308478907/2/full?tick=1882

Contains a full snapshot for clients. Content is binary data and should be persisted. Tick number and fragment number for the fragment should be persisted. Note: if a /full or /delta request is received for a broadcast that has not received a START request, you MUST respond with HTTP status code 205 (Reset Content). This will cause the game server to retransmit a "start" request. Otherwise, you SHOULD return a HTTP 200.

DELTA request

Ex: http://gotv-ingest.example.com/s845489096165654t8799308478907/2/delta

Contains a delta snapshot for clients. Content is binary data and should be persisted. Note: if a /full or /delta request is received for a broadcast that has not received a START request, you MUST respond with HTTP status code 205 (Reset Content). This will cause the game server to retransmit a "start" request. Otherwise, you SHOULD return a HTTP 200.

Playback in the Client

To start playback clients have to issue the playcast command with the "base URL" for your API.

For example:

 playcast "http://gotv-cdn.example.com/match/s845489096165654t8799308478907"

Note: there is no technical limitation requiring the SteamID and Master Cookie to be present in the URL passed to the client. Your implementation may vary.

Once executed, the CS:GO client will issue a series of web requests to initialize and stream the playback of content. To provide GOTV data to CS:GO clients, the following endpoints need to be defined:

 /sync
 /{fragment_number}/start
 /{fragment_number}/full
 /{fragment_number}/delta

SYNC

Tells the CS:GO client where to start playback for the broadcast. The endpoint should select a FULL payload to use as the first fragment to send. Endpoint MUST return a JSON document containing the following fields:

  • tick - the tick number corresponding to the FULL fragment to be used
  • rtdelay - the number of seconds since the select FULL fragment has been received
  • rcvage - the number of seconds since the server received the latest FULL fragment
  • fragment - the fragment number of the FULL fragment used
  • signup_fragment - the fragment number for the START request of the broadcast
  • tps - the ticks per second (as specified in the START request)
  • protocol - the protocol version (as specified in the START request)

Any FULL fragment can be used as the starting fragment. If you experience buffering in CS:GO while testing playback, you may want to select a fragment further back in the broadcast as the starting fragment (for example, N-4, where N is the last FULL fragment number received).

If using a CDN, this should only be cached for a short period of time (such as 5 seconds) so that clients that connect later are reasonably in-sync with other viewers.

Example document:

 {
   tick: 139527,
   rtdelay: 1,
   rcvage: 1,
   fragment: 2,
   signup_fragment: 0,
   tps: 128,
   protocol: 4
 }

START

Ex: http://gotv-cdn.example.com/match/s845489096165654t8799308478907/1/start

This should return the content provided to the START endpoint by the game server for the same fragment number. If using a CDN, this can be cached indefinitely.

FULL

Ex: http://gotv-cdn.example.com/match/s845489096165654t8799308478907/2/full

This should return the content provided to the FULL endpoint by the game server for the same fragment number. If using a CDN, this can be cached indefinitely.

DELTA

Ex: http://gotv-cdn.example.com/match/s845489096165654t8799308478907/2/delta

This should return the content provided to the DELTA endpoint by the game server for the same fragment number. If using a CDN, this can be cached indefinitely.