downloader.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import sys
  2. import time
  3. from instagram_private_api_extensions import live
  4. import logger
  5. class NoBroadcastException(Exception):
  6. pass
  7. def main(api_arg, record_arg, save_path_arg):
  8. global api
  9. global record
  10. global save_path
  11. global current_date
  12. global current_time
  13. global broadcast
  14. global mpd_url
  15. current_time = str(int(time.time()))
  16. current_date = time.strftime("%Y%m%d")
  17. api = api_arg
  18. record = record_arg
  19. save_path = save_path_arg
  20. get_user_info(record)
  21. def record_stream(broadcast):
  22. try:
  23. def check_status():
  24. print_status()
  25. mpd_url = (broadcast.get('dash_manifest')
  26. or broadcast.get('dash_abr_playback_url')
  27. or broadcast['dash_playback_url'])
  28. output_dir = save_path + '{}_{}_{}_{}_downloads'.format(current_date, record, broadcast['id'], current_time)
  29. dl = live.Downloader(
  30. mpd=mpd_url,
  31. output_dir=output_dir,
  32. user_agent=api.user_agent,
  33. max_connection_error_retry=2,
  34. duplicate_etag_retry=60,
  35. callback_check=check_status,
  36. mpd_download_timeout=10,
  37. download_timeout=10)
  38. except Exception as e:
  39. logger.log('[E] Could not start recording broadcast: ' + str(e), "RED")
  40. logger.seperator("GREEN")
  41. sys.exit(0)
  42. try:
  43. viewers = broadcast.get('viewer_count', 0)
  44. started_mins, started_secs = divmod((int(time.time()) - broadcast['published_time']), 60)
  45. started_label = '%d minutes and ' % started_mins
  46. if started_secs:
  47. started_label += '%d seconds' % started_secs
  48. logger.log('[I] Starting broadcast recording:', "GREEN")
  49. last_stream = open("last_stream.html", "w")
  50. last_stream.write('<b>Username:</b> {}<br><b>MPD URL:</b> <a href="{}">LINK</a><br><b>Viewers:</b> {}<br><b>Missing:</b> {}'
  51. .format(record, mpd_url, str(int(viewers)), started_label))
  52. last_stream.close()
  53. logger.log('[I] Username : ' + record, "GREEN")
  54. logger.log('[I] MPD URL : ' + mpd_url, "GREEN")
  55. print_status(api, broadcast)
  56. logger.log('[I] Recording broadcast... press [CTRL+C] to abort.', "GREEN")
  57. dl.run()
  58. stitch_video(dl, broadcast)
  59. except KeyboardInterrupt:
  60. logger.log('', "GREEN")
  61. logger.log('[I] Aborting broadcast recording...', "GREEN")
  62. if not dl.is_aborted:
  63. dl.stop()
  64. stitch_video(dl, broadcast)
  65. def stitch_video(dl, broadcast):
  66. logger.log('[I] Stitching downloaded files into video...', "GREEN")
  67. output_file = save_path + '{}_{}_{}_{}.mp4'.format(current_date, record, broadcast['id'], current_time)
  68. try:
  69. dl.stitch(output_file, cleartempfiles=False)
  70. logger.log('[I] Successfully stitched downloaded files!', "GREEN")
  71. logger.seperator("GREEN")
  72. sys.exit(0)
  73. except Exception as e:
  74. logger.log('[E] Could not stitch downloaded files: ' + str(e), "RED")
  75. logger.seperator("GREEN")
  76. sys.exit(0)
  77. def get_user_info(record):
  78. try:
  79. user_res = api.username_info(record)
  80. user_id = user_res['user']['pk']
  81. get_broadcast(user_id)
  82. except Exception as e:
  83. logger.log('[E] Could not get user info for "' + record + '" : ' + str(e), "RED")
  84. logger.seperator("GREEN")
  85. sys.exit(0)
  86. def get_broadcast(user_id):
  87. try:
  88. logger.log('[I] Checking broadcast for "' + record + '"...', "GREEN")
  89. broadcast = api.user_broadcast(user_id)
  90. if (broadcast is None):
  91. raise NoBroadcastException('No broadcast available.')
  92. else:
  93. record_stream(broadcast)
  94. except NoBroadcastException as e:
  95. logger.log('[W] ' + str(e), "YELLOW")
  96. logger.seperator("GREEN")
  97. sys.exit(0)
  98. except Exception as e:
  99. if (e.__name__ is not NoBroadcastException):
  100. logger.log('[E] Could not get broadcast info: ' + str(e), "RED")
  101. logger.seperator("GREEN")
  102. sys.exit(0)
  103. def print_status(api, broadcast):
  104. heartbeat_info = api.broadcast_heartbeat_and_viewercount(broadcast['id'])
  105. viewers = broadcast.get('viewer_count', 0)
  106. started_mins, started_secs = divmod((int(time.time()) - broadcast['published_time']), 60)
  107. started_label = '%d minutes and ' % started_mins
  108. if started_secs:
  109. started_label += '%d seconds' % started_secs
  110. logger.log('[I] Viewers : ' + str(int(viewers)) + " watching", "GREEN")
  111. logger.log('[I] Airing time : ' + started_label, "GREEN")
  112. logger.log('[I] Status : ' + heartbeat_info['broadcast_status'].title(), "GREEN")
  113. logger.log('', "GREEN")