vid_utils.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import re
  2. import os
  3. from glob import glob, escape
  4. from subprocess import Popen, PIPE
  5. from time import strftime, strptime, sleep
  6. from contextlib import contextmanager
  7. from telegram import InlineKeyboardButton
  8. # many of these imports serve the commented code...
  9. class Video:
  10. def __init__(self, link, chat_id):
  11. self.link = link
  12. self.chat_id = chat_id
  13. self.formats = self.get_formats()
  14. self.keyboard = self.generate_keyboard()
  15. self.file_name = None
  16. def get_formats(self, link=None):
  17. formats = []
  18. cmd = "youtube-dl -F {}".format(self.link)
  19. p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
  20. it = iter(str(p[0], 'utf-8').split('\n')) # iterator of output lines
  21. while "code extension" not in next(it): pass # Remove garbage lines
  22. while True:
  23. try:
  24. line = next(it)
  25. if not line:
  26. raise StopIteration # Usually the last line is empty
  27. if "video only" in line:
  28. continue # I don't need video without audio
  29. except StopIteration:
  30. break
  31. else:
  32. format_code, extension, resolution, *_ = line.strip().split()
  33. formats.append([format_code, extension, resolution])
  34. return formats
  35. def generate_keyboard(self):
  36. """ Generate a list of InlineKeyboardButton of resolutions """
  37. kb = []
  38. for code, extension, resolution in self.formats:
  39. kb.append([InlineKeyboardButton("{0}, {1}".format(extension, resolution),
  40. callback_data=code)])
  41. return kb
  42. def download(self, resolution_code):
  43. cmd = "youtube-dl -f {0} {1}".format(resolution_code, self.link)
  44. p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
  45. for line in str(p[0], 'utf-8').split('\n'):
  46. if "[download] Destination:" in line:
  47. self.file_name = line[24:] # name of the file
  48. def check_dimension(self):
  49. if os.path.getsize(self.file_name) > 50 * 1024 * 1023:
  50. os.system('split -b 49M "{0}" "{1}"'.format(self.file_name, self.file_name))
  51. os.remove(self.file_name)
  52. return glob(escape(self.file_name) + '*')
  53. @contextmanager
  54. def send(self):
  55. files = self.check_dimension() # split if size >= 50MB
  56. yield files
  57. for f in files: #removing old files
  58. os.remove(f)
  59. #__________________________OLD STUFFS, TOUCH CAREFULLY__________________________
  60. # this is the soft-split version, require avconv, but the audio isn't synchronized, avconv's problems :(
  61. '''
  62. def get_duration(filepath): # get duration in seconds
  63. cmd = "avconv -i %s" % filepath
  64. p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
  65. di = p.communicate()
  66. for line in di:
  67. if line.rfind(b"Duration") > 0:
  68. duration = str(re.findall(b"Duration: (\d+:\d+:[\d.]+)", line)[0])
  69. return 3600 * int(duration[2: 4]) + 60 * int(duration[5: 7]) + int(duration[8: 10])
  70. def check_dimension(f): # if f is bigger than 50MB split it in subvideos
  71. if os.path.getsize(f) > 50 * 1024 * 1023:
  72. duration = get_duration(f)
  73. for i in range(0, duration, 180):
  74. start = strftime("%H:%M:%S", strptime('{0} {1} {2}'.format(i // 3600, (i // 60) % 60, i % 60), "%H %M %S")) # TODO this is not pythonic code!
  75. os.system("""avconv -i '{0}' -vcodec copy -acodec copy -ss {1} -t {2} 'part_{3}.mp4'""".format(f, start, 180, (i // 180) % 180))
  76. os.remove(f) # delete original file
  77. '''