added open in mpv on anime for electron ver
This commit is contained in:
@@ -10,10 +10,12 @@ const AnimePlayer = (function() {
|
||||
let _skipIntervals = [];
|
||||
let _progressUpdated = false;
|
||||
|
||||
// Variables nuevas para RPC
|
||||
let _animeTitle = "Anime";
|
||||
let _rpcActive = false;
|
||||
|
||||
let _rawVideoData = null;
|
||||
let _currentSubtitles = [];
|
||||
|
||||
let _localEntryId = null;
|
||||
let _totalEpisodes = 0;
|
||||
|
||||
@@ -31,7 +33,8 @@ const AnimePlayer = (function() {
|
||||
subDubToggle: null,
|
||||
epTitle: null,
|
||||
prevBtn: null,
|
||||
nextBtn: null
|
||||
nextBtn: null,
|
||||
mpvBtn: null
|
||||
};
|
||||
|
||||
function init(animeId, initialSource, isLocal, animeData) {
|
||||
@@ -40,10 +43,8 @@ const AnimePlayer = (function() {
|
||||
_isLocal = isLocal;
|
||||
_malId = animeData.idMal || null;
|
||||
|
||||
// Guardar total de episodios
|
||||
_totalEpisodes = animeData.episodes || 1000;
|
||||
|
||||
// Extraer título para RPC (Lógica traída de player.js)
|
||||
if (animeData.title) {
|
||||
_animeTitle = animeData.title.romaji || animeData.title.english || animeData.title.native || animeData.title || "Anime";
|
||||
}
|
||||
@@ -51,13 +52,15 @@ const AnimePlayer = (function() {
|
||||
_skipIntervals = [];
|
||||
_localEntryId = null;
|
||||
|
||||
// --- REFERENCIAS DOM ---
|
||||
els.wrapper = document.getElementById('hero-wrapper');
|
||||
els.playerWrapper = document.getElementById('player-wrapper');
|
||||
els.video = document.getElementById('player');
|
||||
els.loader = document.getElementById('player-loading');
|
||||
els.loaderText = document.getElementById('player-loading-text');
|
||||
|
||||
els.mpvBtn = document.getElementById('mpv-btn');
|
||||
if (els.mpvBtn) els.mpvBtn.addEventListener('click', openInMPV);
|
||||
|
||||
els.serverSelect = document.getElementById('server-select');
|
||||
els.extSelect = document.getElementById('extension-select');
|
||||
els.subDubToggle = document.getElementById('sd-toggle');
|
||||
@@ -69,11 +72,9 @@ const AnimePlayer = (function() {
|
||||
const closeBtn = document.getElementById('close-player-btn');
|
||||
if(closeBtn) closeBtn.addEventListener('click', closePlayer);
|
||||
|
||||
// Configuración de navegación
|
||||
if(els.prevBtn) els.prevBtn.addEventListener('click', () => playEpisode(_currentEpisode - 1));
|
||||
if(els.nextBtn) els.nextBtn.addEventListener('click', () => playEpisode(_currentEpisode + 1));
|
||||
|
||||
// Botón Flotante (Skip)
|
||||
if (!document.getElementById('skip-overlay-btn')) {
|
||||
const btn = document.createElement('button');
|
||||
btn.id = 'skip-overlay-btn';
|
||||
@@ -85,7 +86,6 @@ const AnimePlayer = (function() {
|
||||
}
|
||||
if(_skipBtn) _skipBtn.onclick = () => handleOverlayClick();
|
||||
|
||||
// Listeners Controles
|
||||
if(els.subDubToggle) els.subDubToggle.addEventListener('click', toggleAudioMode);
|
||||
if(els.serverSelect) els.serverSelect.addEventListener('change', () => loadStream());
|
||||
if(els.extSelect) els.extSelect.addEventListener('change', () => handleExtensionChange(true));
|
||||
@@ -93,7 +93,51 @@ const AnimePlayer = (function() {
|
||||
loadExtensionsList();
|
||||
}
|
||||
|
||||
// --- FUNCIÓN RPC (Integrada desde player.js) ---
|
||||
async function openInMPV() {
|
||||
if (!_rawVideoData) {
|
||||
alert("No video loaded yet.");
|
||||
return;
|
||||
}
|
||||
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) {
|
||||
alert("You need to be logged in.");
|
||||
return;
|
||||
}
|
||||
const body = {
|
||||
title: `${_animeTitle} - Episode ${_currentEpisode}`,
|
||||
video: _rawVideoData,
|
||||
subtitles: _currentSubtitles,
|
||||
chapters: _skipIntervals,
|
||||
animeId: _animeId,
|
||||
episode: _currentEpisode,
|
||||
entrySource: _entrySource,
|
||||
token: localStorage.getItem('token')
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/watch/mpv', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
console.log("MPV Request Sent");
|
||||
closePlayer();
|
||||
} else {
|
||||
console.error("MPV Request Failed");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("MPV Error:", e);
|
||||
} finally {
|
||||
if(els.mpvBtn) {
|
||||
els.mpvBtn.innerHTML = originalContent;
|
||||
els.mpvBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendRPC({ startTimestamp, endTimestamp, paused = false } = {}) {
|
||||
fetch("/api/rpc", {
|
||||
method: "POST",
|
||||
@@ -158,7 +202,6 @@ const AnimePlayer = (function() {
|
||||
const trailer = document.querySelector('#trailer-player iframe');
|
||||
if(trailer) trailer.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
|
||||
|
||||
// Reset RPC state on new episode
|
||||
_rpcActive = false;
|
||||
|
||||
if (els.extSelect.value === 'local') {
|
||||
@@ -185,7 +228,6 @@ const AnimePlayer = (function() {
|
||||
_skipIntervals = [];
|
||||
_rpcActive = false;
|
||||
|
||||
// Enviar señal de pausa o limpieza al cerrar
|
||||
sendRPC({ paused: true });
|
||||
|
||||
const newUrl = new URL(window.location);
|
||||
@@ -294,6 +336,9 @@ const AnimePlayer = (function() {
|
||||
_progressUpdated = false;
|
||||
setLoading("Fetching Stream...");
|
||||
|
||||
_rawVideoData = null;
|
||||
_currentSubtitles = [];
|
||||
|
||||
if (hlsInstance) { hlsInstance.destroy(); hlsInstance = null; }
|
||||
|
||||
const currentExt = els.extSelect.value;
|
||||
@@ -306,6 +351,13 @@ const AnimePlayer = (function() {
|
||||
return;
|
||||
}
|
||||
const localUrl = `/api/library/stream/anime/${localId}/${_currentEpisode}`;
|
||||
|
||||
_rawVideoData = {
|
||||
url: window.location.origin + localUrl,
|
||||
headers: {}
|
||||
};
|
||||
_currentSubtitles = [];
|
||||
|
||||
initVideoPlayer(localUrl, 'mp4');
|
||||
} catch(e) {
|
||||
setLoading("Local Error: " + e.message);
|
||||
@@ -330,6 +382,11 @@ const AnimePlayer = (function() {
|
||||
const source = data.videoSources.find(s => s.type === 'm3u8') || data.videoSources[0];
|
||||
const headers = data.headers || {};
|
||||
|
||||
_rawVideoData = {
|
||||
url: source.url,
|
||||
headers: headers
|
||||
};
|
||||
|
||||
let proxyUrl = `/api/proxy?url=${encodeURIComponent(source.url)}`;
|
||||
if (headers['Referer'] && headers['Referer'] !== "null") proxyUrl += `&referer=${encodeURIComponent(headers['Referer'])}`;
|
||||
if (headers['User-Agent']) proxyUrl += `&userAgent=${encodeURIComponent(headers['User-Agent'])}`;
|
||||
@@ -340,6 +397,12 @@ const AnimePlayer = (function() {
|
||||
src: `/api/proxy?url=${encodeURIComponent(sub.url)}`
|
||||
}));
|
||||
|
||||
_currentSubtitles = (source.subtitles || []).map(sub => ({
|
||||
label: sub.language,
|
||||
srclang: sub.id,
|
||||
src: sub.url
|
||||
}));
|
||||
|
||||
initVideoPlayer(proxyUrl, source.type, subtitles);
|
||||
} catch (err) {
|
||||
setLoading("Stream Error: " + err.message);
|
||||
@@ -350,17 +413,10 @@ const AnimePlayer = (function() {
|
||||
const video = els.video;
|
||||
Array.from(video.querySelectorAll('track')).forEach(t => t.remove());
|
||||
|
||||
// Limpiar listeners de video antiguos para evitar duplicados en RPC
|
||||
const newVideo = video.cloneNode(true);
|
||||
video.parentNode.replaceChild(newVideo, video);
|
||||
els.video = newVideo;
|
||||
// Nota: Al clonar perdemos referencia en 'els', hay que reasignar
|
||||
// Sin embargo, clonar rompe Plyr si no se tiene cuidado.
|
||||
// Mejor estrategia: Remover listeners específicos si fuera posible,
|
||||
// pero dado que son anónimos, la clonación es efectiva si reinicializamos todo.
|
||||
// Como initPlyr se llama después, esto funciona.
|
||||
|
||||
// --- INYECCIÓN DE EVENTOS RPC ---
|
||||
els.video.addEventListener("play", () => {
|
||||
if (!els.video.duration) return;
|
||||
const elapsed = Math.floor(els.video.currentTime);
|
||||
@@ -381,7 +437,6 @@ const AnimePlayer = (function() {
|
||||
const end = start + Math.floor(els.video.duration);
|
||||
sendRPC({ startTimestamp: start, endTimestamp: end });
|
||||
});
|
||||
// -------------------------------
|
||||
|
||||
if (Hls.isSupported() && (type === 'm3u8' || url.includes('.m3u8'))) {
|
||||
hlsInstance = new Hls();
|
||||
@@ -430,7 +485,7 @@ const AnimePlayer = (function() {
|
||||
}
|
||||
|
||||
function initPlyr() {
|
||||
// Asegurarnos de usar el elemento video actualizado
|
||||
|
||||
if (plyrInstance) return;
|
||||
|
||||
plyrInstance = new Plyr(els.video, {
|
||||
|
||||
Reference in New Issue
Block a user