From 348749e6ceccc3b91ff6ebced92c0dca0cc08614 Mon Sep 17 00:00:00 2001 From: zenyd Date: Sun, 24 Sep 2017 03:15:02 +0200 Subject: [PATCH] Add subselect script --- README.md | 34 +++++++++++++++- subselect.lua | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ subselect.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 subselect.lua create mode 100644 subselect.py diff --git a/README.md b/README.md index 09cf62c..97f105f 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,36 @@ Key Bind|Effect `ctrl + j`|Toggle script on/off `alt + j`|Toggle sub visibility on/off (non-styled subs) `alt + '+'`|Increase speedup -`alt + '-'`|Decrease speedup \ No newline at end of file +`alt + '-'`|Decrease speedup + +## subselect +A lua script for downloading subtitles using a GUI and automatically loading them in mpv. It lets you input the name of the video but mainly tries to guess it based on the video title. Uses subliminal for subtitle download and Python tkinter for GUI. Works both on Windows and Linux (possibly macOS too?). + +Right now it only lists subtitles from OpenSubtitles, but has the ability to search for the best subtitle which searches all subtitle providers. + +### Prerequisits +1. Install Python 3 +2. Make sure Python is in your PATH +3. Linux: Depending on the used distribution installation of `pip` and `tk` may be necessary +3. Install subliminal: `python -m pip install subliminal` should do the trick + +### Installation +Copy subselect.lua and subselect.py into your script folder + +### Configuration +* *down_dir*: set the download path for the subtitles +* *subselect_path*: set the subselect.py path +* *sub_language*: set language for subtitles [default english]; value is a 3-letter ISO-639-3 language code + +Per default the script tries to download the subtitles into the folder from where the video is being played. Is that not possible it downloads them into your HOME folder, or in Windows into your Downloads folder. You may have to set the subselect.py path manually if the script guesses the wrong mpv configuration directory. If the script is somehow not working as expected, it is recommended to set both *down_dir* and *subselect_path* and make sure they are absolute paths and do exist. + +The option to be changed can be put inside a `subselect.conf` file in the lua-settings folder. Create them if they don't exist. +Sample `subselect.conf` if you want to change both options: +``` +down_dir=C:\Users\\subtitles +subselect_path=C:\Users\\python_scripts\subselect.py +sub_language=deu +``` + +### Usage +First invoke the script using `alt + u`, input a movie name, or use the one provided by the script, search and download subtitles. If you want to change the language for the subtitles append `;[3-letter ISO-639-3 code]`. So if you want to search for e.g. german subtitles append `;deu`. \ No newline at end of file diff --git a/subselect.lua b/subselect.lua new file mode 100644 index 0000000..40c8373 --- /dev/null +++ b/subselect.lua @@ -0,0 +1,104 @@ +local utils = require 'mp.utils' +require 'mp.options' + +options = {} +options.down_dir = "" +options.sub_language = "eng" + +if package.config:sub(1,1) == "/" then + options.subselect_path = utils.join_path(os.getenv("HOME"), ".config/mpv/scripts/subselect.py") + ops = "unix" +else + options.subselect_path = utils.join_path(os.getenv("APPDATA"), "mpv\\scripts\\subselect.py") + ops = "win" +end + +function fixsub(path) + f = io.open(path, "r") + if f == nil then + return + end + content = f:read("*all") + f:close() + write = false + content = content:gsub("%s*%-%->%s*", + function(w) + if w:len() < 5 then + write = true + return " --> " + end + end, 1) + if not write then + return + end + f = io.open(path, "w") + f:write(content) + f:flush() + f:close() +end + +function set_down_dir(ddir) + if ddir == "" then + if mp.get_property_native("path", ""):find("://") ~= nil then + if ops == "win" then + ddir = utils.join_path(os.getenv("USERPROFILE"), "Downloads") + else + ddir = os.getenv("HOME") + end + else + ddir = utils.split_path(mp.get_property_native("path", "")) + if ops == "win" then + if ddir:find("^%a:") == nil then + ddir = utils.join_path(os.getenv("USERPROFILE"), "Downloads") + end + else + if ddir:find("^/") == nil then + ddir = os.getenv("HOME") + end + end + end + end + return ddir +end + +function get_python_binary() + python = nil + python_version = utils.subprocess({ args = { "python", "--version" }}) + if python_version.status < 0 then + mp.osd_message("python not found") + else + if python_version.stdout:find("3%.") ~= nil then + python = "python" + else + python_version = utils.subprocess({ args = { "python3", "--version" }}) + if python_version.status < 0 then + mp.osd_message("python3 not installed") + else + python = "python3" + end + end + end + return python +end + +function search_subs() + read_options(options) + ddir = set_down_dir(options.down_dir) + video = mp.get_property_native("media-title", "") + python = get_python_binary() + if python ~= nil then + ret = utils.subprocess({ args = { python, options.subselect_path, video, ddir, options.sub_language }}) + else + return + end + if string.find(ret.stdout, ".") ~= nil then + mp.osd_message("loading subtitle: "..ret.stdout) + subtitle_path = utils.join_path(ddir, ret.stdout) + fixsub(subtitle_path) + mp.commandv("sub-add", subtitle_path) + else + mp.osd_message("No subtitles found") + end +end + +mp.add_key_binding("alt+u", "subselect", search_subs) \ No newline at end of file diff --git a/subselect.py b/subselect.py new file mode 100644 index 0000000..905852d --- /dev/null +++ b/subselect.py @@ -0,0 +1,105 @@ +from tkinter import * +from subliminal import * +from babelfish import Language +import sys, os +import tkinter.messagebox + +class subselect : + + def __init__(self) : + self.root = Tk() + frame = self.root + frame.title("Subtitle Downloader") + self.video_title_in = Entry(frame, width=100) + self.video_title_in.insert(0, videotitle) + self.video_title_in.grid(row=0, column=0) + self.search_button = Button(frame, text="Search", command=self.search) + self.search_button.grid(row=0, column=1) + self.best_button = Button(frame, text="Best", command=self.download_best_subtitle) + self.best_button.grid(row=0, column=2, sticky=E+W) + self.result_listbox = Listbox(self.root) + + def show_subtitles(self, subtitles) : + self.result_listbox.delete(0, END) + self.subtitles_in_list = [] + for s in subtitles : + if hasattr(s, "filename") : + self.result_listbox.insert(END, s.filename) + self.subtitles_in_list += [s] + self.result_listbox.grid(row=1, column=0, columnspan=3, sticky=E+W) + + if not hasattr(self, "download_button") : + self.info_label = Label(self.root) + self.info_label.grid(row=2, column=0) + self.download_button = Button(self.root, text="Download", command=self.download_selected_subtitle) + self.download_button.grid(row=2, column=2) + self.info_label.configure(text="{} Subtitles".format(self.result_listbox.size())) + + def get_video_from_title(self) : + video_title = self.video_title_in.get() + if video_title == "" : + return + + self.language = sub_language + if ";" in video_title : + video_title = video_title.split(";") + self.language = video_title[-1].strip() + video_title = video_title[0] + self.video = Video.fromname(video_title) + + def search(self) : + self.get_video_from_title() + try : + subtitles = list_subtitles([self.video], {Language(self.language)}, providers=["opensubtitles"]) + except ValueError as exc : + self.show_message("Error", str(exc)) + else : + self.show_subtitles(subtitles[self.video]) + + def download_best_subtitle(self) : + self.get_video_from_title() + try : + best_subtitles = download_best_subtitles([self.video], {Language(self.language)}) + except ValueError as exc : + self.show_message("Error", str(exc)) + else : + if best_subtitles[self.video] != [] : + best_subtitle = best_subtitles[self.video][0] + self.save_subtitle(self.video, False, best_subtitle) + else : + self.show_message("Not found", "No subtitles found. Try a different name.") + + def download_selected_subtitle(self) : + i = self.result_listbox.curselection() + if i == () : + self.show_message("Download failed", "Please select a subtitle") + else : + selected_subtitle = self.subtitles_in_list[i[0]] + download_subtitles([selected_subtitle]) + self.save_subtitle(self.video, True, selected_subtitle) + + def save_subtitle(self, video, change_filename, subtitle) : + if change_filename : + video.name = subtitle.filename + title = os.path.splitext(subtitle.filename)[0]+".srt" + else : + title = video.name + ".srt" + s = save_subtitles(video, [subtitle], True, save_dir) + if s != [] : + print(title, end="") + self.root.destroy() + else : + self.show_message("Download failed", "Subtitle download failed!") + + def show_message(self, title, msg) : + tkinter.messagebox.showinfo(title, msg) + +videotitle = save_dir = "" +sub_language = "eng" + +if len(sys.argv) > 1 : + videotitle = sys.argv[1] + save_dir = sys.argv[2] + sub_language = sys.argv[3] + +subselect().root.mainloop()