Tracking Viewer Ratings of Twitch Stream Minute-by-Minute
This blog post shows how to use the Twitch API to retrieve the current number of viewers of a channel. See this page for an application example.
Get your API key
Although you can use the API without key, using the client_id is recommended to make sure you are to rate limited by Twitch. You can get the client_id by going to https://secure.twitch.tv/settings/connections and registering a new application:
The client ID will automatically be generated for you:
Calling the API response
You call the API with requests to
https://api.twitch.tv/kraken/streams/<CHANNEL>?client_id=<YOUR_CLIENT_ID>
For example, to get the information for channel manvsgame and client_id abcdef1234567890 you would request:
https://api.twitch.tv/kraken/streams/manvsgame?client_id=abcdef1234567890
If the channel is offline, the response will look like that:
{u'_links': {u'channel': u'https://api.twitch.tv/kraken/channels/manvsgame', u'self': u'https://api.twitch.tv/kraken/streams/manvsgame'}, u'stream': None}
If the channel is online, the response will look like that:
{u'_links': {u'channel': u'https://api.twitch.tv/kraken/channels/manvsgame', u'self': u'https://api.twitch.tv/kraken/streams/manvsgame'}, u'stream': {u'_id': 7797659104L, u'_links': {u'self': u'https://api.twitch.tv/kraken/streams/manvsgame'}, u'channel': {u'_id': 8330235, u'_links': {u'chat': u'https://api.twitch.tv/kraken/chat/manvsgame', u'commercial': u'https://api.twitch.tv/kraken/channels/manvsgame/commercial', u'editors': u'https://api.twitch.tv/kraken/channels/manvsgame/editors', u'features': u'https://api.twitch.tv/kraken/channels/manvsgame/features', u'follows': u'https://api.twitch.tv/kraken/channels/manvsgame/follows', u'self': u'https://api.twitch.tv/kraken/channels/manvsgame', u'stream_key': u'https://api.twitch.tv/kraken/channels/manvsgame/stream_key', u'subscriptions': u'https://api.twitch.tv/kraken/channels/manvsgame/subscriptions', u'teams': u'https://api.twitch.tv/kraken/channels/manvsgame/teams', u'videos': u'https://api.twitch.tv/kraken/channels/manvsgame/videos'}, u'abuse_reported': None, u'background': u'http://static-cdn.jtvnw.net/jtv_user_pictures/manvsgame-background_image-10842e1c129df87d.png', u'banner': None, u'created_at': u'2009-09-17T19:42:52Z', u'delay': 0, u'display_name': u'MANvsGAME', u'game': u'I Wanna Be The Guy', u'logo': u'http://static-cdn.jtvnw.net/jtv_user_pictures/manvsgame-profile_image-731e0a1382912c9c-300x300.png', u'mature': True, u'name': u'manvsgame', u'profile_banner': u'http://static-cdn.jtvnw.net/jtv_user_pictures/manvsgame-profile_banner-926ae0b81e5737df-480.png', u'profile_banner_background_color': None, u'status': u'MAN vs I WANNA BE THE GUY - I Wanna Be The Month!', u'updated_at': u'2013-12-10T08:06:53Z', u'url': u'http://www.twitch.tv/manvsgame', u'video_banner': u'http://static-cdn.jtvnw.net/jtv_user_pictures/manvsgame-channel_offline_image-c01cba2e538ae8f5-640x360.jpeg', u'views': 26903371}, u'game': u'I Wanna Be The Guy', u'preview': {u'large': u'http://static-cdn.jtvnw.net/previews-ttv/live_user_manvsgame-640x400.jpg', u'medium': u'http://static-cdn.jtvnw.net/previews-ttv/live_user_manvsgame-320x200.jpg', u'small': u'http://static-cdn.jtvnw.net/previews-ttv/live_user_manvsgame-80x50.jpg', u'template': u'http://static-cdn.jtvnw.net/previews-ttv/live_user_manvsgame-{width}x{height}.jpg'}, u'viewers': 9233}}
The number of viewers is in ‘stream’ -> ‘viewers’ (e.g. 9233).
Example code
The following Python continuously calls the API and stores the number of viewers to a log file (make sure to add your client_id).
import requests import json from datetime import datetime, timedelta import time import logging import argparse BASE_URL = 'https://api.twitch.tv/kraken/' CLIENTID = '<add your API key here>' def start_logging(logfile='log.txt'): log = logging.getLogger() log.setLevel(logging.DEBUG) ch = logging.StreamHandler() fh = logging.FileHandler(logfile) log.addHandler(ch) log.addHandler(fh) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) def get_viewers(stream_name): url = '{0}streams/{1}?client_id={2}'.format(BASE_URL, stream_name, CLIENTID) r = requests.get(url) if r.status_code != 200: raise Exception("API returned {0}".format(r.status_code)) infos = r.json() stream = infos['stream'] results = {} if not stream: results = {'online':False,'title':None,'viewers':0} else: viewers = stream['viewers'] title = stream['channel']['status'] results = {'online':True,'title':title,'viewers':viewers} results['time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') results['stream'] = stream_name return results def constant_polling(stream, onint=1,offint=5): logging.info("starting polling, inteval is " + "{0}min (online) and {1}min (offline)".format(onint, offint)) while True: online = False try: res = get_viewers(stream) online = res['online'] txt = json.dumps(res) logging.info("Streamviewercount: {0}".format(txt)) except Exception as e: logging.warn("Polling failed: {0}".format(e)) sleep_interval = onint if online else offint time.sleep(60*sleep_interval) if __name__=="__main__": parser = argparse.ArgumentParser(description='log viewer rating of twitch' + ' stream') parser.add_argument('channel', help='channel name') parser.add_argument('--int_on', help='interval if online (min)', default=1) parser.add_argument('--int_off', help='interval if offline (min)', default=5) args = parser.parse_args() start_logging() constant_polling(args.channel, args.int_on, args.int_off)
[download GIST](nums:false https://gist.github.com/baderj/7893756). Sample log file output:
starting polling, inteval is 1min (online) and 5min (offline) Streamviewercount: {"stream": "dendi", "title": "time to practice !!! !!!!!! Dendimon", "time": "2013-12-10 17:38:10", "viewers": 24978, "online": true} Streamviewercount: {"stream": "dendi", "title": "time to practice !!! !!!!!! Dendimon", "time": "2013-12-10 17:39:12", "viewers": 23199, "online": true} Streamviewercount: {"stream": "dendi", "title": "time to practice !!! !!!!!! Dendimon", "time": "2013-12-10 17:40:15", "viewers": 21841, "online": true} Streamviewercount: {"stream": "dendi", "title": "time to practice !!! !!!!!! Dendimon", "time": "2013-12-10 17:41:16", "viewers": 21247, "online": true} Streamviewercount: {"stream": "dendi", "title": null, "time": "2013-12-10 17:42:19", "viewers": 0, "online": false}
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.