import codecs
import logging
import sys, time
from socket import timeout
from instagram_private_api_extensions import live
import logger
class NoBroadcastException(Exception):
pass
def main(api_arg, record_arg, save_path_arg):
global api
global record
global save_path
global current_date
global current_time
global broadcast
global mpd_url
current_time = str(int(time.time()))
current_date = time.strftime("%Y%m%d")
api = api_arg
record = record_arg
save_path = save_path_arg
get_user_info(record)
def record_stream(broadcast):
try:
def check_status():
print_status()
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 = save_path + '{}_{}_{}_{}_downloads'.format(current_date, record, broadcast['id'], current_time)
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:
logger.log('[E] Could not start recording broadcast: ' + str(e), "RED")
logger.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
logger.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()
logger.log('[I] Username : ' + record, "GREEN")
logger.log('[I] MPD URL : ' + mpd_url, "GREEN")
print_status(api, broadcast)
logger.log('[I] Recording broadcast... press [CTRL+C] to abort.', "GREEN")
dl.run()
stitch_video(dl, broadcast)
except KeyboardInterrupt:
logger.log('', "GREEN")
logger.log('[I] Aborting broadcast recording...', "GREEN")
if not dl.is_aborted:
dl.stop()
stitch_video(dl, broadcast)
def stitch_video(dl, broadcast):
logger.log('[I] Stitching downloaded files into video...', "GREEN")
output_file = save_path + '{}_{}_{}_{}.mp4'.format(current_date, record, broadcast['id'], current_time)
try:
dl.stitch(output_file, cleartempfiles=False)
logger.log('[I] Successfully stitched downloaded files!', "GREEN")
logger.seperator("GREEN")
sys.exit(0)
except Exception as e:
logger.log('[E] Could not stitch downloaded files: ' + str(e), "RED")
logger.seperator("GREEN")
sys.exit(0)
def get_user_info(record):
try:
user_res = api.username_info(record)
user_id = user_res['user']['pk']
get_broadcast(user_id)
except Exception as e:
logger.log('[E] Could not get user info for "' + record + '" : ' + str(e), "RED")
logger.seperator("GREEN")
sys.exit(0)
def get_broadcast(user_id):
try:
logger.log('[I] Checking broadcast for "' + record + '"...', "GREEN")
broadcast = api.user_broadcast(user_id)
if (broadcast is None):
raise NoBroadcastException('No broadcast available.')
else:
record_stream(broadcast)
except NoBroadcastException as e:
logger.log('[W] ' + str(e), "YELLOW")
logger.seperator("GREEN")
sys.exit(0)
except Exception as e:
if (e.__name__ is not NoBroadcastException):
logger.log('[E] Could not get broadcast info: ' + str(e), "RED")
logger.seperator("GREEN")
sys.exit(0)
def print_status(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
logger.log('[I] Viewers : ' + str(int(viewers)) + " watching", "GREEN")
logger.log('[I] Airing time : ' + started_label, "GREEN")
logger.log('[I] Status : ' + heartbeat_info['broadcast_status'].title(), "GREEN")
logger.log('', "GREEN")