├── SubtitleTranslate - DeepL.ico ├── LICENSE ├── .gitignore ├── README.md └── SubtitleTranslate - DeepL.as /SubtitleTranslate - DeepL.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/donaldturinglee/potplayer-subtitle-translate-deepl/HEAD/SubtitleTranslate - DeepL.ico -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 donaldturinglee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### C++ ### 2 | # Prerequisites 3 | *.d 4 | 5 | # Compiled Object files 6 | *.slo 7 | *.lo 8 | *.o 9 | *.obj 10 | 11 | # Precompiled Headers 12 | *.gch 13 | *.pch 14 | 15 | # Compiled Dynamic libraries 16 | *.so 17 | *.dylib 18 | *.dll 19 | 20 | # Fortran module files 21 | *.mod 22 | *.smod 23 | 24 | # Compiled Static libraries 25 | *.lai 26 | *.la 27 | *.a 28 | *.lib 29 | 30 | # Executables 31 | *.exe 32 | *.out 33 | *.app 34 | 35 | ### Linux ### 36 | *~ 37 | 38 | # temporary files which can be created if a process still has a handle open of a deleted file 39 | .fuse_hidden* 40 | 41 | # KDE directory preferences 42 | .directory 43 | 44 | # Linux trash folder which might appear on any partition or disk 45 | .Trash-* 46 | 47 | # .nfs files are created when an open file is removed but is still being accessed 48 | .nfs* 49 | 50 | ### Vim ### 51 | # Swap 52 | [._]*.s[a-v][a-z] 53 | !*.svg # comment out if you don't need vector files 54 | [._]*.sw[a-p] 55 | [._]s[a-rt-v][a-z] 56 | [._]ss[a-gi-z] 57 | [._]sw[a-p] 58 | 59 | # Session 60 | Session.vim 61 | Sessionx.vim 62 | 63 | # Temporary 64 | .netrwhist 65 | # Auto-generated tag files 66 | tags 67 | # Persistent undo 68 | [._]*.un~ 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Potplayer Subtitle Translate - DeepL

4 | 5 |

6 | Integrate DeepL for real-time translation of PotPlayer subtitles 7 |
8 | View Demo 9 |   10 | Report Bug 11 |   12 | Request Feature 13 |

14 | 15 | 16 | 17 |
18 | Table of Contents 19 |
    20 |
  1. 21 | About The Project 22 |
  2. 23 |
  3. 24 | Getting Started 25 | 30 |
  4. 31 |
  5. Usage
  6. 32 |
  7. Contributing
  8. 33 |
  9. License
  10. 34 |
  11. Contact
  12. 35 |
36 |
37 | 38 | 39 | 40 | ## About The Project 41 | 42 | This project is a plugin for PotPlayer that enables subtitle translation via DeepL. It's designed to enhance your viewing experience by providing real-time, accurate translations of subtitles. The plugin leverages the advanced machine learning capabilities of DeepL to deliver high-quality translations, making it easier for users to enjoy media in various languages. 43 | 44 |

(back to top)

45 | 46 | 47 | 48 | ## Getting Started 49 | 50 | ### Prerequisites 51 | 52 | Before using this plugin, you need to obtain a DeepL API key: 53 | 54 | 1. **DeepL API Account** 55 | - Visit [DeepL API](https://www.deepl.com/pro-api) 56 | - Sign up for a free or paid account 57 | - Free tier includes 500,000 characters/month 58 | - Paid plans start from $6.99/month for higher usage limits 59 | 60 | 2. **Get Your API Key** 61 | - Log in to your DeepL account 62 | - Go to your [Account Settings](https://www.deepl.com/account/summary) 63 | - Navigate to the "API" tab 64 | - Copy your **Authentication Key** 65 | 66 | 3. **Note Your API Endpoint** 67 | - **Free API**: `https://api-free.deepl.com` 68 | - **Pro API**: `https://api.deepl.com` 69 | 70 | ### Installation 71 | 72 | 1. Clone repo to local 73 | 74 | ```bash 75 | git clone https://github.com/donaldturinglee/potplayer-subtitle-translate-deepl.git 76 | ``` 77 | 78 | 2. Copy files to PotPlayer extension directory 79 | 80 | ```bash 81 | cp potplayer-subtitle-translate-deepl/*.{as,ico} your_directory/PotPlayer/Extension/Subtitle/Translate/ 82 | ``` 83 | 84 |

(back to top)

85 | 86 | 87 | 88 | ## Usage 89 | 90 | [Potplayer with DeepL guide](https://youtu.be/KdrY5-sVJUI) 91 | 92 |

(back to top)

93 | 94 | 95 | 96 | ## Contributing 97 | 98 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. 99 | 100 | If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". 101 | Don't forget to give the project a star! Thanks again! 102 | 103 | 1. Fork the Project 104 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 105 | 3. Commit your Changes (`git commit -m 'feat: Add some AmazingFeature'`) 106 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 107 | 5. Open a Pull Request 108 | 109 |

(back to top)

110 | 111 | 112 | 113 | ## License 114 | 115 | Distributed under the MIT License. See `LICENSE` for more information. 116 | 117 |

(back to top)

118 | 119 | 120 | 121 | ## Contact 122 | 123 | Twitter - [@Donald Lee](https://twitter.com/donaldturinglee) 124 | 125 | Project Link: [https://github.com/donaldturinglee/potplayer-subtitle-translate-deepl](https://github.com/donaldturinglee/potplayer-subtitle-translate-deepl) 126 | 127 |

(back to top)

128 | -------------------------------------------------------------------------------- /SubtitleTranslate - DeepL.as: -------------------------------------------------------------------------------- 1 | /* 2 | real time subtitle translate for PotPlayer using DeepL 3 | */ 4 | 5 | // void OnInitialize() 6 | // void OnFinalize() 7 | // string GetTitle() -> get title for UI 8 | // string GetVersion -> get version for manage 9 | // string GetDesc() -> get detail information 10 | // string GetLoginTitle() -> get title for login dialog 11 | // string GetLoginDesc() -> get desc for login dialog 12 | // string GetUserText() -> get user text for login dialog 13 | // string GetPasswordText() -> get password text for login dialog 14 | // string ServerLogin(string User, string Pass) -> login 15 | // string ServerLogout() -> logout 16 | //------------------------------------------------------------------------------------------------ 17 | // array GetSrcLangs() -> get source language 18 | // array GetDstLangs() -> get target language 19 | // string Translate(string Text, string &in SrcLang, string &in DstLang) -> do translate !! 20 | 21 | string JsonParse(string json) { 22 | JsonReader Reader; 23 | JsonValue Root; 24 | string ret = ""; 25 | 26 | if (Reader.parse(json, Root) && Root.isObject()) { 27 | JsonValue translations = Root["translations"]; 28 | if (translations.isArray() && translations.size() > 0) { 29 | JsonValue firstTranslation = translations[0]; 30 | if (firstTranslation.isObject()) { 31 | JsonValue text = firstTranslation["text"]; 32 | if (text.isString()) { 33 | ret = text.asString(); 34 | } 35 | } 36 | } 37 | } 38 | return ret; 39 | } 40 | 41 | array LangTable = { 42 | "af", 43 | "sq", 44 | "am", 45 | "ar", 46 | "hy", 47 | "az", 48 | "eu", 49 | "be", 50 | "bn", 51 | "bs", 52 | "bg", 53 | "my", 54 | "ca", 55 | "ceb", 56 | "ny", 57 | "zh", 58 | "co", 59 | "hr", 60 | "cs", 61 | "da", 62 | "nl", 63 | "en", 64 | "eo", 65 | "et", 66 | "tl", 67 | "fi", 68 | "fr", 69 | "fy", 70 | "gl", 71 | "ka", 72 | "de", 73 | "el", 74 | "gu", 75 | "ht", 76 | "ha", 77 | "haw", 78 | "iw", 79 | "hi", 80 | "hmn", 81 | "hu", 82 | "is", 83 | "ig", 84 | "id", 85 | "ga", 86 | "it", 87 | "ja", 88 | "jw", 89 | "kn", 90 | "kk", 91 | "km", 92 | "ko", 93 | "ku", 94 | "ky", 95 | "lo", 96 | "la", 97 | "lv", 98 | "lt", 99 | "lb", 100 | "mk", 101 | "ms", 102 | "mg", 103 | "ml", 104 | "mt", 105 | "mi", 106 | "mr", 107 | "mn", 108 | "my", 109 | "ne", 110 | "no", 111 | "ps", 112 | "fa", 113 | "pl", 114 | "pt", 115 | "pa", 116 | "ro", 117 | "romanji", 118 | "ru", 119 | "sm", 120 | "gd", 121 | "sr", 122 | "st", 123 | "sn", 124 | "sd", 125 | "si", 126 | "sk", 127 | "sl", 128 | "so", 129 | "es", 130 | "su", 131 | "sw", 132 | "sv", 133 | "tg", 134 | "ta", 135 | "te", 136 | "th", 137 | "tr", 138 | "uk", 139 | "ur", 140 | "uz", 141 | "vi", 142 | "cy", 143 | "xh", 144 | "yi", 145 | "yo", 146 | "zu" 147 | }; 148 | 149 | string UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"; 150 | 151 | string GetTitle() { 152 | return "{$CP950=DeepL 翻譯$}{$CP0=DeepL translate$}"; 153 | } 154 | 155 | string GetVersion() { 156 | return "1"; 157 | } 158 | 159 | string GetDesc() { 160 | return "https://www.deepl.com/"; 161 | } 162 | 163 | string GetLoginTitle() { 164 | return ""; 165 | } 166 | 167 | string GetLoginDesc() { 168 | return ""; 169 | } 170 | 171 | string GetUserText() { 172 | return "Base URL: "; 173 | } 174 | 175 | string GetPasswordText() { 176 | return "API Key: "; 177 | } 178 | 179 | string base_url, api_key; 180 | 181 | string ServerLogin(string User, string Pass) { 182 | base_url = User; 183 | api_key = Pass; 184 | 185 | if (base_url.empty()) base_url = ""; 186 | if (api_key.empty()) api_key = ""; 187 | return "200 ok"; 188 | } 189 | 190 | void ServerLogout() { 191 | base_url = ""; 192 | api_key = ""; 193 | } 194 | 195 | array GetSrcLangs() { 196 | array ret = LangTable; 197 | 198 | ret.insertAt(0, ""); 199 | return ret; 200 | } 201 | 202 | array GetDstLangs() { 203 | array ret = LangTable; 204 | 205 | return ret; 206 | } 207 | 208 | string Translate(string Text, string &in SrcLang, string &in DstLang) { 209 | 210 | string url = base_url + "/v2/translate"; 211 | 212 | Text.replace("\\","\\\\"); 213 | Text.replace("\"","\\\""); 214 | Text.replace("\n","\\\\n"); 215 | Text.replace("\r","\\\\r"); 216 | Text.replace("\t","\\\\t"); 217 | 218 | string data = "{"; 219 | data += "\"text\":[\"" + Text + "\"],"; 220 | data += "\"target_lang\":\"" + DstLang + "\""; 221 | if (!SrcLang.empty()) { 222 | data += ",\"source_lang\":\"" + SrcLang + "\""; 223 | } 224 | data += "}"; 225 | 226 | string headers = "Authorization: DeepL-Auth-Key "+ api_key + "\r\n"; 227 | headers += "Content-Type: application/json"; 228 | 229 | string text = HostUrlGetStringWithAPI(url, UserAgent, headers, data); 230 | 231 | string ret = JsonParse(text); 232 | 233 | if (ret.length() > 0) { 234 | SrcLang = "UTF8"; 235 | DstLang = "UTF8"; 236 | return ret; 237 | } 238 | 239 | return ret; 240 | } 241 | 242 | string DictionaryToString(dictionary dict) { 243 | array keys = dict.getKeys(); 244 | uint length = keys.length(); 245 | array pairs(length); 246 | for (uint i = 0; i < length; i++) { 247 | string key = keys[i]; 248 | string value = string(dict[key]); 249 | pairs[i] = '"' + key + "\":\"" + value + '"'; 250 | } 251 | string jsonString = join(pairs, ','); 252 | return jsonString; 253 | } --------------------------------------------------------------------------------