Someone on Github asked for Steam Broadcast support in livestreamer. Steam Broadcast is a neat new feature of the Steam client that encodes and broadcasts whatever you’re doing to everyone, your steam friends, or only people you invite. It’s viewable using the HTML5 <video> element in Chrome and through the Steam Client, but not yet available to 3rd party viewers. The ticket in question:

It just got introduced this morning, and it's be nice to see it implemented. http://steamcommunity.com/?subsection=broadcasts

PolarManne

So let’s take a look at how the video is playing in the browser. For now, it appears to require a logged in user to work.

Note: Examples are all for this live stream.

First, a request is made to get the video stream. Using the steam community ID of the user streaming the video (in this case 76561198067563695) and a hardcoded broadcastid of 0, we get:

GET http://steamcommunity.com/broadcast/getbroadcastmpd/?steamid=76561198067563695&broadcastid=0
{
    "success": "ready",
    "retry": 0,
    "broadcastid": "12547374920780913142",
    "url": "http://81.171.106.194:80/broadcast/3118622223253298157/manifest/?viewer=87917971236267582",
    "appid": "570",
    "app_title": "Dota 2",
    "title": "Dota 2",
    "viewer_count": 194
}

Then you take the url value in the returned JSON to find the manifest. Example:

GET http://81.171.106.194/broadcast/3118622223253298157/manifest/?viewer=user_id

Where user_id is the logged-in user’s steam community ID. It’ll be a long number similar to 76561198067563695.

<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic" availabilityStartTime="2014-12-02T19:54:15Z" publishTime="2014-12-02T19:54:15Z" minimumUpdatePeriod="PT30S" minBufferTime="PT3S" timeShiftBufferDepth="PT120S">
<Period id="1" start="PT0S">
<AdaptationSet id="1" segmentAlignment="true" startWithSAP="1" maxWidth="1280" maxHeight="720" lang="und">
<ContentComponent id="1" contentType="video"/>
<ContentComponent id="2" contentType="audio"/>
<SegmentTemplate timescale="1000" duration="3000" media="http://broadcast.akamai.steamstatic.com/broadcast/3118622223253298157/segment/$Number$/?broadcast_origin=par_valve129" startNumber="1" initialization="http://broadcast.akamai.steamstatic.com/broadcast/3118622223253298157/segment/init/?broadcast_origin=par_valve129"/>
<Representation id="main" mimeType="video/mp4" codecs="avc1.4d4032,mp4a.40.2" sar="1:1" audioSamplingRate="48000" startWithSAP="1" bandwidth="3500"></Representation>
</AdaptationSet>
</Period>
</MPD>

These videos can be rewound, and appear to be in 3 second chunks (the duration field, divided by the timescale field). So for every 3 seconds, you make a request to

  • http://broadcast.akamai.steamstatic.com/broadcast/3118622223253298157/segment/1/?broadcast_origin=par_valve129
  • http://broadcast.akamai.steamstatic.com/broadcast/3118622223253298157/segment/2/?broadcast_origin=par_valve129
  • etc…

… to get the next/previous chunk of video.

Notes:

  • It looks like this has been setup to allow multiple streams per user, but currently m_ulBroadcastID is hardcoded to 0, so any url that has a broadcastid in it should just be 0.
  • All of the IDs used in the broadcast system are steam community ids (big long numbers like 76561198067563695) and not the older steamids.
  • There is only one codec supported, video/mp4;codecs=”avc1.4d4032,mp4a.40.2