This CLI tool helps obtain the M3U8 file for Twitch VODs. It works even if a VOD is sub-only or unlisted. If the VOD is not on the Twitch servers, (i.e. one of their S3 buckets), then it is impossible to recover a VOD.
Build the binary.
If you don't want to build it, then just use go run ./cmd/govods.go {stuff}
.
go build ./cmd/govods # Make the binary
./govods --help # View help
./govods sg-manual-get-m3u8 --help # View help for command sg-manual-get-m3u8
- Open the network tab in developer tools
- Go to
https://sullygnome.com/channel/{streamer}/streams
- There should be a response with the XHR response type. View it.
- This response should have information about the recent streams in JSON format. It should include the following fields.
{ "startDateTime": "time", // start time of the stream in 2006-01-02T15:04:05Z format "streamId": "videoid" // video id of the stream }
- Then run the program with SullyGnome.
# Using manually retrieved SullyGnome data, write the .m3u8 file to ./Downloads ./govods sg-manual-get-m3u8 --time {time} --streamer {streamer} --videoid {videoid}
- Go to
https://streamscharts.com/channels/{streamer}/streams
to find a streamer's recent streams. Then go to the stream you want athttps://streamscharts.com/channels/{streamer}/streams/{videoid}
. - Open the Elements Tab in the Chrome developer tools.
- Select the first
<time>
element with thedatetime
attribute. Then copy thedatetime
attribute. It should be in the format02-01-2006 15:04
. You can get this value in the console withdocument.querySelector("time[datetime]").getAttribute("datetime");
- Then run the program with StreamsCharts.
# Using manually retrieved StreamCharts data, write the .m3u8 file to ./Downloads ./govods sc-manual-get-m3u8 --streamer {streamer} --videoid {videoid} --time {time}
- Go to
https://twitchtracker.com/{streamer}/streams
for the streamer's streams. - Open the Network tab in the Chrome developer tools. Then click on the stream you want.
- One of the responses should be the HTML. You can filter for it by clicking on the
Doc
filter near the top. Click on it. Then click on the response tab to show the actual HTML. - Search for
Stream started
in the HTML. Right above it should be the start time in2006-01-02 15:04:05
format. - Then run the program with TwitchTracker.
# Using manually retrieved TwitchTracker data, write the .m3u8 file to ./Downloads ./govods tt-manual-get-m3u8 --streamer {streamer} --videoid {videoid} --time {time}
You can pass in a JSON array with the structure:
[
{
"time": "2024-03-26T20:49:54Z",
"id": "43903162955",
"name": "streamer"
},
{
"time": "2024-03-19T14:32:06Z",
"id": "42424695993",
"name": "streamer"
}
// ...
]
The easiest way to get this JSON is to find the streamer at sullygnome.com
, click on Streams, open Dev Tools > Network Tab, then click on "past 90 days". Then a JSON request should show up in the Network Tab. The URL should look something like https://sullygnome.com/api/tables/channeltables/streams/90/13643637/%20/1/1/desc/0/50
.
You can fetch this link with the curl impersonate CLI tool.
Then you can use jq
to transform it into the form above.
Then pass the output to the STDIN of the program.
LINK=https://sullygnome.com/api/tables/channeltables/streams/90/13643637/%20/1/1/desc/0/50
FILTER='[ .data[] | {time: .startDateTime, id: .streamId|tostring, name: .channelurl} ]'
curl_chrome116 "$LINK" | jq -r "$FILTER" | ./govods stdin
Once we have fetched the files, we can serve them over a local web server.
For example, if you have python3
installed locally, you can run
# Serve the files over a local web server
python3 -m http.server 8080 --directory Downloads
Then you can see the files in http://localhost:8080
.
If you're using Google Chrome, you can install the Native HLS Playback and then click on one of the files to play it.
Alternatively, you can use a media player such as MPV or VLC to play the files.
You can also download the VOD locally with yt-dlp
.
# Play a file with MPV
mpv http://localhost:8080/{streamername}/{stuff}.m3u8
# Download the VOD
yt-dlp http://localhost:8080/{streamername}/{stuff}.m3u8 --concurrent-fragments 4
- A VOD might be shorter than expected. If a stream goes down for any length of time (even a few seconds), Twitch treats this as a new stream with a new
videoid
. In order to provide more accurate information, SullyGnome and TwitchTracker combine this into a single cast.streamscharts.com
seems to be the only website that separates the two VODs. In this case, you should checkstreamscharts.com
for the video ids. - A streamer changed their name. In this case, you need to use the streamer's login name at the time the stream started.
- A valid URL was found, but some segments are not playable. If some of the segments are not playable, you can filter them out with the
--filter-invalid
flag, specifying the number of goroutines to use while checking the segments. For example,This takes longer. It is slow if a lot of the segments are available. If a lot of the video is missing, it will be faster../govods sg-manual-get-m3u8 --time {time} --streamer {streamer} --videoid {videoid} --filter-invalid 100