最近在边看视频边做笔记,单个屏幕两个软件,因为经常需要暂停,快进,快退。软件焦点总会在浏览器和笔记软件切换。总是使用触摸板,误操作有点多。就写了个小插件,使用全局快捷键控制视频的播放,不需要在浏览器上操作,这样光标始终在笔记本上就好了

原理也很简单,使用油猴脚本连接本地websocket程序,监听到消息就对视频进行操作。本地程序监听全局快捷键就可以了。另外robotgo这玩意儿感觉不太好用….. 但是也没发现更好用的

直接放脚本了

油猴脚本

注意, 1. 需要添加只对当前活动页面有效 2. 断线重连机制

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
// ==UserScript==
// @name bilibili external control
// @namespace http://tampermonkey.net/
// @version 0.1
// @description control video play from outside
// @author ficapy
// @match https://www.bilibili.com/video/*
// @icon https://www.google.com/s2/favicons?domain=bilibili.com
// @grant none
// ==/UserScript==

(function() {
//1.创建websocket客户端
let wsServer = "ws://127.0.0.1:7788/control";
let limitConnect = 30; // 断线重连次数
let timeConnect = 0;
webSocketInit(wsServer);

//socket初始化
function webSocketInit(service){
let ws = new WebSocket(service);
ws.onopen = function () {
console.log("已连接TCP服务器");
};
ws.onmessage = function (event) {
if (document.visibilityState != "visible"){
return
}

let video = document.querySelector('video')
let d = event.data
if (d == "play"){
if (video.paused){
video.play()
}else{
video.pause()
}
}
if (d == "forward"){
video.currentTime = video.currentTime + 5;
}
if (d == "backward"){
video.currentTime = video.currentTime - 5;
}
}
ws.onclose = function () {
console.log('服务器已经断开');
reconnect(service);
};

// 重连
function reconnect(service) {
// lockReconnect加锁,防止onclose、onerror两次重连
if(limitConnect>0){
limitConnect --;
timeConnect ++;
console.log("第"+timeConnect+"次重连");
// 进行重连
setTimeout(function(){
webSocketInit(service);
}, 8000);

}else{
console.log("TCP连接已超时");
}
}

// 心跳 * 回应
setInterval(function(){
ws.send('');
}, 1000*100)
}
})();

本地全局快捷键监听

注意, 触发的消息要发送给每一个客户端

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
package main

import (
"flag"
"fmt"
"log"
"net/http"

"github.com/go-vgo/robotgo"
"github.com/gorilla/websocket"
hook "github.com/robotn/gohook"
)

var addr = flag.String("addr", "localhost:7788", "http service address")
var MESSAGE = make(chan string, 1)
var HUB = map[string]*websocket.Conn{}

const (
PLAY = "play"
FORWARD = "forward"
BACKWARD = "backward"
)

var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}

func control(w http.ResponseWriter, r *http.Request) {
c, _ := upgrader.Upgrade(w, r, nil)
key := c.RemoteAddr().String()
HUB[key] = c
defer func() {
delete(HUB, key)
c.Close()
}()
for {
_, _, err := c.ReadMessage()
if err != nil {
break
}
}
}

func sendMessage() {
for i := range MESSAGE {
for _, v := range HUB {
v.WriteMessage(websocket.TextMessage, []byte(i))
}
}
}

func hotkey() {
go func() {
robotgo.EventHook(hook.KeyDown, []string{"alt", "left"}, func(e hook.Event) {
fmt.Println("left")
if len(MESSAGE) == 0 {
MESSAGE <- BACKWARD
}
})

robotgo.EventHook(hook.KeyDown, []string{"alt", "right"}, func(e hook.Event) {
fmt.Println("right")
if len(MESSAGE) == 0 {
MESSAGE <- FORWARD
}
})

robotgo.EventHook(hook.KeyDown, []string{"alt", "up"}, func(e hook.Event) {
fmt.Println("up")
if len(MESSAGE) == 0 {
MESSAGE <- PLAY
}
})

s := robotgo.EventStart()
<-robotgo.EventProcess(s)
}()
}

func main() {
go sendMessage()
hotkey()
flag.Parse()
log.SetFlags(0)
http.HandleFunc("/control", control)
log.Fatal(http.ListenAndServe(*addr, nil))
}