capncoolio

Simple youtube downloader

Jun 11th, 2021 (edited)
510
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. from pytube import YouTube
  2. import PySimpleGUI as sg
  3. import requests
  4. import os.path
  5. import os
  6. import threading
  7.  
  8. downloading = False
  9. dlProg = 0
  10. showDone = False
  11. bytesGot = 0
  12. bytesTot = 0
  13. killThread = False
  14. cancelled = False
  15.  
  16. file_list_column = [
  17.     [
  18.         sg.Text("YT Link", size=(7, 1)),
  19.         sg.In(size=(40, 1), enable_events=True, key="-LINK-"),
  20.         sg.Button(button_text='Go', enable_events=True, key="-GO-", size=(10, 1)),
  21.     ],
  22.     [
  23.         sg.HSeparator()
  24.     ],
  25.     [
  26.         sg.Text("Save dir", size=(7, 1)),
  27.         sg.In(size=(40, 1), key="-DIR-", readonly=True),
  28.         sg.FolderBrowse(size=(10, 1))
  29.     ],
  30.     [
  31.         sg.Listbox(
  32.             values=[], enable_events=True, size=(62, 20), key="-VIDEO LIST-"
  33.         )
  34.     ],
  35.     [
  36.         sg.Text("File name:", size=(10, 1)),
  37.         sg.In(size=(50, 1), key="-NAME-", readonly=False),
  38.     ],
  39.     [
  40.         sg.HSeparator()
  41.     ],
  42.     [
  43.         sg.Button(button_text='Download', enable_events=True, key="-DL-", size=(10, 1)),
  44.         sg.ProgressBar(max_value=100, size=(32, 20), key="-PROG-"),
  45.  
  46.     ],
  47.     [
  48.         sg.HSeparator()
  49.     ],
  50.     [
  51.         sg.Text(key="-TEXTPROG-", text="0/0mb", size=(44, 1), justification='left'),
  52.         sg.Button(button_text='CANCEL', enable_events=True, key="-CANCEL-", size=(10, 1), button_color='gray', disabled=True)
  53.     ]
  54. ]
  55.  
  56. # ----- Full layout -----
  57. layout = [
  58.     [
  59.         sg.Column(file_list_column, element_justification='center'),
  60.     ]
  61. ]
  62.  
  63. window = sg.Window("Youtube downloader", layout, finalize=True)
  64.  
  65.  
  66. def download_video(file_listd, dird, ftyped, indexd, savenamed):
  67.     global downloading
  68.     global dlProg
  69.     global showDone
  70.     global bytesGot
  71.     global bytesTot
  72.     global killThread
  73.     global cancelled
  74.  
  75.     downloading = True
  76.     url = file_listd[indexd].url
  77.     with open(os.path.join(dird, savenamed + ftyped), "wb") as f:
  78.         r = requests.get(url=url, stream=True)
  79.         print(r.headers)
  80.         total_length = r.headers.get('content-length')
  81.         if total_length is None:  # no content length header
  82.             f.write(r.content)
  83.         else:
  84.             dl = 0
  85.             bytesTot = float(total_length) / 1048576.0
  86.             total_length = int(total_length)
  87.             for data in r.iter_content(chunk_size=4096):
  88.                 if killThread is True:
  89.                     print("EXITING THREAD")
  90.                     f.close()
  91.                     os.unlink(f.name)
  92.                     cancelled = True
  93.                     break
  94.                 dl += len(data)
  95.                 f.write(data)
  96.                 bytesGot = (dl / bytesTot) * bytesTot
  97.                 done = int(100 * dl / total_length)
  98.                 dlProg = done
  99.         dlProg = 0
  100.         bytesTot = 0
  101.         bytesGot = 0
  102.         downloading = False
  103.         showDone = True
  104.  
  105.  
  106. # Run the Event Loop
  107. while True:
  108.     # don't actually know exactly what the size of each popup is, but whatever. Close enough.
  109.     popupLocX, popupLocY = int(window.current_location()[0] + window.size[0] / 2) - 60, \
  110.                            int(window.current_location()[1] + window.size[1] / 2) - 30
  111.  
  112.     event, values = window.read(timeout=10)
  113.     stream_strings = []
  114.     selected = None
  115.     if event == "Exit" or event == sg.WIN_CLOSED:
  116.         killThread = True
  117.         try:
  118.             x.join()  # wait... for some reason
  119.         except:
  120.             pass  # who cares we're exiting
  121.         break
  122.  
  123.     if event == "-GO-":
  124.         link = values["-LINK-"]
  125.         try:
  126.             video = YouTube(link)
  127.             file_list = video.fmt_streams
  128.             for f in file_list:
  129.                 if (str(f.mime_type) == 'video/mp4' and len(f.codecs) == 2) or str(f.mime_type) == 'audio/mp4':
  130.                     stream_strings.append(str(f.resolution) + ', ' + str(f.mime_type) + ', ' + str(f.codecs) + ', '
  131.                                           + str(round(float(video.length / 60), 2)) + 'min')
  132.         except:
  133.             sg.popup_error("Invalid Url, try another!", no_titlebar=True, location=(popupLocX, popupLocY))
  134.             file_list = []
  135.             window["-VIDEO LIST-"].update(None)
  136.         fnames = []
  137.         for ff in file_list:
  138.             if (str(ff.mime_type) == 'video/mp4' and len(ff.codecs) == 2) or str(ff.mime_type) == 'audio/mp4':
  139.                 fnames.append(ff)
  140.  
  141.         window["-VIDEO LIST-"].update(stream_strings)
  142.     elif event == "-VIDEO LIST-":  # A file was chosen from the listbox
  143.         try:
  144.             selected = window.Element('-VIDEO LIST-').Widget.curselection()[0]
  145.             print('selected: ' + selected)
  146.         except:
  147.             pass
  148.     elif event == "-DL-":
  149.         dir = values['-DIR-']
  150.         hasElement = True
  151.         try:
  152.             index = window.Element('-VIDEO LIST-').Widget.curselection()[0]
  153.         except:
  154.             hasElement = False
  155.         ftype = None
  156.  
  157.         try:
  158.             file = fnames[index]
  159.             if str(file.mime_type)[0] == 'v':
  160.                 ftype = '.mp4'
  161.             else:
  162.                 ftype = '.m4a'
  163.         except:
  164.             pass
  165.  
  166.         saveName = values['-NAME-']
  167.         if len(dir) == 0 or hasElement is False or len(saveName) == 0:
  168.             if len(dir) == 0:
  169.                 sg.popup_error("No directory selected!", no_titlebar=True, location=(popupLocX, popupLocY))
  170.             elif hasElement is False:
  171.                 sg.popup_error("No item selected!", no_titlebar=True, location=(popupLocX, popupLocY))
  172.             else:
  173.                 sg.popup_error("No filename given!", no_titlebar=True, location=(popupLocX, popupLocY))
  174.             continue
  175.         try:
  176.             if downloading is False:
  177.                 window['-CANCEL-'].update(disabled=False, button_color='red')
  178.                 x = threading.Thread(target=download_video, args=(fnames, dir, ftype, index, saveName))
  179.                 x.start()
  180.             else:
  181.                 sg.popup_error("Another file is currently being downloaded, please wait until it's done!",
  182.                                no_titlebar=True)
  183.         except:
  184.             pass
  185.     elif event == event == "-CANCEL-":
  186.         killThread = True
  187.         window['-CANCEL-'].update(disabled=True, button_color='gray')
  188.  
  189.     progText = '{:.2f}'.format(bytesGot / 1048576.0) + 'mb / ' + '{:.2f}'.format(bytesTot) + 'mb'
  190.     window['-PROG-'].update(dlProg)
  191.     window['-TEXTPROG-'].update(progText)
  192.  
  193.     if showDone is True:
  194.         window['-CANCEL-'].update(disabled=True, button_color='gray')
  195.         if cancelled is True:
  196.             sg.popup_ok("Download cancelled!", no_titlebar=True, location=(popupLocX, popupLocY))
  197.             cancelled = False
  198.             killThread = False
  199.         else:
  200.             sg.popup_ok("Download complete!", no_titlebar=True, location=(popupLocX, popupLocY))
  201.         showDone = False
  202.  
  203. window.close()
  204.  
RAW Paste Data