config/mpv/scripts/autosub.lua (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
--============================================================================= -->> SUBLIMINAL PATH: --============================================================================= -- This script uses Subliminal to download subtitles, -- so make sure to specify your system's Subliminal location below: local subliminal = '/home/prithu/.local/bin/subliminal' --============================================================================= -->> SUBTITLE LANGUAGE: --============================================================================= -- Specify languages in this order: -- { 'language name', 'ISO-639-1', 'ISO-639-2' } ! -- (See: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) local languages = { -- If subtitles are found for the first language, -- other languages will NOT be downloaded, -- so put your preferred language first: { 'English', 'en', 'eng' }, -- { 'Dutch', 'nl', 'dut' }, -- { 'Spanish', 'es', 'spa' }, -- { 'French', 'fr', 'fre' }, -- { 'German', 'de', 'ger' }, -- { 'Italian', 'it', 'ita' }, -- { 'Portuguese', 'pt', 'por' }, -- { 'Polish', 'pl', 'pol' }, -- { 'Russian', 'ru', 'rus' }, -- { 'Chinese', 'zh', 'chi' }, -- { 'Arabic', 'ar', 'ara' }, } --============================================================================= -->> PROVIDER LOGINS: --============================================================================= -- These are completely optional and not required -- for the functioning of the script! -- If you use any of these services, simply uncomment it -- and replace 'USERNAME' and 'PASSWORD' with your own: local logins = { -- { '--addic7ed', 'USERNAME', 'PASSWORD' }, -- { '--legendastv', 'USERNAME', 'PASSWORD' }, -- { '--opensubtitles', 'USERNAME', 'PASSWORD' }, -- { '--subscenter', 'USERNAME', 'PASSWORD' }, } --============================================================================= -->> ADDITIONAL OPTIONS: --============================================================================= local bools = { auto = false, -- Automatically download subtitles, no hotkeys required debug = false, -- Use `--debug` in subliminal command for debug output force = true, -- Force download; will overwrite existing subtitle files utf8 = true, -- Save all subtitle files as UTF-8 } local excludes = { -- Movies with a path containing any of these strings/paths -- will be excluded from auto-downloading subtitles. -- Full paths are also allowed, e.g.: -- '/home/david/Videos', 'no-subs-dl', } local includes = { -- If anything is defined here, only the movies with a path -- containing any of these strings/paths will auto-download subtitles. -- Full paths are also allowed, e.g.: -- '/home/david/Videos', } --============================================================================= local utils = require 'mp.utils' -- Download function: download the best subtitles in most preferred language function download_subs(language) language = language or languages[1] if #language == 0 then log('No Language found\n') return false end log('Searching ' .. language[1] .. ' subtitles ...', 30) -- Build the `subliminal` command, starting with the executable: local table = { args = { subliminal } } local a = table.args for _, login in ipairs(logins) do a[#a + 1] = login[1] a[#a + 1] = login[2] a[#a + 1] = login[3] end if bools.debug then -- To see `--debug` output start MPV from the terminal! a[#a + 1] = '--debug' end a[#a + 1] = 'download' if bools.force then a[#a + 1] = '-f' end if bools.utf8 then a[#a + 1] = '-e' a[#a + 1] = 'utf-8' end a[#a + 1] = '-l' a[#a + 1] = language[2] a[#a + 1] = '-d' a[#a + 1] = directory a[#a + 1] = filename --> Subliminal command ends with the movie filename. local result = utils.subprocess(table) if string.find(result.stdout, 'Downloaded 1 subtitle') then -- When multiple external files are present, -- always activate the most recently downloaded: mp.set_property('slang', language[2]) -- Subtitles are downloaded successfully, so rescan to activate them: mp.commandv('rescan_external_files') log(language[1] .. ' subtitles ready!') return true else log('No ' .. language[1] .. ' subtitles found\n') return false end end -- Manually download second language subs by pressing 'n': function download_subs2() download_subs(languages[2]) end -- Control function: only download if necessary function control_downloads() -- Make MPV accept external subtitle files with language specifier: mp.set_property('sub-auto', 'fuzzy') -- Set subtitle language preference: mp.set_property('slang', languages[1][2]) mp.msg.warn('Reactivate external subtitle files:') mp.commandv('rescan_external_files') directory, filename = utils.split_path(mp.get_property('path')) if not autosub_allowed() then return end sub_tracks = {} for _, track in ipairs(mp.get_property_native('track-list')) do if track['type'] == 'sub' then sub_tracks[#sub_tracks + 1] = track end end if bools.debug then -- Log subtitle properties to terminal: for _, track in ipairs(sub_tracks) do mp.msg.warn('Subtitle track', track['id'], ':\n{') for k, v in pairs(track) do if type(v) == 'string' then v = '"' .. v .. '"' end mp.msg.warn(' "' .. k .. '":', v) end mp.msg.warn('}\n') end end for _, language in ipairs(languages) do if should_download_subs_in(language) then if download_subs(language) then return end -- Download successful! else return end -- No need to download! end log('No subtitles were found') end -- Check if subtitles should be auto-downloaded: function autosub_allowed() local duration = tonumber(mp.get_property('duration')) local active_format = mp.get_property('file-format') if not bools.auto then mp.msg.warn('Automatic downloading disabled!') return false elseif duration < 900 then mp.msg.warn('Video is less than 15 minutes\n' .. '=> NOT auto-downloading subtitles') return false elseif directory:find('^http') then mp.msg.warn('Automatic subtitle downloading is disabled for web streaming') return false elseif active_format:find('^cue') then mp.msg.warn('Automatic subtitle downloading is disabled for cue files') return false else local not_allowed = {'aiff', 'ape', 'flac', 'mp3', 'ogg', 'wav', 'wv', 'tta'} for _, file_format in pairs(not_allowed) do if file_format == active_format then mp.msg.warn('Automatic subtitle downloading is disabled for audio files') return false end end for _, exclude in pairs(excludes) do local escaped_exclude = exclude:gsub('%W','%%%0') local excluded = directory:find(escaped_exclude) if excluded then mp.msg.warn('This path is excluded from auto-downloading subs') return false end end for i, include in ipairs(includes) do local escaped_include = include:gsub('%W','%%%0') local included = directory:find(escaped_include) if included then break elseif i == #includes then mp.msg.warn('This path is not included for auto-downloading subs') return false end end end return true end -- Check if subtitles should be downloaded in this language: function should_download_subs_in(language) for i, track in ipairs(sub_tracks) do local subtitles = track['external'] and 'subtitle file' or 'embedded subtitles' if not track['lang'] and (track['external'] or not track['title']) and i == #sub_tracks then local status = track['selected'] and ' active' or ' present' log('Unknown ' .. subtitles .. status) mp.msg.warn('=> NOT downloading new subtitles') return false -- Don't download if 'lang' key is absent elseif track['lang'] == language[3] or track['lang'] == language[2] or (track['title'] and track['title']:lower():find(language[3])) then if not track['selected'] then mp.set_property('sid', track['id']) log('Enabled ' .. language[1] .. ' ' .. subtitles .. '!') else log(language[1] .. ' ' .. subtitles .. ' active') end mp.msg.warn('=> NOT downloading new subtitles') return false -- The right subtitles are already present end end mp.msg.warn('No ' .. language[1] .. ' subtitles were detected\n' .. '=> Proceeding to download:') return true end -- Log function: log to both terminal and MPV OSD (On-Screen Display) function log(string, secs) secs = secs or 2.5 -- secs defaults to 2.5 when secs parameter is absent mp.msg.warn(string) -- This logs to the terminal mp.osd_message(string, secs) -- This logs to MPV screen end mp.add_key_binding('b', 'download_subs', download_subs) mp.add_key_binding('n', 'download_subs2', download_subs2) mp.register_event('file-loaded', control_downloads) |