Skip to content

Instantly share code, notes, and snippets.

@daggerhashimoto
Last active December 12, 2022 13:56
Show Gist options
  • Save daggerhashimoto/a4d31cf242548c663305f08ce2d22914 to your computer and use it in GitHub Desktop.
Save daggerhashimoto/a4d31cf242548c663305f08ce2d22914 to your computer and use it in GitHub Desktop.
Twitch viewer bot

Cagin Donmez (cd0x23) | 24/05/2016

Viewer bot #2342 online Kappa

So I got bored last night and played around with faking Twitch viewers. I've failed to actually find a practical way to do this but, switching on to Eric Zhang's method, I've been able to get "acceptable (aka "meh") results.

The issue is that Twitch uses HLS for streaming and limits 10 connections per IP. Any more than 10 connections are not counted as viewers on stream. So what I did was, I added proxies, but this also was no good because good luck finding free proxies capable of sending requests every 5 seconds. However premium proxies is worth giving a shot and might actually work.

There's also another issue with CPU usage. I've tested the script with 3 builder threads on my low-end Digitalocean server.

cpu

bandwidth

As you can see the CPU usage spikes around 90% while there's no noticable change in bandwidth usage, which is odd because one would think that bandwidth would be the bottleneck in this case. I should also note that I personally don't think this method is practical as well (unless you have awesome hardware) since this test costs such processing power only for 10 viewers. If you want more viewers you're gonna have to use premium speed proxies and much more threads running this code.

The main reason I'm writing this is actually seeing a lot of people having a hard time running the code mainly because it's outdated. The code I'm posting is updated and tested on both Windows and Ubuntu 14.04. I've also added a proxy option.

You need to meet these requirements to be able to run this code properly.

  • livestreamer
  • requests
  • pyopenssl
  • urllib3

###Troubleshooting If you're having parsing errors, you might want to check if livestreamer module is working properly. Also switching to "simplejson" to see a better error message might help too.

You need to modify the number of threads according to your hardware and needs or you might experience threading errors.

import requests
import subprocess
import json
import sys
import threading
import time
from Queue import Queue
import urllib3
import urllib3.contrib.pyopenssl
urllib3.contrib.pyopenssl.inject_into_urllib3()
#urllib3.disable_warnings() unverified HTTPS requests
numberOfViewers = int(sys.argv[1])
builderThreads = int(sys.argv[2])
startTime = time.time()
numberOfSockets = 0
concurrent = 25
urls = []
urlsUsed = []
proxies = {
'http': 'http://173.201.183.172:8000',
'http': 'http://94.181.34.64:81',
}
def getURL(): # Get tokens
output = subprocess.Popen(["livestreamer", "twitch.tv/swagvyper", "-j"], stdout=subprocess.PIPE).communicate()[0]
return json.loads(output)['streams']['worst']['url'] # Parse json and return the URL parameter
def build(): # Builds a set of tokens, aka viewers
global numberOfSockets
global numberOfViewers
while True:
if numberOfSockets < numberOfViewers:
numberOfSockets += 1
print "Building viewers " + str(numberOfSockets) + "/" + str(numberOfViewers)
urls.append(getURL())
def view(): # Opens connections to send views
global numberOfSockets
while True:
url=q.get()
# requests.head(url, proxies=proxies)
requests.head(url) # Sending a HEAD request is enough to count as a view
if (url in urlsUsed):
urls.remove(url)
urlsUsed.remove(url)
numberOfSockets -= 1
else:
urlsUsed.append(url)
q.task_done()
if __name__ == '__main__':
for i in range(0, builderThreads):
threading.Thread(target = build).start()
while True:
while (numberOfViewers != numberOfSockets): # Wait until sockets are built
time.sleep(1)
q=Queue(concurrent*2)
for i in range(concurrent):
try:
t=threading.Thread(target=view)
t.daemon=True
t.start()
except:
print 'thread error'
try:
for url in urls:
print url
q.put(url.strip())
q.join()
except KeyboardInterrupt:
sys.exit(1)
@rdvo
Copy link

rdvo commented Sep 23, 2017

did twitch brick this with new updates? Livestreamer not working?

@daggerhashimoto
Copy link
Author

daggerhashimoto commented Oct 10, 2017

@ovived I haven't looked into this for over a year so it's very much likely the code is bricked with the new updates.

@AlexCods
Copy link

Could you do another one that works? :(

@Alphacasters
Copy link

Alphacasters commented Nov 10, 2017

Nice work on this my friend! It is a bit outdated but I have successfully made some changes to it and can build tokens, and receive the stream url for the token just having trouble getting twitch to count the viewers at all!
I don't think headers alone are enough for twitch to count you as a viewer...any thoughts?
@CD0x23

@eliecer696
Copy link

console is giving me this error PLEASS HELPP!!

File "script.py.txt", line 36
print "Building viewers " + str(numberOfSockets) + "/" + str(numberOfViewers)
^
SyntaxError: invalid syntax)

@Bee-7
Copy link

Bee-7 commented Jul 14, 2018

SyntaxError: Missing parentheses in call to 'print'
thats all your problem

@VictorSiqueira
Copy link

I need some help, the code is giving me the following error, what can i do to fix it?

Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\Users\Victor\Desktop\twitch.py", line 37, in build
urls.append(getURL())
File "C:\Users\Victor\Desktop\twitch.py", line 28, in getURL
return json.loads(output)['streams']['worst']['url'] # Parse json and return the URL parameter
KeyError: 'streams'

Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\Users\Victor\Desktop\twitch.py", line 37, in build
urls.append(getURL())
File "C:\Users\Victor\Desktop\twitch.py", line 28, in getURL
return json.loads(output)['streams']['worst']['url'] # Parse json and return the URL parameter
KeyError: 'streams'

@darthvader666uk
Copy link

I seem to have to update the code a little to get it running. I THINK its correct:

import requests
import subprocess
import json
import sys
import threading
import time
from multiprocessing import Queue
import urllib3
import urllib3.contrib.pyopenssl

urllib3.contrib.pyopenssl.inject_into_urllib3()
#urllib3.disable_warnings() unverified HTTPS requests
numberOfViewers = int(sys.argv[1])
builderThreads = int(sys.argv[2])
startTime = time.time()
numberOfSockets = 0
concurrent = 25
urls = []
urlsUsed = []
proxies = {
    'http': 'http://173.201.183.172:8000',
    'http': 'http://94.181.34.64:81',
}


def getURL(): # Get tokens
  output = subprocess.Popen(["livestreamer", "twitch.tv/swagvyper", "-j"], stdout=subprocess.PIPE).communicate()[0]
  return json.loads(output)['streams']['worst']['url'] # Parse json and return the URL parameter

def build(): # Builds a set of tokens, aka viewers
	global numberOfSockets
	global numberOfViewers
	while True:
		if numberOfSockets < numberOfViewers:
			numberOfSockets += 1
			print("Building viewers " + str(numberOfSockets) + "/" + str(numberOfViewers))
			urls.append(getURL())

def view(): # Opens connections to send views
	global numberOfSockets
	while True:
		url=q.get()
        # requests.head(url, proxies=proxies)
		requests.head(url) # Sending a HEAD request is enough to count as a view
		if (url in urlsUsed):
			urls.remove(url)
			urlsUsed.remove(url)
			numberOfSockets -= 1
		else:
			urlsUsed.append(url)
		q.task_done()

if __name__ == '__main__':
	for i in range(0, builderThreads):
		threading.Thread(target = build).start()

	while True:
		while (numberOfViewers != numberOfSockets): # Wait until sockets are built
			time.sleep(1)

		q=Queue(concurrent*2)
		for i in range(concurrent):
			try:
				t=threading.Thread(target=view)
				t.daemon=True
				t.start()
			except:
				print('thread error')
		try:
			for url in urls:
				print(url)
				q.put(url.strip())
				q.join()
		except KeyboardInterrupt:
			sys.exit(1)

However, I appear to always get this error:

thread errorException in thread Thread-1:
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\lib\threading.py", line 916, in _bootstrap_inner
    self.run()
  File "C:\Program Files (x86)\Python36-32\lib\threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "bot.py", line 37, in build
    urls.append(getURL())
  File "bot.py", line 27, in getURL
    output = subprocess.Popen(["livestreamer", "twitch.tv/swagvyper", "-j"], stdout=subprocess.PIPE).communicate()[0]
  File "C:\Program Files (x86)\Python36-32\lib\subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "C:\Program Files (x86)\Python36-32\lib\subprocess.py", line 997, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified

Traceback (most recent call last):
  File "bot.py", line 66, in <module>
  File "C:\Program Files (x86)\Python36-32\lib\threading.py", line 846, in start
MemoryError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "bot.py", line 68, in <module>
MemoryError

When running python bot.py 1 1. Any ideas what I am missing here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment