chore: commit history pruned

This commit is contained in:
ae 2024-10-29 18:40:05 +02:00
commit dd25ddd888
3 changed files with 401 additions and 0 deletions

21
LICENSE-MIT Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 David Deprost
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

77
README.md Normal file
View File

@ -0,0 +1,77 @@
# [Automatic subtitle downloading for MPV](https://github.com/davidde/mpv-autosub)
- Cross-platform: **Windows, Mac and Linux**
- Multi-language support
- Subtitle provider login support
- **No hotkeys required**: opening a video will automatically trigger subtitles to download
(Only when the right subtitles are not yet present)
## Dependencies
This Lua script uses the [Python](https://www.python.org/downloads/) program
[subliminal](https://github.com/Diaoul/subliminal) to download subtitles.
Make sure you have both installed:
```bash
pip install subliminal
```
## Setup
1. Copy autosub.lua into:
| OS | Path |
| ------------- | ---------------------------------------------------- |
| **Windows** | [Drive]:\Users\\[User]\AppData\Roaming\mpv\scripts\ |
| **Mac/Linux** | ~/.config/mpv/scripts/ |
```bash
mkdir ~/.config/mpv/scripts
cat > ~/.config/mpv/scripts/autosub.lua
[Paste script contents and CTRL+D]
```
2. Specify the correct subliminal location for your system:
- To determine the correct path, use:
| OS | App | Command |
| ------------- | -------------- | ---------------- |
| **Windows** | Command Prompt | where subliminal |
| **Mac/Linux** | Terminal | which subliminal |
- Copy the path(s) to the subliminal variable(s) at the start of the script (optionally define multiple paths for different operating systems)
```lua
local subliminal_paths = {
['windows'] = '<path to subliminal.exe>',
['linux'] = '<path to subliminal>',
['darwin'] = '<path to subliminal>',
}
```
On Windows, the backslashes in the path need to be escaped, e.g.:
**C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37\\\\Scripts\\\\subliminal.exe**
## Customization
- Optionally change the subtitle languages / [ISO codes](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).
Be sure to put your preferred language at the top of the list.
If necessary, you can manually trigger downloading your first choice language by pressing `b`,
or your second choice language by pressing `n`.
- Optionally specify the login credentials for your preferred subtitle provider(s), if you have one.
- If you do not care for the automatic downloading functionality, and only wish to use the hotkeys,
simply change the `auto` bool to `false`.
- For added convenience, you can specify the locations to exclude from auto-downloading subtitles, or alternatively,
the _only_ locations that _should_ auto-download subtitles.
This script is under the [MIT License](./LICENSE-MIT),
so you are free to modify and adapt this script to your needs:
check out the [MPV Lua API](https://mpv.io/manual/stable/#lua-scripting) for more information.
If you find yourself unable to find the correct subtitles for some niche movies/series,
you might be interested in the [submod](https://github.com/davidde/submod_rs)
command line tool I've written to manually correct subtitle timing.
## Credits
Inspired by [selsta's](https://gist.github.com/selsta/ce3fb37e775dbd15c698) and
[fullmetalsheep's](https://gist.github.com/fullmetalsheep/28c397b200a7348027d983f31a7eddfa) autosub scripts.

303
autosub.lua Normal file
View File

@ -0,0 +1,303 @@
--=============================================================================
-->> SUBLIMINAL PATH:
--=============================================================================
-- This script uses Subliminal to download subtitles,
-- so make sure to specify your systems's Subliminal locations below:
local subliminal_paths = {
['windows'] = '<path to subliminal.exe>',
['linux'] = '<path to subliminal>',
['darwin'] = '<path to 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' },
-- { 'Swedish', 'sv', 'swe' },
-- { '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 = true, -- 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'
local subliminal = nil
-- 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
-- Determine OS to set correct subliminal executable path
-- Source: https://gist.github.com/soulik/82e9d02a818ce12498d1
function determine_os()
local raw_os_name = ''
-- LuaJIT shortcut
if jit and jit.os and jit.arch then
raw_os_name = jit.os
else
local popen_status, popen_result = pcall(io.popen, '')
if popen_status then
popen_result:close()
-- Unix based OS
raw_os_name = io.popen('uname -s', 'r'):read('*l')
else
-- Windows
local env_os = os.getenv('OS')
if env_os then
raw_os_name = env_os
end
end
end
return (raw_os_name):lower()
end
local os_name = determine_os()
if subliminal_paths[os_name] then
subliminal = subliminal_paths[os_name]
else
mp.msg.warn('Subliminal path not found for ' .. os_name)
mp.msg.warn('=> Subliminal path must be set manually in autosub.lua')
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)