import argparse import codecs import datetime import json import logging import os.path import threading from socket import error as SocketError from socket import timeout from ssl import SSLError from urllib2 import URLError import cLogger, cComments import sys, os, time from httplib import HTTPException from instagram_private_api_extensions import live class NoBroadcastException(Exception): pass def main(apiArg, recordArg): global api global record global isRecording global currentDate global currentTime global broadcast global mpd_url currentTime = str(int(time.time())) currentDate = time.strftime("%Y%m%d") isRecording = False api = apiArg record = recordArg getUserInfo(record) def recordStream(broadcast): try: def check_status(): printStatus() return heartbeat_info['broadcast_status'] not in ['active', 'interrupted'] mpd_url = (broadcast.get('dash_manifest') or broadcast.get('dash_abr_playback_url') or broadcast['dash_playback_url']) outputDir = '{}_{}_{}_{}_downloads/'.format(currentDate ,record, broadcast['id'], currentTime) dl = live.Downloader( mpd=mpd_url, output_dir=outputDir, user_agent=api.user_agent, max_connection_error_retry=2, duplicate_etag_retry=60, callback_check=check_status, mpd_download_timeout=10, download_timeout=10) except Exception as e: cLogger.log('[E] Could not start recording broadcast: ' + str(e), "RED") cLogger.seperator("GREEN") sys.exit(0) try: viewers = broadcast.get('viewer_count', 0) started_mins, started_secs = divmod((int(time.time()) - broadcast['published_time']), 60) started_label = '%d minutes and ' % started_mins if started_secs: started_label += '%d seconds' % started_secs cLogger.log('[I] Starting broadcast recording:', "GREEN") last_stream = open("last_stream.html", "w") last_stream.write('Username: {}
MPD URL: LINK
Viewers: {}
Missing: {}' .format(record, mpd_url, str(int(viewers)), started_label)) last_stream.close() cLogger.log('[I] Username : ' + record, "GREEN") cLogger.log('[I] MPD URL : ' + mpd_url, "GREEN") printStatus(api, broadcast) cLogger.log('[I] Recording broadcast...', "GREEN") dl.run() stitchVideo(dl, broadcast) except KeyboardInterrupt: cLogger.log('', "GREEN") cLogger.log('[I] Aborting broadcast recording...', "GREEN") if not dl.is_aborted: dl.stop() stitchVideo(dl, broadcast) def stitchVideo(dl, broadcast): isRecording = False cLogger.log('[I] Stitching downloaded files into video...', "GREEN") output_file = '{}_{}_{}_{}.mp4'.format(currentDate ,record, broadcast['id'], currentTime) dl.stitch(output_file, cleartempfiles=False) cLogger.log('[I] Successfully stitched downloaded files!', "GREEN") cLogger.seperator("GREEN") sys.exit(0) def getUserInfo(record): try: user_res = api.username_info(record) user_id = user_res['user']['pk'] getBroadcast(user_id) except Exception as e: cLogger.log('[E] Could not get user info: ' + str(e), "RED") cLogger.seperator("GREEN") sys.exit(0) def getBroadcast(user_id): try: cLogger.log('[I] Checking broadcast for "' + record + '"...', "GREEN") broadcast = api.user_broadcast(user_id) if (broadcast is None): raise NoBroadcastException('No broadcast available.') else: recordStream(broadcast) except NoBroadcastException as e: cLogger.log('[W] ' + str(e), "YELLOW") cLogger.seperator("GREEN") sys.exit(0) except Exception as e: if (e.__name__ is not NoBroadcastException): cLogger.log('[E] Could not get broadcast info: ' + str(e), "RED") cLogger.seperator("GREEN") sys.exit(0) def printStatus(api, broadcast): heartbeat_info = api.broadcast_heartbeat_and_viewercount(broadcast['id']) viewers = broadcast.get('viewer_count', 0) started_mins, started_secs = divmod((int(time.time()) - broadcast['published_time']), 60) started_label = '%d minutes and ' % started_mins if started_secs: started_label += '%d seconds' % started_secs cLogger.log('[I] Viewers : ' + str(int(viewers)) + " watching", "GREEN") cLogger.log('[I] Airing time : ' + started_label, "GREEN") cLogger.log('[I] Status : ' + heartbeat_info['broadcast_status'].title(), "GREEN") cLogger.log('', "GREEN")