sonygod commited on
Commit
14e8f07
·
1 Parent(s): cf4bb10

油猴脚本

Browse files
Files changed (1) hide show
  1. youhou.js +193 -0
youhou.js ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ==UserScript==
2
+ // @name HeiMuer TV Video Player
3
+ // @namespace http://tampermonkey.net/
4
+ // @version 0.3
5
+ // @description Add video player for HeiMuer TV
6
+ // @author You
7
+ // @match https://heimuer.tv/index.php/vod/detail/id/*
8
+ // @grant GM_log
9
+ // @require https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.4.10/hls.min.js
10
+ // ==/UserScript==
11
+
12
+ (function () {
13
+ 'use strict';
14
+
15
+ const processedUrls = new Set();
16
+ let currentHls = null;
17
+
18
+ function createVideoPlayer() {
19
+ // Create main panel
20
+ const panelDiv = document.createElement('div');
21
+ panelDiv.className = 'stui-pannel clearfix';
22
+
23
+ // Create header
24
+ const headDiv = document.createElement('div');
25
+ headDiv.className = 'stui-pannel__head clearfix';
26
+
27
+ // Create title
28
+ const title = document.createElement('h3');
29
+ title.className = 'title';
30
+ title.textContent = '在线播放';
31
+ headDiv.appendChild(title);
32
+
33
+ // Create episode list container
34
+ const episodeListDiv = document.createElement('div');
35
+ episodeListDiv.className = 'episode-list';
36
+ episodeListDiv.style.cssText = 'margin: 10px 0; display: flex; flex-wrap: wrap; gap: 5px;';
37
+ headDiv.appendChild(episodeListDiv);
38
+
39
+ // Create video wrapper
40
+ const wrapper = document.createElement('div');
41
+ wrapper.className = 'video-wrapper';
42
+ wrapper.style.cssText = 'width: 100%; position: relative; aspect-ratio: 16/9;';
43
+
44
+ // Create video container
45
+ const container = document.createElement('div');
46
+ container.className = 'custom-video-player';
47
+ container.style.cssText = 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;';
48
+
49
+ // Create video element
50
+ const video = document.createElement('video');
51
+ video.controls = true;
52
+ video.style.cssText = 'width: 100%; height: 100%; object-fit: contain;';
53
+
54
+ // Assemble DOM
55
+ container.appendChild(video);
56
+ wrapper.appendChild(container);
57
+ panelDiv.appendChild(headDiv);
58
+ panelDiv.appendChild(wrapper);
59
+
60
+ // Add loading indicator
61
+ const loadingDiv = document.createElement('div');
62
+ loadingDiv.style.cssText = `
63
+ position: absolute;
64
+ top: 50%;
65
+ left: 50%;
66
+ transform: translate(-50%, -50%);
67
+ background: rgba(0,0,0,0.7);
68
+ color: white;
69
+ padding: 10px 20px;
70
+ border-radius: 4px;
71
+ display: none;
72
+ `;
73
+ loadingDiv.textContent = '加载中...';
74
+ container.appendChild(loadingDiv);
75
+
76
+ return {
77
+ container: panelDiv,
78
+ episodeList: episodeListDiv,
79
+ video: video,
80
+ playUrl: function (url) {
81
+ loadingDiv.style.display = 'block';
82
+
83
+ if (currentHls) {
84
+ currentHls.destroy();
85
+ }
86
+
87
+ const tryPlay = () => {
88
+ video.play().catch(error => {
89
+ console.log("Retrying autoplay...");
90
+ setTimeout(tryPlay, 1000);
91
+ });
92
+ };
93
+
94
+ if (Hls.isSupported()) {
95
+ currentHls = new Hls();
96
+ currentHls.loadSource(url);
97
+ currentHls.attachMedia(video);
98
+
99
+ currentHls.on(Hls.Events.MANIFEST_LOADED, () => {
100
+ console.log("Manifest loaded");
101
+ });
102
+
103
+ currentHls.on(Hls.Events.MANIFEST_PARSED, () => {
104
+ console.log("Manifest parsed");
105
+ loadingDiv.style.display = 'none';
106
+ tryPlay();
107
+ });
108
+
109
+ currentHls.on(Hls.Events.ERROR, (event, data) => {
110
+ console.log("HLS error:", data);
111
+ loadingDiv.style.display = 'none';
112
+ });
113
+ } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
114
+ video.src = url;
115
+ video.addEventListener('loadedmetadata', () => {
116
+ loadingDiv.style.display = 'none';
117
+ tryPlay();
118
+ });
119
+ }
120
+ }
121
+ };
122
+ }
123
+
124
+ function init() {
125
+ const descDiv = document.getElementById('desc');
126
+ if (!descDiv) return;
127
+
128
+ // Parse all episodes
129
+ const episodes = [];
130
+ document.querySelectorAll('.hidden-xs').forEach(el => {
131
+ const text = el.textContent || '';
132
+ if (text.includes('m3u8.heimuertv.com')) {
133
+ const [number, fullUrl] = text.split('$');
134
+ const url = fullUrl.match(/https:\/\/m3u8\.heimuertv\.com\/play\/[\w\.]+\.m3u8/)?.[0];
135
+ if (url) {
136
+ console.log('Episode number:', number); // Debug log
137
+ episodes.push({ number, url });
138
+ }
139
+ }
140
+ });
141
+
142
+ if (episodes.length > 0) {
143
+ // Sort episodes
144
+ episodes.sort((a, b) => Number(a.number) - Number(b.number));
145
+
146
+ // Create player
147
+ const player = createVideoPlayer();
148
+ descDiv.parentNode.insertBefore(player.container, descDiv);
149
+
150
+ // Create episode buttons
151
+ episodes.forEach((episode, idx) => {
152
+ const btn = document.createElement('button');
153
+ const episodeNum = (idx + 1).toString().padStart(2, '0'); // Convert index to episode number
154
+ btn.textContent = `第${episodeNum}集`;
155
+ btn.style.cssText = `
156
+ padding: 5px 15px;
157
+ border: 1px solid ${idx === 0 ? '#007bff' : '#ddd'};
158
+ background: ${idx === 0 ? '#007bff' : '#fff'};
159
+ color: ${idx === 0 ? '#fff' : '#333'};
160
+ border-radius: 3px;
161
+ cursor: pointer;
162
+ `;
163
+ btn.onclick = () => {
164
+ // Update button styles
165
+ player.episodeList.querySelectorAll('button').forEach(b => {
166
+ b.style.background = '#fff';
167
+ b.style.color = '#333';
168
+ b.style.borderColor = '#ddd';
169
+ });
170
+ btn.style.background = '#007bff';
171
+ btn.style.color = '#fff';
172
+ btn.style.borderColor = '#007bff';
173
+
174
+ // Play episode
175
+ player.playUrl(episode.url);
176
+ };
177
+ player.episodeList.appendChild(btn);
178
+ });
179
+
180
+ // Play first episode
181
+ // Trigger initial play with slight delay
182
+ setTimeout(() => {
183
+ player.playUrl(episodes[0].url);
184
+ }, 500);
185
+ }
186
+ }
187
+
188
+ if (document.readyState === 'loading') {
189
+ document.addEventListener('DOMContentLoaded', init);
190
+ } else {
191
+ init();
192
+ }
193
+ })();