├── .github └── FUNDING.yml ├── SubtitleTranslate - lingva.ico ├── LICENSE ├── README_KO.md ├── README.md └── SubtitleTranslate - lingva.as /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: gnh1201 2 | custom: ['https://gnh1201.link'] 3 | -------------------------------------------------------------------------------- /SubtitleTranslate - lingva.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnh1201/potplayer-lingva/HEAD/SubtitleTranslate - lingva.ico -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Namhyeon, Go 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 | -------------------------------------------------------------------------------- /README_KO.md: -------------------------------------------------------------------------------- 1 | # potplayer-lingva 2 | 팟플레이어 실시간 자막 번역을 위한 Lingva Translate 연동 3 | 4 | [English](README.md) | [한국어](README_KO.md) 5 | 6 | ## 사용방법 7 | 1. *.as 및 *.ico로 끝나는 파일을 `C:\Program Files\DAUM\PotPlayer\Extension\Subtitle\Translate`에 복사합니다. 8 | 2. 서버 URL(예를 들어, `https://lingva.ml` 또는 직접 구축한 서버 URL)를 팟플레이어의 실시간 자막 설정에 기재합니다. 9 | 3. 영상을 시청합니다. 10 | 11 | ## 사용 가능한 서버 12 | - https://lingva.ml - 기본 13 | - https://translate.catswords.net - 대한민국, 2024년 11월 10일 기준 운영중 (***확인 필수***: [이용 규칙](https://policy.catswords.social/site_extended_description.html) 및 [개인정보보호정책](https://policy.catswords.social/site_terms.html)) 14 | 15 | ## 필요한 구성요소 16 | - PotPlayer - https://potplayer.daum.net/ 17 | - Lingva Translate - https://github.com/thedaviddelta/lingva-translate 18 | 19 | ## 보안 문제 보고 20 | - abuse@catswords.net 21 | - [GitHub 보안 권고 (gnh1201/potplayer-lingva)](https://github.com/gnh1201/potplayer-lingva/security) 22 | 23 | ## 커뮤니티 참여 24 | - ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss) 25 | - [Microsoft Teams에서 Catswords OSS 참여 (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI) 26 | - [Discord에서 Catswords OSS #potplayer-lingva 참여 (discord.gg)](https://discord.gg/zmQW5MtjcC) 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # potplayer-lingva 2 | [![Discord chat](https://img.shields.io/discord/359930650330923008?logo=discord)](https://discord.gg/zmQW5MtjcC) 3 | 4 | Lingva Translate integration for PotPlayer subtitles realtime translation 5 | 6 | [English](README.md) | [한국어](README_KO.md) 7 | 8 | ## How to use 9 | 1. Copy the files(*.as, *.ico) to `C:\Program Files\DAUM\PotPlayer\Extension\Subtitle\Translate` 10 | 2. Set the server URL (e.g. `https://lingva.ml` or your server URL) in the subtitles realtime translation configuration on PotPlayer 11 | 3. Enjoy it. 12 | 13 | ## Available servers 14 | - https://lingva.ml - Default 15 | - https://translate.catswords.net - Asia (South Korea), Last checked on November 11, 2024 (***Please check***: [Terms of Service](https://policy.catswords.social/site_extended_description_EN.html) and [Privacy Policy](https://policy.catswords.social/site_terms_EN.html)) 16 | 17 | ## Requirements 18 | - PotPlayer - https://potplayer.daum.net/ 19 | - Lingva Translate - https://github.com/thedaviddelta/lingva-translate 20 | 21 | ## Report abuse 22 | - abuse@catswords.re.kr 23 | - [GitHub Security Advisories (gnh1201/potplayer-lingva)](https://github.com/gnh1201/potplayer-lingva/security) 24 | 25 | ## Join the community 26 | - ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss) 27 | - [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI) 28 | - [Join Catswords OSS #potplayer-lingva on Discord (discord.gg)](https://discord.gg/zmQW5MtjcC) 29 | -------------------------------------------------------------------------------- /SubtitleTranslate - lingva.as: -------------------------------------------------------------------------------- 1 | /* 2 | real time subtitle translate for PotPlayer using Lingva (Google alternative front-end) API 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 JsonParseV1(string json) 22 | { 23 | JsonReader Reader; 24 | JsonValue Root; 25 | string ret = ""; 26 | 27 | if (Reader.parse(json, Root) && Root.isObject()) { 28 | JsonValue translation = Root["translation"]; 29 | if (translation.isString()) ret = translation.asString(); 30 | HostPrintUTF8("(f: JsonParseV1) ret: " + ret);// for debug print 31 | } 32 | 33 | return ret; 34 | } 35 | 36 | array LangTable = 37 | { 38 | "af", 39 | "sq", 40 | "am", 41 | "ar", 42 | "hy", 43 | "az", 44 | "eu", 45 | "be", 46 | "bn", 47 | "bs", 48 | "bg", 49 | "my", 50 | "ca", 51 | "ceb", 52 | "ny", 53 | "zh", 54 | "zh-CN", 55 | "zh-TW", 56 | "co", 57 | "hr", 58 | "cs", 59 | "da", 60 | "nl", 61 | "en", 62 | "eo", 63 | "et", 64 | "tl", 65 | "fi", 66 | "fr", 67 | "fy", 68 | "gl", 69 | "ka", 70 | "de", 71 | "el", 72 | "gu", 73 | "ht", 74 | "ha", 75 | "haw", 76 | "iw", 77 | "hi", 78 | "hmn", 79 | "hu", 80 | "is", 81 | "ig", 82 | "id", 83 | "ga", 84 | "it", 85 | "ja", 86 | "jw", 87 | "kn", 88 | "kk", 89 | "km", 90 | "ko", 91 | "ku", 92 | "ky", 93 | "lo", 94 | "la", 95 | "lv", 96 | "lt", 97 | "lb", 98 | "mk", 99 | "ms", 100 | "mg", 101 | "ml", 102 | "mt", 103 | "mi", 104 | "mr", 105 | "mn", 106 | "my", 107 | "ne", 108 | "no", 109 | "ps", 110 | "fa", 111 | "pl", 112 | "pt", 113 | "pa", 114 | "ro", 115 | "romanji", 116 | "ru", 117 | "sm", 118 | "gd", 119 | "sr", 120 | "st", 121 | "sn", 122 | "sd", 123 | "si", 124 | "sk", 125 | "sl", 126 | "so", 127 | "es", 128 | "su", 129 | "sw", 130 | "sv", 131 | "tg", 132 | "ta", 133 | "te", 134 | "th", 135 | "tr", 136 | "uk", 137 | "ur", 138 | "uz", 139 | "vi", 140 | "cy", 141 | "xh", 142 | "yi", 143 | "yo", 144 | "zu" 145 | }; 146 | 147 | string UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"; 148 | 149 | 150 | string GetTitle() 151 | { 152 | return "{$CP949=링바(구글) 번역$}{$CP950=Lingva(Google) 翻譯$}{$CP0=Lingva(Google) translate$}"; 153 | } 154 | 155 | string GetVersion() 156 | { 157 | return "1"; 158 | } 159 | 160 | string GetDesc() 161 | { 162 | return "https://github.com/gnh1201/potplayer-lingva"; 163 | } 164 | 165 | string GetLoginTitle() 166 | { 167 | return ""; 168 | } 169 | 170 | string GetLoginDesc() 171 | { 172 | return ""; 173 | } 174 | 175 | string GetUserText() 176 | { 177 | return "Server URL:"; 178 | } 179 | 180 | string GetPasswordText() 181 | { 182 | return ""; 183 | } 184 | 185 | string server_url; 186 | 187 | string ServerLogin(string User, string Pass) 188 | { 189 | //HostOpenConsole(); // for debug 190 | 191 | string text; 192 | int start_pos; 193 | server_url = User; 194 | if (server_url.empty()) 195 | { 196 | string[] server_urls = { 197 | "https://translate.catswords.net", 198 | "https://translate.plausibility.cloud", 199 | "https://translate.alxserver.de", 200 | "https://translate.abrendan.dev", 201 | "https://lingva.dialectapp.org", 202 | "https://translate.sphererapids.com", 203 | "https://salucyr69.synology.me:6455", 204 | "https://translater.perfectpurple.top", 205 | "https://translate.palmasolutions.net", 206 | "https://nyc1.lv.ggtyler.dev", 207 | "https://lingva.sharktale.xyz", 208 | "https://translate.gururaja.in", 209 | "https://lingva.steel77.ddnss.de", 210 | "https://translate.mnsr.net", 211 | "https://lingva.privacytools.click", 212 | "https://lingva.adminforge.de", 213 | "https://fanyi.qz.ci", 214 | "https://lingva.seasi.dev", 215 | "https://lingva.lunar.icu", 216 | "https://translate.nexo.moe", 217 | "https://translate.ssnc.uk", 218 | "https://lingva.ml" 219 | }; 220 | 221 | for (uint i = 0; i < server_urls.length(); i++) { 222 | server_url = server_urls[i]; 223 | 224 | string text = HostUrlGetString(server_url + "/api/v1/en/ko/hello", UserAgent); 225 | HostPrintUTF8("(f: ServerLogin) url: " + server_url + ", text: " + text); // for debug print 226 | 227 | int start_pos = text.findFirst("translation", 0); 228 | if (start_pos > 0) { 229 | return "200 ok"; 230 | } 231 | } 232 | } 233 | 234 | return "200 ok"; 235 | } 236 | 237 | void ServerLogout() 238 | { 239 | server_url = ""; 240 | } 241 | 242 | array GetSrcLangs() 243 | { 244 | array ret = LangTable; 245 | 246 | ret.insertAt(0, ""); // empty is auto 247 | return ret; 248 | } 249 | 250 | array GetDstLangs() 251 | { 252 | array ret = LangTable; 253 | 254 | return ret; 255 | } 256 | 257 | string Translate(string Text, string &in SrcLang, string &in DstLang) 258 | { 259 | //HostOpenConsole(); // for debug 260 | 261 | SrcLang.replace("zh-CN", "zh"); 262 | SrcLang.replace("zh-TW", "zh"); 263 | DstLang.replace("zh-CN", "zh"); 264 | DstLang.replace("zh-TW", "zh"); 265 | 266 | if (SrcLang.length() <= 0) SrcLang = "auto"; 267 | SrcLang.MakeLower(); 268 | 269 | string enc = HostUrlEncode(Text); 270 | string url = server_url + "/api/v1/" + SrcLang + "/" + DstLang + "/" + enc; 271 | string text = HostUrlGetString(url, UserAgent); 272 | HostPrintUTF8("(f: Translate) url: " + url + ", text:" + text); // for debug print 273 | 274 | string ret = JsonParseV1(text); 275 | if (ret.length() > 0) 276 | { 277 | SrcLang = "UTF8"; 278 | DstLang = "UTF8"; 279 | return ret; 280 | } 281 | 282 | return ret; 283 | } 284 | --------------------------------------------------------------------------------