downloader.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import sys
  2. import time
  3. import os
  4. from instagram_private_api_extensions import live, replay
  5. import logger
  6. class NoLivestreamException(Exception):
  7. pass
  8. class NoReplayException(Exception):
  9. pass
  10. def main(api_arg, record_arg, save_path_arg):
  11. global api
  12. global record
  13. global save_path
  14. global current_date
  15. global current_time
  16. global broadcast
  17. global mpd_url
  18. current_time = str(int(time.time()))
  19. current_date = time.strftime("%Y%m%d")
  20. api = api_arg
  21. record = record_arg
  22. save_path = save_path_arg
  23. get_user_info(record)
  24. def record_stream(broadcast):
  25. try:
  26. def check_status():
  27. print_status()
  28. mpd_url = (broadcast.get('dash_manifest')
  29. or broadcast.get('dash_abr_playback_url')
  30. or broadcast['dash_playback_url'])
  31. output_dir = save_path + '{}_{}_{}_{}_live_downloads'.format(current_date, record, broadcast['id'], current_time)
  32. dl = live.Downloader(
  33. mpd=mpd_url,
  34. output_dir=output_dir,
  35. user_agent=api.user_agent,
  36. max_connection_error_retry=2,
  37. duplicate_etag_retry=60,
  38. callback_check=check_status,
  39. mpd_download_timeout=10,
  40. download_timeout=10)
  41. except Exception as e:
  42. logger.log('[E] Could not start recording livestream: ' + str(e), "RED")
  43. logger.seperator("GREEN")
  44. sys.exit(0)
  45. try:
  46. viewers = broadcast.get('viewer_count', 0)
  47. started_mins, started_secs = divmod((int(time.time()) - broadcast['published_time']), 60)
  48. started_label = '%d minutes and ' % started_mins
  49. if started_secs:
  50. started_label += '%d seconds' % started_secs
  51. logger.log('[I] Starting livestream recording:', "GREEN")
  52. last_stream = open("last_stream.html", "w")
  53. last_stream.write('<b>Username:</b> {}<br><b>MPD URL:</b> <a href="{}">LINK</a><br><b>Viewers:</b> {}<br><b>Missing:</b> {}'
  54. .format(record, mpd_url, str(int(viewers)), started_label))
  55. last_stream.close()
  56. logger.log('[I] Username : ' + record, "GREEN")
  57. logger.log('[I] MPD URL : ' + mpd_url, "GREEN")
  58. print_status(api, broadcast)
  59. logger.log('[I] Recording livestream... press [CTRL+C] to abort.', "GREEN")
  60. dl.run()
  61. stitch_video(dl, broadcast)
  62. except KeyboardInterrupt:
  63. logger.log('', "GREEN")
  64. logger.log('[I] Aborting livestream recording...', "GREEN")
  65. if not dl.is_aborted:
  66. dl.stop()
  67. stitch_video(dl, broadcast)
  68. def stitch_video(dl, broadcast):
  69. logger.log('[I] Stitching downloaded files into video...', "GREEN")
  70. output_file = save_path + '{}_{}_{}_{}_live.mp4'.format(current_date, record, broadcast['id'], current_time)
  71. try:
  72. dl.stitch(output_file, cleartempfiles=False)
  73. logger.log('[I] Successfully stitched downloaded files!', "GREEN")
  74. logger.seperator("GREEN")
  75. sys.exit(0)
  76. except Exception as e:
  77. logger.log('[E] Could not stitch downloaded files: ' + str(e), "RED")
  78. logger.seperator("GREEN")
  79. sys.exit(0)
  80. def get_user_info(record):
  81. try:
  82. user_res = api.username_info(record)
  83. user_id = user_res['user']['pk']
  84. get_livestreams(user_id)
  85. except Exception as e:
  86. logger.log('[E] Could not get livestream info for "' + record + '" : ' + str(e), "RED")
  87. logger.seperator("GREEN")
  88. sys.exit(0)
  89. get_replays(user_id)
  90. def get_livestreams(user_id):
  91. try:
  92. logger.log('[I] Checking livestreams for "' + record + '"...', "GREEN")
  93. broadcast = api.user_broadcast(user_id)
  94. if (broadcast is None):
  95. raise NoLivestreamException('No livestreams available.')
  96. else:
  97. record_stream(broadcast)
  98. except NoLivestreamException as e:
  99. logger.log('[W] ' + str(e), "YELLOW")
  100. except Exception as e:
  101. if (e.__class__.__name__ is not NoLivestreamException):
  102. logger.log('[E] Could not get livestreams info: ' + str(e), "RED")
  103. logger.seperator("GREEN")
  104. sys.exit(0)
  105. def get_replays(user_id):
  106. try:
  107. user_story_feed = api.user_story_feed(user_id)
  108. broadcasts = user_story_feed.get('post_live_item', {}).get('broadcasts', [])
  109. if (len(broadcasts) == 0):
  110. raise NoReplayException('No replays available.')
  111. else:
  112. for index, broadcast in enumerate(broadcasts):
  113. exists = False
  114. for directory in filter(os.path.isdir, os.listdir(os.getcwd())):
  115. if (str(broadcast['id']) in directory) and ("_live_" not in directory):
  116. logger.log("[W] Already downloaded a replay with ID '" + str(broadcast['id']) + "', skipping...", "GREEN")
  117. exists = True
  118. return
  119. if exists is False:
  120. current = index + 1
  121. logger.log("[I] Starting replay download " + str(current) + " of " + str(len(broadcasts)) + "...", "GREEN")
  122. current_time = str(int(time.time()))
  123. output_dir = save_path + '{}_{}_{}_{}_replay_downloads'.format(current_date, record, broadcast['id'], current_time)
  124. dl = replay.Downloader(
  125. mpd=broadcast['dash_manifest'],
  126. output_dir=output_dir,
  127. user_agent=api.user_agent)
  128. dl.download(save_path + '{}_{}_{}_{}_replay.mp4'.format(current_date, record, broadcast['id'], current_time))
  129. logger.log("[I] Finished downloading available replays.", "GREEN")
  130. logger.seperator("GREEN")
  131. sys.exit(0)
  132. except NoReplayException as e:
  133. logger.log('[W] ' + str(e), "YELLOW")
  134. logger.seperator("GREEN")
  135. sys.exit(0)
  136. except Exception as e:
  137. if (e.__class__.__name__ is not NoReplayException):
  138. logger.log('[E] Could not get replay info: ' + str(e), "RED")
  139. logger.seperator("GREEN")
  140. sys.exit(0)
  141. def print_status(api, broadcast):
  142. heartbeat_info = api.broadcast_heartbeat_and_viewercount(broadcast['id'])
  143. viewers = broadcast.get('viewer_count', 0)
  144. started_mins, started_secs = divmod((int(time.time()) - broadcast['published_time']), 60)
  145. started_label = '%d minutes and ' % started_mins
  146. if started_secs:
  147. started_label += '%d seconds' % started_secs
  148. logger.log('[I] Viewers : ' + str(int(viewers)) + " watching", "GREEN")
  149. logger.log('[I] Airing time : ' + started_label, "GREEN")
  150. logger.log('[I] Status : ' + heartbeat_info['broadcast_status'].title(), "GREEN")
  151. logger.log('', "GREEN")