|
@@ -1,12 +1,16 @@
|
|
import sys
|
|
import sys
|
|
import time
|
|
import time
|
|
|
|
+import os
|
|
|
|
|
|
-from instagram_private_api_extensions import live
|
|
|
|
|
|
+from instagram_private_api_extensions import live, replay
|
|
|
|
|
|
import logger
|
|
import logger
|
|
|
|
|
|
|
|
|
|
-class NoBroadcastException(Exception):
|
|
|
|
|
|
+class NoLivestreamException(Exception):
|
|
|
|
+ pass
|
|
|
|
+
|
|
|
|
+class NoReplayException(Exception):
|
|
pass
|
|
pass
|
|
|
|
|
|
def main(api_arg, record_arg, save_path_arg):
|
|
def main(api_arg, record_arg, save_path_arg):
|
|
@@ -33,7 +37,7 @@ def record_stream(broadcast):
|
|
or broadcast.get('dash_abr_playback_url')
|
|
or broadcast.get('dash_abr_playback_url')
|
|
or broadcast['dash_playback_url'])
|
|
or broadcast['dash_playback_url'])
|
|
|
|
|
|
- output_dir = save_path + '{}_{}_{}_{}_downloads'.format(current_date, record, broadcast['id'], current_time)
|
|
|
|
|
|
+ output_dir = save_path + '{}_{}_{}_{}_live_downloads'.format(current_date, record, broadcast['id'], current_time)
|
|
|
|
|
|
dl = live.Downloader(
|
|
dl = live.Downloader(
|
|
mpd=mpd_url,
|
|
mpd=mpd_url,
|
|
@@ -45,7 +49,7 @@ def record_stream(broadcast):
|
|
mpd_download_timeout=10,
|
|
mpd_download_timeout=10,
|
|
download_timeout=10)
|
|
download_timeout=10)
|
|
except Exception as e:
|
|
except Exception as e:
|
|
- logger.log('[E] Could not start recording broadcast: ' + str(e), "RED")
|
|
|
|
|
|
+ logger.log('[E] Could not start recording livestream: ' + str(e), "RED")
|
|
logger.seperator("GREEN")
|
|
logger.seperator("GREEN")
|
|
sys.exit(0)
|
|
sys.exit(0)
|
|
|
|
|
|
@@ -55,7 +59,7 @@ def record_stream(broadcast):
|
|
started_label = '%d minutes and ' % started_mins
|
|
started_label = '%d minutes and ' % started_mins
|
|
if started_secs:
|
|
if started_secs:
|
|
started_label += '%d seconds' % started_secs
|
|
started_label += '%d seconds' % started_secs
|
|
- logger.log('[I] Starting broadcast recording:', "GREEN")
|
|
|
|
|
|
+ logger.log('[I] Starting livestream recording:', "GREEN")
|
|
last_stream = open("last_stream.html", "w")
|
|
last_stream = open("last_stream.html", "w")
|
|
last_stream.write('<b>Username:</b> {}<br><b>MPD URL:</b> <a href="{}">LINK</a><br><b>Viewers:</b> {}<br><b>Missing:</b> {}'
|
|
last_stream.write('<b>Username:</b> {}<br><b>MPD URL:</b> <a href="{}">LINK</a><br><b>Viewers:</b> {}<br><b>Missing:</b> {}'
|
|
.format(record, mpd_url, str(int(viewers)), started_label))
|
|
.format(record, mpd_url, str(int(viewers)), started_label))
|
|
@@ -63,19 +67,19 @@ def record_stream(broadcast):
|
|
logger.log('[I] Username : ' + record, "GREEN")
|
|
logger.log('[I] Username : ' + record, "GREEN")
|
|
logger.log('[I] MPD URL : ' + mpd_url, "GREEN")
|
|
logger.log('[I] MPD URL : ' + mpd_url, "GREEN")
|
|
print_status(api, broadcast)
|
|
print_status(api, broadcast)
|
|
- logger.log('[I] Recording broadcast... press [CTRL+C] to abort.', "GREEN")
|
|
|
|
|
|
+ logger.log('[I] Recording livestream... press [CTRL+C] to abort.', "GREEN")
|
|
dl.run()
|
|
dl.run()
|
|
stitch_video(dl, broadcast)
|
|
stitch_video(dl, broadcast)
|
|
except KeyboardInterrupt:
|
|
except KeyboardInterrupt:
|
|
logger.log('', "GREEN")
|
|
logger.log('', "GREEN")
|
|
- logger.log('[I] Aborting broadcast recording...', "GREEN")
|
|
|
|
|
|
+ logger.log('[I] Aborting livestream recording...', "GREEN")
|
|
if not dl.is_aborted:
|
|
if not dl.is_aborted:
|
|
dl.stop()
|
|
dl.stop()
|
|
stitch_video(dl, broadcast)
|
|
stitch_video(dl, broadcast)
|
|
|
|
|
|
def stitch_video(dl, broadcast):
|
|
def stitch_video(dl, broadcast):
|
|
logger.log('[I] Stitching downloaded files into video...', "GREEN")
|
|
logger.log('[I] Stitching downloaded files into video...', "GREEN")
|
|
- output_file = save_path + '{}_{}_{}_{}.mp4'.format(current_date, record, broadcast['id'], current_time)
|
|
|
|
|
|
+ output_file = save_path + '{}_{}_{}_{}_live.mp4'.format(current_date, record, broadcast['id'], current_time)
|
|
try:
|
|
try:
|
|
dl.stitch(output_file, cleartempfiles=False)
|
|
dl.stitch(output_file, cleartempfiles=False)
|
|
logger.log('[I] Successfully stitched downloaded files!', "GREEN")
|
|
logger.log('[I] Successfully stitched downloaded files!', "GREEN")
|
|
@@ -90,28 +94,64 @@ def get_user_info(record):
|
|
try:
|
|
try:
|
|
user_res = api.username_info(record)
|
|
user_res = api.username_info(record)
|
|
user_id = user_res['user']['pk']
|
|
user_id = user_res['user']['pk']
|
|
- get_broadcast(user_id)
|
|
|
|
|
|
+ get_livestreams(user_id)
|
|
except Exception as e:
|
|
except Exception as e:
|
|
- logger.log('[E] Could not get user info for "' + record + '" : ' + str(e), "RED")
|
|
|
|
|
|
+ logger.log('[E] Could not get livestream info for "' + record + '" : ' + str(e), "RED")
|
|
logger.seperator("GREEN")
|
|
logger.seperator("GREEN")
|
|
sys.exit(0)
|
|
sys.exit(0)
|
|
|
|
+ get_replays(user_id)
|
|
|
|
|
|
-
|
|
|
|
-def get_broadcast(user_id):
|
|
|
|
|
|
+def get_livestreams(user_id):
|
|
try:
|
|
try:
|
|
- logger.log('[I] Checking broadcast for "' + record + '"...', "GREEN")
|
|
|
|
|
|
+ logger.log('[I] Checking livestreams for "' + record + '"...', "GREEN")
|
|
broadcast = api.user_broadcast(user_id)
|
|
broadcast = api.user_broadcast(user_id)
|
|
if (broadcast is None):
|
|
if (broadcast is None):
|
|
- raise NoBroadcastException('No broadcast available.')
|
|
|
|
|
|
+ raise NoLivestreamException('No livestreams available.')
|
|
else:
|
|
else:
|
|
record_stream(broadcast)
|
|
record_stream(broadcast)
|
|
- except NoBroadcastException as e:
|
|
|
|
|
|
+ except NoLivestreamException as e:
|
|
|
|
+ logger.log('[W] ' + str(e), "YELLOW")
|
|
|
|
+ except Exception as e:
|
|
|
|
+ if (e.__class__.__name__ is not NoLivestreamException):
|
|
|
|
+ logger.log('[E] Could not get livestreams info: ' + str(e), "RED")
|
|
|
|
+ logger.seperator("GREEN")
|
|
|
|
+ sys.exit(0)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def get_replays(user_id):
|
|
|
|
+ try:
|
|
|
|
+ user_story_feed = api.user_story_feed(user_id)
|
|
|
|
+ broadcasts = user_story_feed.get('post_live_item', {}).get('broadcasts', [])
|
|
|
|
+ if (len(broadcasts) == 0):
|
|
|
|
+ raise NoReplayException('No replays available.')
|
|
|
|
+ else:
|
|
|
|
+ for index, broadcast in enumerate(broadcasts):
|
|
|
|
+ exists = False
|
|
|
|
+ for directory in filter(os.path.isdir, os.listdir(os.getcwd())):
|
|
|
|
+ if (str(broadcast['id']) in directory) and ("_live_" not in directory):
|
|
|
|
+ logger.log("[W] Already downloaded a replay with ID '" + str(broadcast['id']) + "', skipping...", "GREEN")
|
|
|
|
+ exists = True
|
|
|
|
+ return
|
|
|
|
+ if exists is False:
|
|
|
|
+ current = index + 1
|
|
|
|
+ logger.log("[I] Starting replay download " + str(current) + " of " + str(len(broadcasts)) + "...", "GREEN")
|
|
|
|
+ current_time = str(int(time.time()))
|
|
|
|
+ output_dir = save_path + '{}_{}_{}_{}_replay_downloads'.format(current_date, record, broadcast['id'], current_time)
|
|
|
|
+ dl = replay.Downloader(
|
|
|
|
+ mpd=broadcast['dash_manifest'],
|
|
|
|
+ output_dir=output_dir,
|
|
|
|
+ user_agent=api.user_agent)
|
|
|
|
+ dl.download(save_path + '{}_{}_{}_{}_replay.mp4'.format(current_date, record, broadcast['id'], current_time))
|
|
|
|
+ logger.log("[I] Finished downloading available replays.", "GREEN")
|
|
|
|
+ logger.seperator("GREEN")
|
|
|
|
+ sys.exit(0)
|
|
|
|
+ except NoReplayException as e:
|
|
logger.log('[W] ' + str(e), "YELLOW")
|
|
logger.log('[W] ' + str(e), "YELLOW")
|
|
logger.seperator("GREEN")
|
|
logger.seperator("GREEN")
|
|
sys.exit(0)
|
|
sys.exit(0)
|
|
except Exception as e:
|
|
except Exception as e:
|
|
- if (e.__name__ is not NoBroadcastException):
|
|
|
|
- logger.log('[E] Could not get broadcast info: ' + str(e), "RED")
|
|
|
|
|
|
+ if (e.__class__.__name__ is not NoReplayException):
|
|
|
|
+ logger.log('[E] Could not get replay info: ' + str(e), "RED")
|
|
logger.seperator("GREEN")
|
|
logger.seperator("GREEN")
|
|
sys.exit(0)
|
|
sys.exit(0)
|
|
|
|
|