-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathqq_speed_bbs_toolkit.js
More file actions
217 lines (216 loc) · 8.8 KB
/
qq_speed_bbs_toolkit.js
File metadata and controls
217 lines (216 loc) · 8.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
// ==UserScript==
// @name QQ飞车官方论坛视频处理工具 - 自动识别视频并以 <iframe> 方式加载
// @namespace https://speed.qq.com
// @icon https://speed.qq.com/favicon.ico
// @version 1.0.0
// @description 视频播放方式改为 <iframe> 加载, 避免 chomre 及 firefox 需要手动开启 flash 权限的情况(现在所有浏览器厂商普遍表示将在未来淘汰 flash, 包括 adobe); 通过加速的方式跳过片头广告
// @author Sven
// @match https://speed.gamebbs.qq.com/forum.php?mod=viewthread&tid=*
// @match https://v.qq.com/txp/iframe/player.html?vid=*
// @match https://v.qq.com/x/cover/*.html*
// @match https://v.qq.com/x/page/*.html*
// @run-at document-start
// @grant none
// ==/UserScript==
; (function () {
/**
* 工具模块类
*/
class ToolkitModule {
static playbackRate = 16
static PAGES = {
bbs: {
host: 'speed.gamebbs.qq.com',
sheets: `
#video_iframe_wrapper {
margin-bottom: 20px;
display: flex;
justify-content: center;
}
#video_iframe_wrapper > iframe {
width: 100%;
max-width: 900px;
height: 65vh;
min-height: 450px;
max-height: 600px;
}
`
},
qq_video: {
host: 'v.qq.com',
sheets: `
#video_container txpdiv.txp_tipbar { display: none; }
.txp_recommend_content > .txp_btn.txp_btn_expand { display: none; }
`,
get adExists() {
return !!document.querySelector('.txp_ad_control:not(.txp_none)')
}
},
iqiyi_video: {
host: 'www.iqiyi.com',
sheets: `
div[data-adzone] {
display: none;
}
`,
}
}
static get PAGE_TYPE() {
for (const page in ToolkitModule.PAGES) {
if (location.host === ToolkitModule.PAGES[page].host) return page
}
}
static get PAGE_OPTIONS() {
for (const page in ToolkitModule.PAGES) {
if (location.host === ToolkitModule.PAGES[page].host) return ToolkitModule.PAGES[page]
}
}
static get TEXT_ARTICLE() { const d = document.querySelector('.plc .pct'); return d && d.innerText }
static get VIDEO_URL() {
const article = ToolkitModule.TEXT_ARTICLE
const urlMatchResult = article.match(/https:\/\/v\.qq\.com\/x\/page\/([\d\w]+).htm.*/) || article.match(/http:\/\/v\.qq\.com\/page\/.*\/([\d\w]+).htm.*/)
const embed = document.querySelector('embed')
return (embed && embed.src.indexOf('17173') > 0)
? embed.src
: (urlMatchResult && urlMatchResult[0])
}
static get VIDEO_ID() {
// console.log(ToolkitModule.VIDEO_URL)
if (!ToolkitModule.VIDEO_URL) return
if (ToolkitModule.VIDEO_URL.indexOf('17173') > 0) { // such as http://f.v.17173cdn.com/player_f2/MTQ0MjI1MTA.swf
const matchResult = ToolkitModule.VIDEO_URL.match(/http:\/\/[\w\.]+17173cdn.com\/.*\/([\d\w]+)\.swf/)
return matchResult[1]
} else {
const urlMatchResult = ToolkitModule.VIDEO_URL.match(/https:\/\/v\.qq\.com\/x\/page\/([\d\w]+).htm.*/) || ToolkitModule.VIDEO_URL.match(/http:\/\/v\.qq\.com\/page\/.*\/([\d\w]+).htm.*/)
return urlMatchResult[1]
}
}
static get VIDEO_IFRAME_URL() {
if (!ToolkitModule.VIDEO_ID) return
// console.warn(ToolkitModule.VIDEO_ID)
return ToolkitModule.VIDEO_URL.indexOf('17173') > 0 ? `//v.17173.com/player_ifrm2/${ToolkitModule.VIDEO_ID}.html` : `https://v.qq.com/txp/iframe/player.html?vid=${ToolkitModule.VIDEO_ID}`
}
static get DOM_VIDEOS() {
return document.querySelectorAll('video')
}
get activePages() { throw new Error('must implemention') }
get isActive() { return this.activePages.includes(ToolkitModule.PAGE_TYPE) }
onload() { throw new Error('must implemention') }
/**
* 通过重写 setTimeout 实现加速 setTimeout
* @param {number} multiple 加速倍数
*/
speedUpSetTimeout(multiple = 30) {
window._setTimeout = setTimeout
window.setTimeout = (handler, time, ...args) => {
window._setTimeout(handler, time / multiple, ...args)
}
}
}
/**
* 论坛视频贴载入视频的 iframe
*/
class VideoToolkitModule extends ToolkitModule {
activePages = ['bbs']
constructor() { super() }
onload(ctx) {
ctx.log('已提取到视频, URL: ', ToolkitModule.VIDEO_IFRAME_URL)
if (!ToolkitModule.VIDEO_IFRAME_URL) return
const videoIframeWrapper = document.createElement('div')
videoIframeWrapper.id = 'video_iframe_wrapper'
const iframe = this.generateVideoDom(ToolkitModule.VIDEO_IFRAME_URL, this.iframeOnload)
videoIframeWrapper.appendChild(iframe)
document.querySelector('.pcb').insertBefore(videoIframeWrapper, document.querySelector('.pcb > div'))
}
generateVideoDom(url, onload) {
const iframe = document.createElement('iframe')
iframe.addEventListener('load', onload)
iframe.id = 'video_iframe'
iframe.setAttribute('frameBorder', '0')
iframe.setAttribute('allowFullScreen', 'true')
iframe.src = url
return iframe
}
iframeOnload(evt) {
console.log('iframe load', evt)
}
}
/**
* 载入页面样式
*/
class SheetsToolkitModule extends ToolkitModule {
activePages = ['bbs', 'qq_video']
constructor() { super() }
onload(ctx) {
const sheet = document.createTextNode(ToolkitModule.PAGE_OPTIONS.sheets)
const el = document.createElement('style')
el.id = 'toolkit-sheets'
el.appendChild(sheet)
document.getElementsByTagName('head')[0].appendChild(el)
}
}
/**
* 加速跳过腾讯视频片头广告
*/
class QQVideoADJumpToolkitModule extends ToolkitModule {
activePages = ['qq_video']
constructor() { super() }
onload(ctx) {
setInterval(() => {
const adExists = ToolkitModule.PAGE_OPTIONS.adExists
const videos = document.querySelectorAll('video')
if (!adExists) {
// ctx.log(`[QQVideoADJump] 已加速跳过广告, enjoy`)
if (videos && videos.length) videos.forEach(v => v.playbackRate = 1)
return
}
for (const video of videos) {
video.playbackRate = ToolkitModule.playbackRate
ctx.log(`[QQVideoADJump] 腾讯视频过滤日志 => 视频播放加速倍率: ${video.playbackRate}; 视频状态值: ${video.status}, 正在播放广告: ${adExists}`)
}
}, 1000);
}
}
/**
* 工具类
*/
class Toolkit {
debug = true
options = {}
constructor(options = {}) {
Object.assign(this.options, options)
this.emitHook('init')
}
/**
* 工具集
*/
static modules = []
/**
* 注册工具模块
*/
static use(moduleItem) {
// 禁用未激活的模块
if (!moduleItem.isActive) return
Array.isArray(moduleItem) ? moduleItem.map(item => Toolkit.use(item)) : Toolkit.modules.push(moduleItem)
}
/**
* 触发钩子函数
* @param {string}} hook 钩子函数名
*/
emitHook(hook) {
this.log('触发钩子函数: ' + hook)
Toolkit.modules.map(module => module[hook] && typeof module[hook] === 'function' && module[hook](this))
}
log(...args) {
console.log('%c[QQ Speed BBS Toolkit] LOG: ', 'color:teal', ...args)
}
static delay(timeout = 200) {
return new Promise(resolve => setTimeout(resolve, timeout))
}
}
Toolkit.use(new SheetsToolkitModule())
Toolkit.use(new VideoToolkitModule())
Toolkit.use(new QQVideoADJumpToolkitModule())
window._$Toolkit = new Toolkit()
window.addEventListener('DOMContentLoaded', () => window._$Toolkit.emitHook('onload'))
})();