Add subselect script

This commit is contained in:
zenyd 2017-09-24 03:15:02 +02:00
parent 025a419e63
commit 348749e6ce
3 changed files with 242 additions and 1 deletions

View File

@ -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
`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\<me>\subtitles
subselect_path=C:\Users\<me>\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`.

104
subselect.lua Normal file
View File

@ -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)

105
subselect.py Normal file
View File

@ -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()