ソースを参照

Add support for downloading Instagram Replays

Cammy 7 年 前
コミット
e6925fe9f2
1 ファイル変更57 行追加17 行削除
  1. 57 17
      pyinstalive/downloader.py

+ 57 - 17
pyinstalive/downloader.py

@@ -1,12 +1,16 @@
 import sys
 import time
+import os
 
-from instagram_private_api_extensions import live
+from instagram_private_api_extensions import live, replay
 
 import logger
 
 
-class NoBroadcastException(Exception):
+class NoLivestreamException(Exception):
+	pass
+
+class NoReplayException(Exception):
 	pass
 
 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['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(
 			mpd=mpd_url,
@@ -45,7 +49,7 @@ def record_stream(broadcast):
 			mpd_download_timeout=10,
 			download_timeout=10)
 	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")
 		sys.exit(0)
 
@@ -55,7 +59,7 @@ def record_stream(broadcast):
 		started_label = '%d minutes and ' % started_mins
 		if 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.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))
@@ -63,19 +67,19 @@ def record_stream(broadcast):
 		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")
+		logger.log('[I] Recording livestream... press [CTRL+C] to abort.', "GREEN")
 		dl.run()
 		stitch_video(dl, broadcast)
 	except KeyboardInterrupt:
 		logger.log('', "GREEN")
-		logger.log('[I] Aborting broadcast recording...', "GREEN")
+		logger.log('[I] Aborting livestream 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)
+		output_file = save_path + '{}_{}_{}_{}_live.mp4'.format(current_date, record, broadcast['id'], current_time)
 		try:
 			dl.stitch(output_file, cleartempfiles=False)
 			logger.log('[I] Successfully stitched downloaded files!', "GREEN")
@@ -90,28 +94,64 @@ def get_user_info(record):
 	try:
 		user_res = api.username_info(record)
 		user_id = user_res['user']['pk']
-		get_broadcast(user_id)
+		get_livestreams(user_id)
 	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")
 		sys.exit(0)
+	get_replays(user_id)
 
-
-def get_broadcast(user_id):
+def get_livestreams(user_id):
 	try:
-		logger.log('[I] Checking broadcast for "' + record + '"...', "GREEN")
+		logger.log('[I] Checking livestreams for "' + record + '"...', "GREEN")
 		broadcast = api.user_broadcast(user_id)
 		if (broadcast is None):
-			raise NoBroadcastException('No broadcast available.')
+			raise NoLivestreamException('No livestreams available.')
 		else:
 			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.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")
+		if (e.__class__.__name__ is not NoReplayException):
+			logger.log('[E] Could not get replay info: ' + str(e), "RED")
 			logger.seperator("GREEN")
 			sys.exit(0)