Posted By

pantuts on 10/18/12


Tagged

download YouTube videos tubeNick


Versions (?)

tubeNick - Download youtube videos


 / Published in: Python
 

URL: https://sourceforge.net/projects/tubenickdownloa/

Tool to download youtube videos with STDIN (PIPE) support for playlist parsers like umph or youParse

(PYTHON3+)

  1. #!/usr/bin/python3
  2.  
  3. # Name: tubeNick.py
  4. # Version: 1.5
  5. # Author: pantuts
  6. # Email: [email protected]
  7. # Description: Download videos from youtube.
  8. # Use python3 and later.
  9. # Agreement: You can use, modify, or redistribute this tool under
  10. # the terms of GNU General Public License (GPLv3). This tool is for educational purposes only.
  11. # Any damage you make will not affect the author.
  12. # Send bugs to above email.
  13. # Usage: python3 tubeNick.py youtubeURLhere
  14. # Download: https://sourceforge.net/projects/tubenickdownloa/
  15.  
  16. import re
  17. import urllib.request
  18. import urllib.error
  19. import sys
  20. import time
  21.  
  22. COLON = '%253A'
  23. BACKSLASH = '%252F'
  24. QMARK = '%253F'
  25. EQUALS = '%253D'
  26. AMPERSAND = '%2526'
  27. PERCENT = '%2525'
  28.  
  29. MATCHED_LINK = []
  30. SIGNATURE = []
  31. COMPLETE_LINK = []
  32. VIDEO_TYPE = []
  33. VIDEO_RES = []
  34. FINAL_LINK = []
  35.  
  36. sTUBE = ''
  37. final_title = ''
  38. final_url = ''
  39. url = ''
  40. final_f_format = 0
  41. arg_queryf = ''
  42. arg_format = ''
  43. arg_f_format = []
  44.  
  45. ########################################################################
  46.  
  47. def main():
  48.  
  49. global url
  50. global arg_format
  51. global arg_queryf
  52.  
  53. if len(sys.argv) < 2 or len(sys.argv) > 4: return usage()
  54. elif len(sys.argv) == 2:
  55. if sys.argv[-1] == '-h': return usage()
  56. else:
  57. if sys.argv[-1] == '-': url = list(sys.stdin.readlines())
  58. else: url = sys.argv[-1]
  59. elif len(sys.argv) == 3:
  60. for args in sys.argv:
  61. if '-h' in args or '-f' in args: print('\nCommand ERROR...'); exit(1)
  62. if sys.argv[1] == '-q': sys.argv[1] = '-q'; arg_queryf = sys.argv[1]
  63. else: return usage()
  64. if sys.argv[-1] == '-': url = list(sys.stdin.readlines())
  65. else: url = sys.argv[-1]
  66. elif len(sys.argv) == 4:
  67. for args in sys.argv:
  68. if '-h' in args or '-q' in args: print('\nCommand ERROR...'); exit(1)
  69. if sys.argv[1] == '-f': sys.argv[1] = '-f';
  70. else: return usage()
  71. arg_format = sys.argv[2]
  72. if sys.argv[-1] == '-': url = list(sys.stdin.readlines())
  73. else: url = sys.argv[-1]
  74. else: return usage()
  75.  
  76. if sys.argv[-1] == '-':
  77.  
  78. i = 0
  79. while i < len(url):
  80. check_url(url[i].split('\\')[0])
  81. i = i + 1
  82. else:
  83. check_url(url)
  84.  
  85. ########################################################################
  86.  
  87. def usage():
  88.  
  89. print('\nUSAGE: python3 tubeNick.py -q [-f format] [URL or [-] STDIN]')
  90. print('Optional arguments:')
  91. print('\t-q \t\tQuery video formats. Use of -f will be invalid.')
  92. print('\t-f format\tSupply queried format. Highest video if blank.')
  93. print('\t-h \t\tPrint this.')
  94. print()
  95.  
  96. ########################################################################
  97.  
  98. def check_url(url):
  99.  
  100. global final_url
  101.  
  102. tmp_url = 'http://www.youtube.com/get_video_info?video_id='
  103. invalid = '~`!@#$%^&*()_=+{[}]|\\:;"\'<,>.?/'
  104. tmp_id = ''
  105. final_id = ''
  106. eq = 0
  107. last_id = 0
  108.  
  109. split_url = url.split('/')
  110. tmp_id = split_url[-1]
  111.  
  112. if 'v' not in url: print('[-] URLError: Invalid link.'); exit(1)
  113. if len(url) < 20: print('[-] URLError: Invalid link.'); exit(1)
  114. if 'youtube.com' not in url and url != '-': print('[-] URLError: Youtube URLs only.'); exit(1)
  115.  
  116. if 'watch?v=' in tmp_id:
  117. eq = tmp_id.index('=') + 1
  118. if '&' in tmp_id:
  119. tmp_split = tmp_id.split('&')[0]
  120. final_id = tmp_split[eq:]
  121. else: final_id = tmp_id[eq:]
  122.  
  123. # the video id for requesting get_video_info
  124. final_url = tmp_url + final_id
  125.  
  126. if final_url:
  127. con = 'Connecting...\n'
  128. i = 0
  129. while i < len(con):
  130. sys.stdout.write(con[i])
  131. sys.stdout.flush()
  132. time.sleep(0.01)
  133. i = i + 1
  134.  
  135. connection(final_url)
  136.  
  137. ########################################################################
  138.  
  139. def connection(final_url):
  140.  
  141. global sTUBE
  142.  
  143. try:
  144. req = urllib.request.Request(final_url)
  145. req.add_header('User-Agent', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0')
  146. yTUBE = urllib.request.urlopen(req)
  147. sTUBE = str(yTUBE.read())
  148.  
  149. except urllib.request.URLerror as e: print(e.reason); exit(1)
  150.  
  151. if sTUBE:
  152. rep_page(sTUBE)
  153.  
  154. ########################################################################
  155.  
  156. def rep_page(sTUBE):
  157.  
  158. REP_STR = [COLON, BACKSLASH, QMARK, EQUALS, AMPERSAND, PERCENT]
  159. if REP_STR[0] in sTUBE:
  160. sTUBE = sTUBE.replace('%253A', ':')
  161. if REP_STR[1] in sTUBE:
  162. sTUBE = sTUBE.replace('%252F', '/')
  163. if REP_STR[2] in sTUBE:
  164. sTUBE = sTUBE.replace('%253F', '?')
  165. if REP_STR[3] in sTUBE:
  166. sTUBE = sTUBE.replace('%253D', '=')
  167. if REP_STR[4] in sTUBE:
  168. sTUBE = sTUBE.replace('%2526', '&')
  169. if REP_STR[5] in sTUBE:
  170. sTUBE = sTUBE.replace('%2525', '%')
  171.  
  172. crawl_youtube(sTUBE)
  173.  
  174. ########################################################################
  175.  
  176. def crawl_youtube(sTUBE):
  177.  
  178. global VIDEO_TITLE
  179. global MATCHED_LINK
  180. global SIGNATURE
  181. global COMPLETE_LINK
  182. global VIDEO_TYPE
  183. global VIDEO_RES
  184. global final_title
  185. global final_f_format
  186. global arg_f_format
  187.  
  188. # get title
  189. vid_title = re.search(r'title=\w.+', sTUBE)
  190. if vid_title:
  191. the_title = vid_title.group()
  192. if '&' in the_title:
  193. tmp_title = the_title.index('&')
  194. else: tmp_title = len(the_title) - 1
  195. f_title = the_title[6:tmp_title]
  196. final_title = f_title.replace('+', ' ')
  197. for per_num in ['%21','%22','%23','%24','%25','%26','%27','%28','%29',\
  198. '%2D','%5F','%3D','%2B','%5B','%7B','%7D','%5D','%7C','%5C',\
  199. '%3A','%3B','%2C','%3C','%3E','%2E','%3F','%2F']:
  200. if per_num in final_title:
  201. final_title = final_title.replace(per_num, '')
  202. else: print('[-] ERROR: Can\'t find video title. Title set to default.'); final_title = 'DownloadYTube'
  203.  
  204. # get links
  205. match = re.findall(r'http://\w.+?cp.+?video.+?quality.+?3D\w.+?%', sTUBE)
  206. if match:
  207. for mat in match:
  208.  
  209. MATCHED_LINK.append(mat)
  210.  
  211. # get signature
  212. find_sig = re.search(r'sig+\S.+quality', mat)
  213. if find_sig:
  214. c_sig = find_sig.group()
  215. final_sig = c_sig[6:-10]
  216. SIGNATURE.append(final_sig)
  217. #print(final_sig)
  218.  
  219. # for link / get last characters [id]
  220. if 'id=' in mat:
  221. y_index = mat.index('id=')
  222. id_last = y_index + 19
  223. li = mat[:id_last]
  224. COMPLETE_LINK.append(li)
  225.  
  226. # get video type
  227. if 'video/' in mat:
  228. vid_start = mat.index('video/')
  229. vid_end = vid_start + 11
  230. vid_type = mat[vid_start:vid_end]
  231. for vid_cod in ['flv', 'webm', 'mp4', '3gp']:
  232. if vid_cod in vid_type:
  233. VIDEO_TYPE.append(vid_cod)
  234.  
  235. else: print('[-] URLError'); exit(1)
  236.  
  237. # get formats/resolution
  238. fmt = re.search(r'fmt_list=\S.+?\&', sTUBE)
  239. if fmt:
  240. frmt = fmt.group().split('%2F')
  241. for v_format in frmt:
  242. if 'x' in v_format:
  243. VIDEO_RES.append(v_format)
  244. else: print('Can\'t find video formats. '); exit(1)
  245.  
  246. # append and combine video type and resolution
  247. j = 0
  248. while j < len(COMPLETE_LINK):
  249. arg_f_format.append(VIDEO_TYPE[j] + '_' + VIDEO_RES[j])
  250. j = j + 1
  251.  
  252. # if argument is [ -q ]
  253. if arg_queryf:
  254. i = 0
  255. print(final_title)
  256. while i < len(COMPLETE_LINK):
  257. print('[+] ' + VIDEO_TYPE[i] + '_' + VIDEO_RES[i])
  258. time.sleep(0.04)
  259. i = i + 1
  260. flush()
  261.  
  262. else:
  263.  
  264. # if argument is [ -f ] and the default format
  265. if arg_format is not None and arg_format in arg_f_format:
  266. final_f_format = arg_f_format.index(arg_format)
  267. elif arg_format not in arg_f_format and len(sys.argv) != 2:
  268. print('\n' + arg_format + ' not in video formats.')
  269. exit(1)
  270. else:
  271. final_f_format = 0
  272.  
  273. final_download_link()
  274.  
  275. ########################################################################
  276.  
  277. def final_download_link():
  278.  
  279. global FINAL_LINK
  280.  
  281. i = 0
  282. while i < len(COMPLETE_LINK):
  283. FINAL_LINK.append(COMPLETE_LINK[i] + '&signature=' + SIGNATURE[i])
  284. i = i + 1
  285.  
  286. download()
  287.  
  288. ########################################################################
  289.  
  290. def download():
  291.  
  292. req = urllib.request.Request(FINAL_LINK[final_f_format])
  293. req.add_header('User-Agent', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0')
  294. try:
  295. tmp_req = urllib.request.urlopen(req)
  296. tmp_size = tmp_req.getheader('Content-Length')
  297. size = int(tmp_size)
  298.  
  299. print('Downloading...')
  300.  
  301. # for reporthook in urlretrieve, 3 arguments needed
  302. def download_progress(counter, bsize, size):
  303. prog_percent = (counter * bsize * 100) / size
  304. sys.stdout.write('\r' + final_title.replace(' ', '') + '.' + VIDEO_TYPE[final_f_format] + \
  305. ' .......................... %2.f%%' % int(prog_percent))
  306. sys.stdout.flush()
  307.  
  308. urllib.request.urlretrieve(FINAL_LINK[final_f_format], (final_title.replace(' ', '') + \
  309. '.' + VIDEO_TYPE[final_f_format]), reporthook=download_progress)
  310. print('\nDone.')
  311. flush()
  312.  
  313. except urllib.error.HTTPError as e: print('Error downloading : ' + e.reason); exit(1)
  314.  
  315. ########################################################################
  316.  
  317. def flush():
  318.  
  319. del MATCHED_LINK[:]
  320. del SIGNATURE[:]
  321. del COMPLETE_LINK[:]
  322. del VIDEO_TYPE[:]
  323. del VIDEO_RES[:]
  324. del FINAL_LINK[:]
  325.  
  326. sTUBE = ''
  327. final_title = ''
  328. final_url = ''
  329. url = ''
  330. final_f_format = 0
  331. arg_queryf = ''
  332. arg_format = ''
  333. del arg_f_format[:]
  334.  
  335. ########################################################################
  336.  
  337. if __name__ =='__main__':
  338. main()

Report this snippet  

You need to login to post a comment.