Created
June 13, 2026 17:27
-
-
Save dEN5-tech/4dae13913dff8a66ac20583c6317ad51 to your computer and use it in GitHub Desktop.
mpv-lampa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function () { | |
| 'use strict'; | |
| Lampa.Lang.add({ | |
| mpv_integration_title: { | |
| ru: 'Интеграция MPV', | |
| en: 'MPV Integration', | |
| uk: 'Інтеграція MPV' | |
| }, | |
| mpv_integration_descr: { | |
| ru: 'Использовать внешний плеер MPV с поддержкой плейлистов M3U8', | |
| en: 'Use external MPV player with M3U8 playlists support', | |
| uk: 'Використовувати зовнішній плеєр MPV з підтримкою плейлистів M3U8' | |
| }, | |
| mpv_integration_mode_title: { | |
| ru: 'Режим MPV', | |
| en: 'MPV Mode', | |
| uk: 'Режим MPV' | |
| }, | |
| mpv_integration_mode_descr: { | |
| ru: 'Способ запуска плеера MPV', | |
| en: 'How to launch the MPV player', | |
| uk: 'Спосіб запуску плеєра MPV' | |
| }, | |
| mpv_integration_enabled: { | |
| ru: 'Включена', | |
| en: 'Enabled', | |
| uk: 'Увімкнена' | |
| }, | |
| mpv_integration_disabled: { | |
| ru: 'Выключена', | |
| en: 'Disabled', | |
| uk: 'Вимкнена' | |
| }, | |
| mpv_noty_sent: { | |
| ru: 'Плейлист отправлен в MPV', | |
| en: 'Playlist sent to MPV', | |
| uk: 'Плейлист відправлений в MPV' | |
| }, | |
| mpv_noty_error: { | |
| ru: 'Ошибка воспроизведения в MPV', | |
| en: 'Playback error in MPV', | |
| uk: 'Помилка відтворення в MPV' | |
| }, | |
| mpv_noty_conn_error: { | |
| ru: 'Не удалось связаться с сервером Lampac', | |
| en: 'Failed to connect to Lampac server', | |
| uk: 'Не вдалося зв\'язатися з сервером Lampac' | |
| } | |
| }); | |
| var Defined = { | |
| localhost: '{localhost}' | |
| }; | |
| function startPlugin() { | |
| console.log('MPV Integration: Plugin initialized.'); | |
| // Monkey-patch Lampa.Player.play and Lampa.Player.playlist | |
| var currentElement = null; | |
| var originalPlay = Lampa.Player.play; | |
| var originalPlaylist = Lampa.Player.playlist; | |
| Lampa.Player.play = function (element) { | |
| currentElement = element; | |
| if (Lampa.Storage.get('mpv_integration_enabled', 'false') === 'true') { | |
| setTimeout(function () { | |
| if (currentElement) { | |
| playInMpv(currentElement); | |
| currentElement = null; | |
| } | |
| }, 50); | |
| return; | |
| } | |
| originalPlay.apply(this, arguments); | |
| }; | |
| Lampa.Player.playlist = function (playlist) { | |
| if (Lampa.Storage.get('mpv_integration_enabled', 'false') === 'true') { | |
| if (currentElement) { | |
| currentElement.playlist = playlist; | |
| } | |
| return; | |
| } | |
| originalPlaylist.apply(this, arguments); | |
| }; | |
| function playInMpv(element) { | |
| var playlistItems = []; | |
| var index = 0; | |
| if (element.playlist && element.playlist.length > 0) { | |
| playlistItems = element.playlist; | |
| index = playlistItems.findIndex(function (item) { | |
| return item.url === element.url || item.title === element.title; | |
| }); | |
| if (index < 0) index = 0; | |
| } else { | |
| playlistItems = [element]; | |
| index = 0; | |
| } | |
| Lampa.Loading.start(function () { | |
| Lampa.Loading.stop(); | |
| }); | |
| var payload = { | |
| index: index, | |
| playlist: playlistItems.map(function (item, i) { | |
| return { | |
| title: item.title || element.title || ('Episode ' + (i + 1)), | |
| url: item.url | |
| }; | |
| }) | |
| }; | |
| $.ajax({ | |
| url: Defined.localhost + '/player-inner/playlist', | |
| type: 'POST', | |
| contentType: 'application/json', | |
| data: JSON.stringify(payload), | |
| success: function (response) { | |
| Lampa.Loading.stop(); | |
| if (response.success) { | |
| var mode = Lampa.Storage.get('mpv_integration_mode', 'local'); | |
| if (mode === 'local') { | |
| $.get(Defined.localhost + '/player-inner/play-playlist?id=' + response.id + '&index=' + response.index); | |
| Lampa.Noty.show(Lampa.Lang.translate('mpv_noty_sent')); | |
| } else if (mode === 'intent') { | |
| var intentUrl = 'intent:' + encodeURIComponent(response.url) + '#Intent;package=is.xyz.mpv;type=video/*;end'; | |
| window.location.href = intentUrl; | |
| } else if (mode === 'scheme') { | |
| var schemeUrl = 'mpv://' + response.url; | |
| window.location.href = schemeUrl; | |
| } | |
| } else { | |
| Lampa.Noty.show(Lampa.Lang.translate('mpv_noty_error')); | |
| } | |
| }, | |
| error: function () { | |
| Lampa.Loading.stop(); | |
| Lampa.Noty.show(Lampa.Lang.translate('mpv_noty_conn_error')); | |
| } | |
| }); | |
| } | |
| // Add settings panel options | |
| Lampa.Settings.listener.follow('open', function (e) { | |
| if (e.name == 'player') { | |
| var body = e.body; | |
| if (!body.find('[data-parent="mpv_integration"]').length) { | |
| var html = $('<div class="settings-param selector" data-parent="mpv_integration" data-type="select">\n' + | |
| '<div class="settings-param__name">' + Lampa.Lang.translate('mpv_integration_title') + '</div>\n' + | |
| '<div class="settings-param__value">Выключена</div>\n' + | |
| '<div class="settings-param__descr">' + Lampa.Lang.translate('mpv_integration_descr') + '</div>\n' + | |
| '</div>'); | |
| var val = Lampa.Storage.get('mpv_integration_enabled', 'false'); | |
| html.find('.settings-param__value').text(val === 'true' ? Lampa.Lang.translate('mpv_integration_enabled') : Lampa.Lang.translate('mpv_integration_disabled')); | |
| html.on('hover:enter', function () { | |
| var current = Lampa.Storage.get('mpv_integration_enabled', 'false'); | |
| var next = current === 'true' ? 'false' : 'true'; | |
| Lampa.Storage.set('mpv_integration_enabled', next); | |
| html.find('.settings-param__value').text(next === 'true' ? Lampa.Lang.translate('mpv_integration_enabled') : Lampa.Lang.translate('mpv_integration_disabled')); | |
| }); | |
| var modeHtml = $('<div class="settings-param selector" data-parent="mpv_integration_mode" data-type="select">\n' + | |
| '<div class="settings-param__name">' + Lampa.Lang.translate('mpv_integration_mode_title') + '</div>\n' + | |
| '<div class="settings-param__value">Локальный (Lampac)</div>\n' + | |
| '<div class="settings-param__descr">' + Lampa.Lang.translate('mpv_integration_mode_descr') + '</div>\n' + | |
| '</div>'); | |
| var mode = Lampa.Storage.get('mpv_integration_mode', 'local'); | |
| var modeNames = { | |
| 'local': { ru: 'Локальный (Lampac)', en: 'Local (Lampac)', uk: 'Локальний (Lampac)' }, | |
| 'intent': { ru: 'Android Intent', en: 'Android Intent', uk: 'Android Intent' }, | |
| 'scheme': { ru: 'Протокол (mpv://)', en: 'Protocol (mpv://)', uk: 'Протокол (mpv://)' } | |
| }; | |
| var getModeName = function (m) { | |
| var lang = Lampa.Storage.get('language', 'ru'); | |
| if (!modeNames[m]) m = 'local'; | |
| return modeNames[m][lang] || modeNames[m]['en'] || modeNames[m]['ru']; | |
| }; | |
| modeHtml.find('.settings-param__value').text(getModeName(mode)); | |
| modeHtml.on('hover:enter', function () { | |
| var currentMode = Lampa.Storage.get('mpv_integration_mode', 'local'); | |
| var modes = ['local', 'intent', 'scheme']; | |
| var nextIndex = (modes.indexOf(currentMode) + 1) % modes.length; | |
| var nextMode = modes[nextIndex]; | |
| Lampa.Storage.set('mpv_integration_mode', nextMode); | |
| modeHtml.find('.settings-param__value').text(getModeName(nextMode)); | |
| }); | |
| body.append(html); | |
| body.append(modeHtml); | |
| Lampa.Controller.updateFormat(body); | |
| } | |
| } | |
| }); | |
| } | |
| if (window.appready) { | |
| startPlugin(); | |
| } else { | |
| Lampa.Listener.follow('app', function (e) { | |
| if (e.type == 'ready') { | |
| startPlugin(); | |
| } | |
| }); | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment