diff --git a/CAM4Recorder.py b/CAM4Recorder.py new file mode 100644 index 0000000..b1ff904 --- /dev/null +++ b/CAM4Recorder.py @@ -0,0 +1,89 @@ +import urllib.request, json, time, datetime, os, threading, sys +from livestreamer import Livestreamer + + +#specify path to save to ie "/Users/Joe/cam4" +save_directory = "/Users/Joe/cam4" +#specify the path to the wishlist file ie "/Users/Joe/cam4/wanted.txt" +wishlist = "/Users/Joe/cam4/wanted.txt" +online = [] +if not os.path.exists("{path}".format(path=save_directory)): + os.makedirs("{path}".format(path=save_directory)) +recording = [] +UserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Mobile Safari/537.36" +offline = False + +def getOnlineModels(page): + sys.stdout.write("\033[K") + print("{} model(s) are being recorded. Checking for models to record (page {})".format(len(recording), page)) + sys.stdout.write("\033[K") + print("the following models are being recorded: {}".format(recording), end="\r") + result = urllib.request.urlopen("https://www.cam4.com/directoryCams?directoryJson=true&online=true&url=true&page={}".format(page)) + result = result.read() + results = json.loads(result.decode()) + return results + + +def startRecording(model): + req = urllib.request.Request('https://www.cam4.com/' + model) + req.add_header('UserAgent', UserAgent) + resp = urllib.request.urlopen(req) + resp = resp.read().decode().splitlines() + videoPlayUrl = "" + videoAppUrl = "" + for line in resp: + if "videoPlayUrl" in line: + for part in line.split("&"): + if "videoPlayUrl" in part and videoPlayUrl == "": + videoPlayUrl = part[13:] + elif "videoAppUrl" in part and videoAppUrl == "": + videoAppUrl = part.split("//")[1] + session = Livestreamer() + session.set_option('http-headers', "referer=https://www.cam4.com/{}".format(model)) + streams = session.streams("hlsvariant://https://{}/amlst:{}_aac/playlist.m3u8?referer=www.cam4.com×tamp={}\" best" + .format(videoAppUrl, videoPlayUrl, str(int(time.time() * 1000)))) + stream = streams["best"] + fd = stream.open() + ts = time.time() + st = datetime.datetime.fromtimestamp(ts).strftime("%Y.%m.%d_%H.%M.%S") + if not os.path.exists("{path}/{model}".format(path=save_directory, model=model)): + os.makedirs("{path}/{model}".format(path=save_directory, model=model)) + with open("{path}/{model}/{st}_{model}.mp4".format(path=save_directory, model=model, + st=st), 'wb') as f: + recording.append(model.lower()) + while True: + try: + data = fd.read(1024) + f.write(data) + except: + recording.remove(model) + + +if __name__ == '__main__': + while True: + wanted = [] + i = 1 + with open(wishlist) as f: + for model in f: + models = model.split() + for theModel in models: + wanted.append(theModel.lower()) + while not offline: + results = getOnlineModels(i) + if len(results['users']) >= 1: + for model in results['users']: + if model['username'].lower() in wanted and model['username'].lower() not in recording: + thread = threading.Thread(target=startRecording, args=(model['username'].lower(),)) + thread.start() + else: + offline = True + i = i + 1 + sys.stdout.write("\033[F") + offline = False + for i in range(20, 0, -1): + sys.stdout.write("\033[K") + print("{} model(s) are being recorded. Next check in {} seconds".format(len(recording), i)) + sys.stdout.write("\033[K") + print("the following models are being recorded: {}".format(recording), end="\r") + time.sleep(1) + sys.stdout.write("\033[F")