cDownloader.py 3.3 KB

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