PRISMA revised this gist . Go to revision
1 file changed, 133 insertions
OnlineBase.js(file created)
| @@ -0,0 +1,133 @@ | |||
| 1 | + | (function () { | |
| 2 | + | 'use strict'; | |
| 3 | + | ||
| 4 | + | var network = new Lampa.Reguest(); | |
| 5 | + | var filmixHost = 'https://filmix.ac'; // Основной хост Filmix (может измениться, используйте зеркала) | |
| 6 | + | var collapsHost = 'https://collaps.org'; // Хост для embeds Collaps | |
| 7 | + | ||
| 8 | + | // Утилиты | |
| 9 | + | function proxy(url) { | |
| 10 | + | // Простой прокси для CORS (можно использовать ваш или встроенный Lampa) | |
| 11 | + | return Lampa.Proxy.cors(url); | |
| 12 | + | } | |
| 13 | + | ||
| 14 | + | function cleanTitle(title) { | |
| 15 | + | return title.replace(/[^a-zA-Z0-9 ]/g, '').toLowerCase(); | |
| 16 | + | } | |
| 17 | + | ||
| 18 | + | // Провайдер для Filmix | |
| 19 | + | var filmixProvider = { | |
| 20 | + | search: function (query, callback, error) { | |
| 21 | + | var url = proxy(filmixHost + '/search?query=' + encodeURIComponent(query)); | |
| 22 | + | network.silent(url, function (data) { | |
| 23 | + | // Парсинг HTML результатов поиска (пример: извлечение ссылок на фильмы/сериалы) | |
| 24 | + | var results = []; | |
| 25 | + | // Предполагаем, что data - HTML, парсим с помощью DOMParser | |
| 26 | + | var parser = new DOMParser(); | |
| 27 | + | var doc = parser.parseFromString(data, 'text/html'); | |
| 28 | + | $(doc).find('.film-item').each(function () { | |
| 29 | + | var item = $(this); | |
| 30 | + | var title = item.find('.title').text(); | |
| 31 | + | var year = item.find('.year').text(); | |
| 32 | + | var link = filmixHost + item.find('a').attr('href'); | |
| 33 | + | results.push({ | |
| 34 | + | title: title, | |
| 35 | + | year: year, | |
| 36 | + | url: link | |
| 37 | + | }); | |
| 38 | + | }); | |
| 39 | + | callback(results); | |
| 40 | + | }, error); | |
| 41 | + | }, | |
| 42 | + | getStreams: function (url, callback, error) { | |
| 43 | + | network.silent(proxy(url), function (data) { | |
| 44 | + | // Извлечение embed из Filmix (обычно iframe с Collaps) | |
| 45 | + | var embedUrl = $(data).find('iframe[src*="collaps"]').attr('src'); | |
| 46 | + | if (embedUrl) { | |
| 47 | + | getCollapsStreams(embedUrl, callback, error); | |
| 48 | + | } else { | |
| 49 | + | error('No embed found'); | |
| 50 | + | } | |
| 51 | + | }, error); | |
| 52 | + | } | |
| 53 | + | }; | |
| 54 | + | ||
| 55 | + | // Провайдер для Collaps (извлечение потоков из embed) | |
| 56 | + | function getCollapsStreams(url, callback, error) { | |
| 57 | + | network.silent(proxy(url), function (data) { | |
| 58 | + | // Парсинг JS из embed для потоков (HLS/M3U8 или MP4) | |
| 59 | + | var streams = []; | |
| 60 | + | // Пример: поиск в скрипте плейлиста | |
| 61 | + | var script = $(data).find('script').text(); | |
| 62 | + | var m3uMatch = script.match(/file:"([^"]+)"/); | |
| 63 | + | if (m3uMatch) { | |
| 64 | + | var m3uUrl = m3uMatch[1]; | |
| 65 | + | // Разбор M3U для качеств | |
| 66 | + | network.silent(proxy(m3uUrl), function (m3uData) { | |
| 67 | + | var lines = m3uData.split('\n'); | |
| 68 | + | for (var i = 0; i < lines.length; i++) { | |
| 69 | + | if (lines[i].startsWith('#EXT-X-STREAM-INF')) { | |
| 70 | + | var quality = lines[i].match(/RESOLUTION=\d+x(\d+)/)[1]; | |
| 71 | + | var file = lines[i+1]; | |
| 72 | + | streams.push({ | |
| 73 | + | quality: quality + 'p', | |
| 74 | + | url: file | |
| 75 | + | }); | |
| 76 | + | } | |
| 77 | + | } | |
| 78 | + | callback(streams); | |
| 79 | + | }, error); | |
| 80 | + | } else { | |
| 81 | + | error('No streams found'); | |
| 82 | + | } | |
| 83 | + | }, error); | |
| 84 | + | } | |
| 85 | + | ||
| 86 | + | // Компонент для Lampa | |
| 87 | + | function component(object) { | |
| 88 | + | var comp = Lampa.Component.create('online_services', object); | |
| 89 | + | ||
| 90 | + | comp.search = function (query) { | |
| 91 | + | filmixProvider.search(query, function (results) { | |
| 92 | + | comp.render(results); | |
| 93 | + | }, function (err) { | |
| 94 | + | Lampa.Noty.show('Ошибка поиска: ' + err); | |
| 95 | + | }); | |
| 96 | + | }; | |
| 97 | + | ||
| 98 | + | comp.getStream = function (item, call) { | |
| 99 | + | filmixProvider.getStreams(item.url, function (streams) { | |
| 100 | + | var playlist = streams.map(function (s) { | |
| 101 | + | return { | |
| 102 | + | title: s.quality, | |
| 103 | + | url: s.url | |
| 104 | + | }; | |
| 105 | + | }); | |
| 106 | + | call({ playlist: playlist }); | |
| 107 | + | }, function (err) { | |
| 108 | + | Lampa.Noty.show('Ошибка загрузки потоков: ' + err); | |
| 109 | + | }); | |
| 110 | + | }; | |
| 111 | + | ||
| 112 | + | // Фильтры и UI | |
| 113 | + | comp.filter = function () { | |
| 114 | + | // Добавьте сезоны/озвучки, если нужно | |
| 115 | + | return { | |
| 116 | + | seasons: [], | |
| 117 | + | voices: [] | |
| 118 | + | }; | |
| 119 | + | }; | |
| 120 | + | ||
| 121 | + | return comp; | |
| 122 | + | } | |
| 123 | + | ||
| 124 | + | // Инициализация плагина | |
| 125 | + | function init() { | |
| 126 | + | Lampa.Component.add('online_services', component); | |
| 127 | + | Lampa.Template.add('online_services_folder', '<div class="online-services-folder"></div>'); | |
| 128 | + | // Добавьте другие шаблоны по необходимости | |
| 129 | + | } | |
| 130 | + | ||
| 131 | + | if (window.appready) init(); | |
| 132 | + | else Lampa.Listener.follow('app', function (e) { if (e.type == 'ready') init(); }); | |
| 133 | + | })(); | |
Newer
Older