nekostream 2026.2.1 → 2026.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/player-main.js +22 -7
- package/player.html +123 -48
package/package.json
CHANGED
package/player-main.js
CHANGED
|
@@ -4,13 +4,28 @@ const path = require('path')
|
|
|
4
4
|
|
|
5
5
|
let mainWindow = null
|
|
6
6
|
|
|
7
|
-
function logToRenderer(msg) {
|
|
8
|
-
if (mainWindow && !mainWindow.isDestroyed() && mainWindow.webContents) {
|
|
9
|
-
mainWindow.webContents.send('main-log', msg);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
function logToRenderer(msg) {
|
|
8
|
+
if (mainWindow && !mainWindow.isDestroyed() && mainWindow.webContents) {
|
|
9
|
+
mainWindow.webContents.send('main-log', msg);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
ipcMain.on('player:minimize', () => {
|
|
14
|
+
if (mainWindow && !mainWindow.isDestroyed()) {
|
|
15
|
+
mainWindow.minimize()
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
ipcMain.on('player:toggle-maximize', () => {
|
|
20
|
+
if (!mainWindow || mainWindow.isDestroyed()) return
|
|
21
|
+
if (mainWindow.isMaximized()) {
|
|
22
|
+
mainWindow.unmaximize()
|
|
23
|
+
} else {
|
|
24
|
+
mainWindow.maximize()
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
function createWindow() {
|
|
14
29
|
const streamData = process.env.NEKOSTREAM_CLI_STREAM
|
|
15
30
|
if (!streamData) {
|
|
16
31
|
console.error('No stream data provided.')
|
package/player.html
CHANGED
|
@@ -14,48 +14,107 @@
|
|
|
14
14
|
overflow: hidden;
|
|
15
15
|
font-family: sans-serif;
|
|
16
16
|
}
|
|
17
|
-
#player-container {
|
|
18
|
-
width: 100%;
|
|
19
|
-
height: 100%;
|
|
20
|
-
}
|
|
17
|
+
#player-container {
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
}
|
|
21
21
|
webview {
|
|
22
22
|
width: 100%;
|
|
23
23
|
height: 100%;
|
|
24
24
|
border: none;
|
|
25
25
|
}
|
|
26
|
-
#
|
|
27
|
-
position: absolute;
|
|
28
|
-
top:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
right:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
26
|
+
#top-nav {
|
|
27
|
+
position: absolute;
|
|
28
|
+
top: 0;
|
|
29
|
+
left: 0;
|
|
30
|
+
right: 0;
|
|
31
|
+
height: 34px;
|
|
32
|
+
z-index: 10000;
|
|
33
|
+
background: transparent;
|
|
34
|
+
-webkit-app-region: drag;
|
|
35
|
+
user-select: none;
|
|
36
|
+
pointer-events: auto;
|
|
37
|
+
}
|
|
38
|
+
.window-controls {
|
|
39
|
+
position: absolute;
|
|
40
|
+
top: 8px;
|
|
41
|
+
right: 10px;
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: row-reverse;
|
|
44
|
+
align-items: center;
|
|
45
|
+
gap: 0;
|
|
46
|
+
min-width: 28px;
|
|
47
|
+
height: 28px;
|
|
48
|
+
pointer-events: auto;
|
|
49
|
+
-webkit-app-region: no-drag;
|
|
50
|
+
}
|
|
51
|
+
.window-dot {
|
|
52
|
+
width: 12px;
|
|
53
|
+
height: 12px;
|
|
54
|
+
padding: 0;
|
|
55
|
+
border: 1px solid rgba(255, 255, 255, 0.58);
|
|
56
|
+
border-radius: 999px;
|
|
57
|
+
background: rgba(255, 255, 255, 0.86);
|
|
58
|
+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.45);
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
transition: transform 0.18s ease, background 0.18s ease, border-color 0.18s ease;
|
|
61
|
+
}
|
|
62
|
+
.window-controls:hover .window-dot,
|
|
63
|
+
.window-controls:focus-within .window-dot {
|
|
64
|
+
transform: scale(0.74);
|
|
65
|
+
background: rgba(255, 255, 255, 0.55);
|
|
66
|
+
border-color: rgba(255, 255, 255, 0.75);
|
|
67
|
+
}
|
|
68
|
+
.window-btn {
|
|
69
|
+
width: 0;
|
|
70
|
+
height: 28px;
|
|
71
|
+
margin-right: 0;
|
|
72
|
+
padding: 0;
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
border: 0;
|
|
77
|
+
border-radius: 999px;
|
|
78
|
+
background: rgba(8, 12, 20, 0.58);
|
|
79
|
+
color: rgba(255, 255, 255, 0.82);
|
|
80
|
+
backdrop-filter: blur(10px);
|
|
81
|
+
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.38);
|
|
82
|
+
font-size: 14px;
|
|
83
|
+
line-height: 1;
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
opacity: 0;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
transform: translateX(12px) scale(0.82);
|
|
88
|
+
transition: width 0.2s ease, margin-right 0.2s ease, opacity 0.16s ease, transform 0.2s ease, background 0.15s ease, color 0.15s ease;
|
|
89
|
+
}
|
|
90
|
+
.window-controls:hover .window-btn,
|
|
91
|
+
.window-controls:focus-within .window-btn {
|
|
92
|
+
width: 28px;
|
|
93
|
+
margin-right: 7px;
|
|
94
|
+
opacity: 1;
|
|
95
|
+
transform: translateX(0) scale(1);
|
|
96
|
+
}
|
|
97
|
+
.window-controls:hover #window-minimize,
|
|
98
|
+
.window-controls:focus-within #window-minimize {
|
|
99
|
+
transition-delay: 0.02s;
|
|
100
|
+
}
|
|
101
|
+
.window-controls:hover #window-maximize,
|
|
102
|
+
.window-controls:focus-within #window-maximize {
|
|
103
|
+
transition-delay: 0.05s;
|
|
104
|
+
}
|
|
105
|
+
.window-controls:hover #window-close,
|
|
106
|
+
.window-controls:focus-within #window-close {
|
|
107
|
+
transition-delay: 0.08s;
|
|
108
|
+
}
|
|
109
|
+
.window-btn:hover {
|
|
110
|
+
background: rgba(255, 255, 255, 0.18);
|
|
111
|
+
color: #fff;
|
|
112
|
+
}
|
|
113
|
+
.window-btn.close:hover {
|
|
114
|
+
background: #e5484d;
|
|
115
|
+
color: #fff;
|
|
116
|
+
}
|
|
117
|
+
#loading-overlay {
|
|
59
118
|
position: absolute;
|
|
60
119
|
top: 0;
|
|
61
120
|
left: 0;
|
|
@@ -92,10 +151,16 @@
|
|
|
92
151
|
<script src="./node_modules/hls.js/dist/hls.min.js"></script>
|
|
93
152
|
<script src="./node_modules/artplayer/dist/artplayer.js"></script>
|
|
94
153
|
</head>
|
|
95
|
-
<body>
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
154
|
+
<body>
|
|
155
|
+
<header id="top-nav">
|
|
156
|
+
<div class="window-controls">
|
|
157
|
+
<button class="window-btn close" id="window-close" title="Close">×</button>
|
|
158
|
+
<button class="window-btn" id="window-maximize" title="Maximize">□</button>
|
|
159
|
+
<button class="window-btn" id="window-minimize" title="Minimize">-</button>
|
|
160
|
+
<button class="window-dot" title="Window controls" aria-label="Window controls"></button>
|
|
161
|
+
</div>
|
|
162
|
+
</header>
|
|
163
|
+
<div id="loading-overlay">
|
|
99
164
|
<div class="spinner"></div>
|
|
100
165
|
<div class="loading-text">Đang tải và làm sạch trình phát...</div>
|
|
101
166
|
</div>
|
|
@@ -103,9 +168,19 @@
|
|
|
103
168
|
|
|
104
169
|
<script>
|
|
105
170
|
const { ipcRenderer } = require('electron');
|
|
106
|
-
ipcRenderer.on('main-log', (e, msg) => {
|
|
107
|
-
console.log('[Main Process]', msg);
|
|
108
|
-
});
|
|
171
|
+
ipcRenderer.on('main-log', (e, msg) => {
|
|
172
|
+
console.log('[Main Process]', msg);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
document.getElementById('window-minimize').addEventListener('click', () => {
|
|
176
|
+
ipcRenderer.send('player:minimize');
|
|
177
|
+
});
|
|
178
|
+
document.getElementById('window-maximize').addEventListener('click', () => {
|
|
179
|
+
ipcRenderer.send('player:toggle-maximize');
|
|
180
|
+
});
|
|
181
|
+
document.getElementById('window-close').addEventListener('click', () => {
|
|
182
|
+
window.close();
|
|
183
|
+
});
|
|
109
184
|
|
|
110
185
|
// Keyboard shortcut: Escape to close
|
|
111
186
|
document.addEventListener('keydown', (e) => {
|
|
@@ -113,10 +188,10 @@
|
|
|
113
188
|
});
|
|
114
189
|
|
|
115
190
|
|
|
116
|
-
window.initPlayer = function(streamInfo, baseDir, cleanUA) {
|
|
117
|
-
const container = document.getElementById('player-container');
|
|
118
|
-
|
|
119
|
-
if (streamInfo.type === 'iframe') {
|
|
191
|
+
window.initPlayer = function(streamInfo, baseDir, cleanUA) {
|
|
192
|
+
const container = document.getElementById('player-container');
|
|
193
|
+
|
|
194
|
+
if (streamInfo.type === 'iframe') {
|
|
120
195
|
const overlay = document.getElementById('loading-overlay');
|
|
121
196
|
overlay.style.display = 'flex';
|
|
122
197
|
|