cover image for post 'How to Find the Video URL of Twitch.tv Streams'

How to Find the Video URL of Twitch.tv Streams

extract video URLs to watch live streams through VLC for reduced lagging or to download entire past broadcasts

In this blog post I previously described how in 2014 the URLs of Twitch streams could be extracted for playback in VLC. This information is hopelessly outdated 10 years later and has therefore been deleted.

One possible alternative might be Streamlink.

Archived Comments

Note: I removed the Disqus integration in an effort to cut down on bloat. The following comments were retrieved with the export functionality of Disqus. If you have comments, please reach out to me by Twitter or email.

kolyall Jan 23, 2014 13:17:09 UTC

Now it doesn't work

Johannes Jan 23, 2014 22:18:35 UTC

Both API calls still work for me
- http://api.justin.tv/api/br...
- http://usher.twitch.tv/sele...

The first call always returns JSON formatted data with a couple of video urls; the second call returns "[]" if the stream is offline. But it's Twitch after all and they are constantly trying to resolve their many issues by tinkering with their servers, so maybe the API was down for a while.

Edit: I updated the post with notes on how to get the token and signature for the live stream url. They might be required if your not visiting the channel page first.

Ken Jan 24, 2014 19:52:40 UTC

- http://usher.twitch.tv/sele...
[
{
url: "/select/sirhcez.json?nauthsig=&nauth=&allow_source=true",
type: "error",
error: "missing token"
}
]
it missing token..

Johannes Jan 27, 2014 14:58:08 UTC

For me too, it seems like they are checking the token now. I updated the post on how to get the token. This Python snippet currently works for me (with European and US IP): https://gist.github.com/bad...

Sandra Feb 02, 2014 20:44:53 UTC

It's "Exception", not "Exeption". I know this because I got the exception triggered: "API returned 404".

Johannes Feb 05, 2014 21:37:37 UTC

Fixed it, thanks.

Samme Feb 06, 2014 14:45:39 UTC

The call to get the available streams is currently just returning an emtpy json array.
I sniffed the calls livestreamer do and it sends an additional parameter; "p" (p as in password?) wich seems to be generated for each call. You think that parameter is required now or am I just doing something wrong?

Samme Feb 06, 2014 20:06:17 UTC

Nevermind, it works. I indeed did something wrong...

Spit Feb 16, 2014 11:04:08 UTC

Can you tell me what you did wrong because i am too are getting just an empty json array

Sandra Feb 08, 2014 22:35:00 UTC

Johannes, thank you so much for finding this api. I got the 404 on the first few videos I tried, but it works on some. Just making a guess, I'd say that it doesn't work on older videos? But that's just guessing. The videos I tried to watch were these: http://www.twitch.tv/teamco... I tried to see the Plugged-In Tour - Final Round - Top Table but it just gave me a 404. I tried the LCG Night and it did download the file. It crashed when trying to call json() on the request object, so there's something else weird going on.

For now, I just did a sed 's/"/\n/g' 501571848.json\?onsite=true|grep flv$|xargs totem

Rik Jun 09, 2014 23:58:52 UTC

I would like to know how to find these API links. i tried to find them with the chrome developer toolkit, but i didn't see it passing by.
I know I can use these now, but if they change it in the future i would like to know how to find it.

Thanks in advance!

Johannes Jun 11, 2014 14:36:45 UTC

I prefer to use Wireshark.
- Start capturing; open the URL of the live stream in your browser; stop capturing when the video starts playing.
- Filter for <tt>http.response.phrase == "OK"</tt>. This should provide you with a list of delivered HTTP content.
- Look for interesting content types in the info column, like application/json or application/vnd.apple.mgegurl.

When I tested it today, the first "application/vnd.apple.mpegurl" was a list of urls to different qualities of the stream. To see what triggered this response, simply click the "[Request in frame: ...]" link in the HTTP header display in Wireshark or use "follow tcp stream". In my case there was a call to "usher.twitch.tv/select/gsl.......". This gives you the API call to get the video urls.

Rik Jun 12, 2014 00:57:06 UTC

Thanks a lot for the info!!
I did try Wireshark, but I'm not too familiar with it.
I'll try this coming weekend and see if i can find anything of interest.

DatOneDude Aug 16, 2014 07:26:16 UTC

This is fantastic! thank you sir - you made my day

Austin T. Aug 28, 2014 13:02:12 UTC

Hi! I'm attempting to pull this data out manually (and then transition it into java code).
I'm getting something like this:

[{"url": "/select/lmqtcvasilii.json?nauthsig=625793f94f2354bbadd0faf1acb721fe9b59c0b2;nauth=%22{\\%22user_id\\%22:46105340,\\%22channel\\%22:\\%22lmqtcvasilii\\%22,\\%22expires\\%22:1409217507,\\%22chansub\\%22:{\\%22view_until\\%22:1924905600,\\%22restricted_bitrates\\%22:[]},\\%22private\\%22:{\\%22allowed_to_view\\%22:true},\\%22privileged\\%22:false}%22;allow_source=true", "type": "error", "error": "missing token"}]

"Missing Token", and I have no idea why. Could you take a moment to explain?

Johannes Aug 29, 2014 12:45:55 UTC

It seems like you used the semicolon to separate the nauthsig and nauth pairs, try to use &:
.... 59c0b2;nauth=%22{\\%22use ... ----> .... 59c0b2&nauth=%22{\\%22use ...

Austin T. Aug 29, 2014 15:38:51 UTC

Hi, thanks for the quick reply.
I put everything into a program to automatically generate new urls.

http://usher.twitch.tv/sele..."{\"user_id\":null,\"channel\":\"ongamenet\",\"expires\":1409313212,\"chansub\":{\"view_until\":1924905600,\"restricted_bitrates\":[\"archives\",\"live\",\"high\",\"source\",\"chunked\"]},\"private\":{\"allowed_to_view\":true},\"privileged\":false}"&allow_source=true

But for whatever reason all I get is an empty json array.

[]

I think that's why I substituted the ampersand for a semicolon, partially because one of your examples used semicolons. I get only empty arrays with an ampersand. When I tried semicolons I at least got an error.

Johannes Aug 29, 2014 16:40:09 UTC

Try the following changes:
- no quote after nauth=, and no quote before &allow_source
- don't escape any quote (\" -> ")

For example:
http://usher.twitch.tv/sele...{"user_id":null,"channel":"starladder1","expires":1409316907,"chansub":{"view_until":1924905600,"restricted_bitrates":["archives"]},"private":{"allowed_to_view":true},"privileged":false}&allow_source=true

Austin T. Aug 30, 2014 01:30:10 UTC

Great, thank you very much.
It works

vriska Oct 14, 2014 17:59:36 UTC

hey the api call for past broadcasts doesn't work now. it always returns a 404 page

Johannes Oct 14, 2014 18:59:33 UTC

Thank you for pointing that out. It seems like the api.justin.tv has been shut down. The following works for me: If you want to download the past broadcast http://www.twitch.tv/riotga..., make the following API call: https://api.twitch.tv/api/v...

So for http://www.twitch.tv/riotga...

$ curl -H 'Accept: application/json' -X GET https://api.twitch.tv/api/v... | python -m json.tool

which should give you a JSON formatted list of video urls:

{
"api_id": "a577357806",
"broadcaster_software": "fme",
"channel": "riotgames",
"chunks": {
"240p": [
{
"length": 1800,
"upkeep": null,
"url": "http://media-cdn.twitch.tv/...",
"vod_count_url": "http://countess.twitch.tv/p..."
},
{
"length": 1802,
"upkeep": "pass",
"url": "http://media-cdn.twitch.tv/...",
"vod_count_url": "http://countess.twitch.tv/p..."
},

Edit: I updated the blog post and Gist.

Rik Oct 16, 2014 02:37:25 UTC

If it is a subscriber only channel, with the new API you have to be a subscriber to check the url. so it's now impossible to watch VOD's of subscribers without being a subscriber.
So you have to also specify the OAuth code of an account that you want to download. that must also be specified in the url, so the curl command will be as follows:
curl -H "Accept: application/json" -H "Authorization: OAuth " -X GET https://api.twitch.tv/api/v...

Travis Nov 20, 2014 08:15:15 UTC

Is this still working? I'm trying to get a list of m3u8 video links, which worked fine about two weeks ago, but no for some reason is returning [] (empty json response array).

This is the request:
http://usher.twitch.tv/sele...{%22user_id%22:null%2C%22channel%22:%22nightblue3%22%2C%22expires%22:1416452994%2C%22chansub%22:{%22view_until%22:1924905600%2C%22restricted_bitrates%22:[]}%2C%22private%22:{%22allowed_to_view%22:true}%2C%22privileged%22:false}&allow_source=true

Note: I have tried both URL encoding the request (hence , become %2C, and " become %22) and not (and a combination of encoding , or " only) to no avail.

Thanks.

someguy123 Nov 22, 2014 19:39:02 UTC

I used the same url for about 2-3 months, now it doesn't work. I used Wireshark to get the requests the browser sends when viewing streams and for the last 2 days the requests look different every single time. Here are some examples:
The one I "fixed to work" 2 days ago:
usher.twitch.tv/api/channel..."+id123+".m3u8?token=%7B%22user_id%22%3Anull%2C%22channel%22%3A%22"+id+"%22%2C%22expires%22%3A"+expires+"%2C%22chansub%22%3A%7B%22view_until%22%3A"+view_until+"%2C%22restricted_bitrates%22%3A%5B%5D%7D%2C%22private%22%3A%7B%22allowed_to_view%22%3Atrue%7D%2C%22privileged%22%3Afalse%2C%22source_restricted%22%3Afalse%7D&segment_preference=2&sig="+sig;
Yesterday:
usher.twitch.tv/api/channel... HTTP/1.1

Today:

usher.twitch.tv/api/channel... HTTP/1.1

I don't know what they are doing. Is it possible they want to stop exactly what we are doing ?

kolyall Dec 12, 2014 15:49:55 UTC

Today API call to doesn't work for me
http://usher.twitch.tv/sele...

kolyall Dec 12, 2014 15:50:50 UTC

code responce is always 404

Rik Dec 14, 2014 21:55:22 UTC

That is right, twitch has updated their API (again)
you have to request a token here: http://api.twitch.tv/api/ch...{channel}/access_token
and then you have to use the new URL:

python code: "http://usher.twitch.tv/api/...{CHANNEL}.m3u8?player=twitchweb&token={ENCODED_TOKEN}&sig={SIG}&allow_audio_only=true&allow_source=true&type=any&p={RANDOM}".format(CHANNEL=channel,SIG=access_token_sig,ENCODED_TOKEN=urllib.quote_plus(access_token),RANDOM=int(random() * 999999))

this is an example of a valid request: "http://usher.twitch.tv/api/..."

Rik Dec 14, 2014 21:57:17 UTC

this is an example of a valid request: "http://usher.twitch.tv/api/..."

steve Dec 20, 2014 17:20:35 UTC

I was using something similar to livestreamer but it would embed vlc on the twitch page instead of using VLC by itself.. The person who made this said the new API doesn't provide "source" quality and its the only limitation he could see . His bandaid works fine but the "best" quality is "high" setting and not source. Thanks for your time.

https://github.com/DeniSix/...

steve Dec 20, 2014 17:26:50 UTC

Also i emailed a livestreamer dev about it. He said "make sure you pass "allow_source=true" as a query parameter to the HLS playlist." but I dont think it worked when i tried. maybe i did it wrong

Rik Dec 23, 2014 21:39:00 UTC

It's right that you have to pass "allow_source=true". check my comment (the one above you). That should do the trick =). "allow_audio_only=true" also adds the option to only listen to the stream.

joen Jan 04, 2015 20:36:31 UTC

looks like twitch changed something again

"Transcode does not exist" when I try and grab the live stream stuff

e.g.

"http://usher.twitch.tv/api/..."

I've Tried this with and without allow_source

Rik Jan 05, 2015 18:57:52 UTC

It seems like your request was correct. I've tried a request and it still seems to work.

Make sure that the channel is live ;) , I've only seen that message when i tried to get the m3u for a channel that wasn't live at that moment.

Johannes Jan 05, 2015 19:46:56 UTC

Your API update also works for me. Thanks for posting the changes in the comments, I fixed my Gist file accordingly.

Jendos Jan 27, 2015 01:19:17 UTC

i dont know, ive tried few times and always gettin errors like "invalid token" can someone help me with draskyl's stream?

rikels May 04, 2015 22:43:14 UTC

Twitch just updated their past broadcasts... at least, I now get 3 second parts (just like the live stream) like index-0000000014-pAWB.ts for the channel I watch.

I think you can check here to see if the channel you follow uses the new implementation: https://api.twitch.tv/api/c... (the part: "use_new_rtmp_impl":true)

The m3u is always called index-dvr.m3u8, but the link where it is located is a bit hard for me to find out. I don't have to much time to dig deeper now.

Rikels May 07, 2015 10:19:42 UTC

Okay, I finally had time to dig a little deeper.

what you have to do, is request an access token before you can request the M3U file that is used for the past broadcast stream (yes, this is totally different from how it worked previously, it's now quite close to grabbing the live url)

request a token via the following url:
https://api.twitch.tv/api/v...{ID of the VOD you want to wacht}/access_token?as3=t&oauth_token={the oauth token from your Twitch account}

after that, copy the strings in the following url:
"http://usher.justin.tv/vod/...{sig}&nauth={token}".format(sig=sig,token=token)

than you'll get an M3U file which you can watch via VLC or any other good video player ;)

preview of a valid url, yes if you try, it will say invalid, because I changed the ID's and the token probably ran out of time. It's here just so you have a preview of a correct looking url.

http://usher.justin.tv/vod/...{"user_id":35065643,"vod_id":4746543,"expires":1431063621,"chansub":{"restricted_bitrates":[]},"privileged":true}

rikels May 10, 2015 20:30:38 UTC

The new link for the info of the broadcast can be found here:

https://api.twitch.tv/krake...{ID}

Rikels Jul 22, 2015 15:46:46 UTC

recently they changed the API, you now have to pass "allow_source=true" in the API call to retrieve the raw (Chunked) stream. just like you had to in the old API. The audio only is also gone, for that add "allow_audio_only=true" to the request. Example: http://usher.justin.tv/vod/{ID}?allow_source=true&allow_audio_only=true&nauth={NAUTH}&nauthsig={NAUTHSIG}&player=twitchweb

kondratovich May 17, 2015 10:42:29 UTC

There is a type at '$allow_audio_only=true'

manyanimals Jun 27, 2015 14:54:36 UTC

I just find an easy method to free download twitch videos at http://www.allavsoft.com/ho...

Hope it is what you are looking for.

random23u23u89ee8u89oi May 31, 2016 12:54:34 UTC

Thank you! In the progress of making a chrome extension replacing the flash player with html5. Any idea on how to get commercials links?

Guest Mar 09, 2017 12:53:44 UTC

Thanks for the article!
Unfortunately it didn't works for me, but this did:
https://github.com/systoolz...
I hope it helps.

aKanG cuPez Mar 28, 2017 06:10:28 UTC

I have created a simple PHP library for extracting the video or channel streaming from TwitchTV
https://github.com/akangcup...

any suggestions and forks are welcomed

tari fari May 30, 2017 09:09:01 UTC

Hey, i think twitch modified their api functions. Can you update this version? Want to use this code for my bouquet creator to use twitch streams as a normal channel on enigma2 receivers