downloader.py 4.1 KB

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