diff --git a/SIGNALS.txt b/SIGNALS.txt index 027dd23..309452b 100644 --- a/SIGNALS.txt +++ b/SIGNALS.txt @@ -33,7 +33,9 @@ SIGNALS ['[ffmpeg]', index]: Post-Processing for url, index -['ignore', index] Do nothing +['ignore', index]: Do nothing + +['remove', index]: Removing dash audio/videos files, index EXAMPLES ======== diff --git a/youtube_dl_gui/DownloadThread.py b/youtube_dl_gui/DownloadThread.py index 054f1d7..06388a2 100644 --- a/youtube_dl_gui/DownloadThread.py +++ b/youtube_dl_gui/DownloadThread.py @@ -13,7 +13,8 @@ from .Utils import ( remove_spaces, string_to_array, get_encoding, - encode_list + encode_list, + remove_file ) OS_TYPE = name @@ -22,8 +23,9 @@ PUBLISHER_TOPIC = 'download' class DownloadManager(Thread): - def __init__(self, options, downloadlist): + def __init__(self, options, downloadlist, clear_dash_files): super(DownloadManager, self).__init__() + self.clear_dash_files = clear_dash_files self.downloadlist = downloadlist self.options = options self.running = True @@ -44,7 +46,14 @@ class DownloadManager(Thread): self.procNo -= 1 # If we still running create new ProcessWrapper thread if self.running: - self.procList.append(ProcessWrapper(self.options, url, index)) + self.procList.append( + ProcessWrapper( + self.options, + url, + index, + self.clear_dash_files + ) + ) self.procNo += 1 else: # Return True if at least one process is alive else return False @@ -56,7 +65,7 @@ class DownloadManager(Thread): # If we reach here close down all child threads self.terminate_all() CallAfter(Publisher.sendMessage, PUBLISHER_TOPIC, ['finish', -1]) - + def add_download_item(self, downloadItem): self.downloadlist.append(downloadItem) @@ -93,11 +102,13 @@ class DownloadManager(Thread): class ProcessWrapper(Thread): - def __init__(self, options, url, index): + def __init__(self, options, url, index, clear_dash_files): super(ProcessWrapper, self).__init__() + self.clear_dash_files = clear_dash_files self.options = options self.index = index self.url = url + self.filenames = [] self.proc = None self.stopped = False self.err = False @@ -120,8 +131,21 @@ class ProcessWrapper(Thread): else: CallAfter(Publisher.sendMessage, PUBLISHER_TOPIC, data) if not self.err and not self.stopped: + if self.clear_dash_files: + self.cleardash() CallAfter(Publisher.sendMessage, PUBLISHER_TOPIC, ['finish', self.index]) + def extract_filename(self, data): + data_list = data.split(':') + if 'Destination' in data_list[0].split(): + self.filenames.append(data_list[1].lstrip()) + + def cleardash(self): + if self.filenames: + CallAfter(Publisher.sendMessage, PUBLISHER_TOPIC, ['remove', self.index]) + for f in self.filenames: + remove_file(f) + def close(self): self.proc.kill() self.stopped = True @@ -139,6 +163,8 @@ class ProcessWrapper(Thread): return output.rstrip() def proc_output(self, output): + if self.clear_dash_files: + self.extract_filename(output) data = remove_spaces(string_to_array(output)) data.append(self.index) data = self.filter_data(data) diff --git a/youtube_dl_gui/OptionsHandler.py b/youtube_dl_gui/OptionsHandler.py index b2102cc..ca16869 100644 --- a/youtube_dl_gui/OptionsHandler.py +++ b/youtube_dl_gui/OptionsHandler.py @@ -44,6 +44,8 @@ class OptionsHandler(): self.subsLang = "English" self.writeAutoSubs = False self.cmdArgs = "" + self.dashAudioFormat = "NO SOUND" + self.clearDashFiles = False def set_settings_path(self): self.settings_abs_path = os.path.expanduser('~') @@ -94,6 +96,8 @@ class OptionsHandler(): self.subsLang = opts[25] self.writeAutoSubs = opts[26] in ['True'] self.cmdArgs = opts[27] + self.dashAudioFormat = opts[28] + self.clearDashFiles = opts[29] in ['True'] def save_to_file(self): f = open(self.settings_abs_path, 'w') @@ -125,5 +129,7 @@ class OptionsHandler(): f.write('SubtitlesLanguage='+str(self.subsLang)+'\n') f.write('WriteAutoSubtitles='+str(self.writeAutoSubs)+'\n') f.write('CmdArgs='+str(self.cmdArgs)+'\n') + f.write('DashAudioFormat='+str(self.dashAudioFormat)+'\n') + f.write('ClearDashFiles='+str(self.clearDashFiles)+'\n') f.close() \ No newline at end of file diff --git a/youtube_dl_gui/SignalHandler.py b/youtube_dl_gui/SignalHandler.py index f521163..23b4c4f 100644 --- a/youtube_dl_gui/SignalHandler.py +++ b/youtube_dl_gui/SignalHandler.py @@ -57,6 +57,8 @@ class IndexDownloadHandler(): self.download(data) elif data[0] == '[ffmpeg]': self.post_proc() + elif data[0] == 'remove': + self.remove() def finish(self): self.ListCtrl._write_data(self.index, 4, '') @@ -77,7 +79,7 @@ class IndexDownloadHandler(): def post_proc(self): self.ListCtrl._write_data(self.index, 4, '') - self.ListCtrl._write_data(self.index, 5, 'Converting to Audio %s' % self.info) + self.ListCtrl._write_data(self.index, 5, 'Post-Processing %s' % self.info) def download(self, data): self.ListCtrl._write_data(self.index, 1, data[3]) @@ -92,4 +94,7 @@ class IndexDownloadHandler(): self.ListCtrl._write_data(self.index, 3, '') self.ListCtrl._write_data(self.index, 4, '') self.info = '%s/%s' % (data[1], data[2]) - \ No newline at end of file + + def remove(self): + self.ListCtrl._write_data(self.index, 5, 'Removing DASH %s' % self.info) + diff --git a/youtube_dl_gui/Utils.py b/youtube_dl_gui/Utils.py index 4128450..8897ee4 100644 --- a/youtube_dl_gui/Utils.py +++ b/youtube_dl_gui/Utils.py @@ -1,5 +1,6 @@ #! /usr/bin/env python +import os import sys def remove_spaces(array): @@ -19,4 +20,12 @@ def get_encoding(): def encode_list(data_list, encoding): return [x.encode(encoding, 'ignore') for x in data_list] - \ No newline at end of file + +def video_is_dash(video): + return "DASH" in video + +def have_dash_audio(audio): + return audio != "NO SOUND" + +def remove_file(filename): + os.remove(filename) \ No newline at end of file diff --git a/youtube_dl_gui/YoutubeDLGUI.py b/youtube_dl_gui/YoutubeDLGUI.py index c3de003..f791990 100644 --- a/youtube_dl_gui/YoutubeDLGUI.py +++ b/youtube_dl_gui/YoutubeDLGUI.py @@ -25,6 +25,10 @@ from .DownloadThread import DownloadManager from .OptionsHandler import OptionsHandler from .YoutubeDLInterpreter import YoutubeDLInterpreter from .SignalHandler import DownloadHandler +from .Utils import ( + video_is_dash, + have_dash_audio +) if os.name == 'nt': YOUTUBE_DL_FILENAME = 'youtube-dl.exe' @@ -43,6 +47,9 @@ VIDEOFORMATS = ["highest available", "mp4 720p(DASH)", "mp4 480p(DASH)", "mp4 360p(DASH)"] +DASH_AUDIO_FORMATS = ["NO SOUND", + "DASH m4a audio 128k", + "DASH webm audio 48k"] LANGUAGES = ["English", "Greek", "Portuguese", @@ -158,7 +165,11 @@ class MainFrame(wx.Frame): if not self.statusList._is_empty(): options = YoutubeDLInterpreter(self.optionsList, YOUTUBE_DL_FILENAME).get_options() self.status_bar_write('Download started') - self.downloadThread = DownloadManager(options, self.statusList._get_items()) + self.downloadThread = DownloadManager( + options, + self.statusList._get_items(), + self.optionsList.clearDashFiles + ) self.downloadHandler = DownloadHandler(self.statusList) self.downloadButton.SetLabel('Stop') self.updateButton.Disable() @@ -342,25 +353,53 @@ class VideoPanel(wx.Panel): wx.Panel.__init__(self, parent) wx.StaticText(self, -1, 'Video Format', (15, 10)) self.videoFormatCombo = wx.ComboBox(self, choices=VIDEOFORMATS, pos=(10, 30), size=(160, 30)) - wx.StaticText(self, -1, 'Playlist Options', (300, 30)) - wx.StaticText(self, -1, 'Start', (250, 60)) - self.startBox = wx.TextCtrl(self, -1, pos=(320, 55), size=(50, -1)) - wx.StaticText(self, -1, 'Stop', (250, 100)) - self.stopBox = wx.TextCtrl(self, -1, pos=(320, 95), size=(50, -1)) - wx.StaticText(self, -1, 'Max DLs', (250, 140)) - self.maxBox = wx.TextCtrl(self, -1, pos=(320, 135), size=(50, -1)) + wx.StaticText(self, -1, 'DASH Audio', (15, 100)) + self.dashAudioFormatCombo = wx.ComboBox(self, choices=DASH_AUDIO_FORMATS, pos=(10, 120), size=(160, 30)) + self.clearDashFilesChk = wx.CheckBox(self, -1, 'Clear DASH audio/video files', (10, 160)) + wx.StaticText(self, -1, 'Playlist Options', (350, 30)) + wx.StaticText(self, -1, 'Start', (300, 60)) + self.startBox = wx.TextCtrl(self, -1, pos=(370, 55), size=(50, -1)) + wx.StaticText(self, -1, 'Stop', (300, 100)) + self.stopBox = wx.TextCtrl(self, -1, pos=(370, 95), size=(50, -1)) + wx.StaticText(self, -1, 'Max DLs', (300, 140)) + self.maxBox = wx.TextCtrl(self, -1, pos=(370, 135), size=(50, -1)) + + self.Bind(wx.EVT_COMBOBOX, self.OnVideoFormatPick, self.videoFormatCombo) + self.Bind(wx.EVT_COMBOBOX, self.OnAudioFormatPick, self.dashAudioFormatCombo) + + def OnAudioFormatPick(self, event): + if have_dash_audio(self.dashAudioFormatCombo.GetValue()): + self.clearDashFilesChk.Enable() + else: + self.clearDashFilesChk.SetValue(False) + self.clearDashFilesChk.Disable() + + def OnVideoFormatPick(self, event): + if video_is_dash(self.videoFormatCombo.GetValue()): + self.dashAudioFormatCombo.Enable() + else: + self.dashAudioFormatCombo.Disable() def load_options(self): self.videoFormatCombo.SetValue(self.optList.videoFormat) self.startBox.SetValue(self.optList.startTrack) self.stopBox.SetValue(self.optList.endTrack) self.maxBox.SetValue(self.optList.maxDownloads) + self.dashAudioFormatCombo.SetValue(self.optList.dashAudioFormat) + self.clearDashFilesChk.SetValue(self.optList.clearDashFiles) + if not video_is_dash(self.optList.videoFormat): + self.dashAudioFormatCombo.Disable() + if not have_dash_audio(self.optList.dashAudioFormat): + self.clearDashFilesChk.SetValue(False) + self.clearDashFilesChk.Disable() def save_options(self): self.optList.videoFormat = self.videoFormatCombo.GetValue() self.optList.startTrack = self.startBox.GetValue() self.optList.endTrack = self.stopBox.GetValue() self.optList.maxDownloads = self.maxBox.GetValue() + self.optList.dashAudioFormat = self.dashAudioFormatCombo.GetValue() + self.optList.clearDashFiles = self.clearDashFilesChk.GetValue() class DownloadPanel(wx.Panel): diff --git a/youtube_dl_gui/YoutubeDLInterpreter.py b/youtube_dl_gui/YoutubeDLInterpreter.py index 3250d9d..435462f 100644 --- a/youtube_dl_gui/YoutubeDLInterpreter.py +++ b/youtube_dl_gui/YoutubeDLInterpreter.py @@ -9,6 +9,7 @@ work) ''' from os import name +from .Utils import video_is_dash OS_TYPE = name @@ -31,6 +32,10 @@ VIDEOFORMATS = {"highest available":"auto", "mp4 720p(DASH)":"136", "mp4 480p(DASH)":"135", "mp4 360p(DASH)":"134"} + +DASH_AUDIO_FORMATS = {"NO SOUND":"None", + "DASH m4a audio 128k":"140", + "DASH webm audio 48k":"171"} class YoutubeDLInterpreter(): @@ -98,7 +103,15 @@ class YoutubeDLInterpreter(): def set_video_opts(self): if self.optionsList.videoFormat != 'highest available': self.opts.append('-f') - self.opts.append(VIDEOFORMATS[self.optionsList.videoFormat]) + if video_is_dash(self.optionsList.videoFormat): + vf = VIDEOFORMATS[self.optionsList.videoFormat] + af = DASH_AUDIO_FORMATS[self.optionsList.dashAudioFormat] + if af != 'None': + self.opts.append(vf+'+'+af) + else: + self.opts.append(vf) + else: + self.opts.append(VIDEOFORMATS[self.optionsList.videoFormat]) def set_playlist_opts(self): if (self.optionsList.startTrack != '1' and self.optionsList.startTrack != ''):