Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
m1k1o
GitHub Repository: m1k1o/neko
Path: blob/master/client/src/store/video.ts
1301 views
1
import { getterTree, mutationTree, actionTree } from 'typed-vuex'
2
import { get, set } from '~/utils/localstorage'
3
import { EVENT } from '~/neko/events'
4
import { ScreenConfigurations, ScreenResolution } from '~/neko/types'
5
import { accessor } from '~/store'
6
7
export const namespaced = true
8
9
export const state = () => ({
10
index: -1,
11
tracks: [] as MediaStreamTrack[],
12
streams: [] as MediaStream[],
13
configurations: [] as ScreenResolution[],
14
width: 1280,
15
height: 720,
16
rate: 30,
17
horizontal: 16,
18
vertical: 9,
19
volume: get<number>('volume', 100),
20
muted: get<boolean>('muted', false),
21
playing: false,
22
playable: false,
23
})
24
25
export const getters = getterTree(state, {
26
stream: (state) => state.streams[state.index],
27
track: (state) => state.tracks[state.index],
28
resolution: (state) => ({ w: state.width, h: state.height }),
29
})
30
31
export const mutations = mutationTree(state, {
32
play(state) {
33
if (state.playable) {
34
state.playing = true
35
}
36
},
37
38
pause(state) {
39
if (state.playable) {
40
state.playing = false
41
}
42
},
43
44
togglePlay(state) {
45
if (state.playable) {
46
state.playing = !state.playing
47
}
48
},
49
50
setMuted(state, muted: boolean) {
51
state.muted = muted
52
set('mute', muted)
53
},
54
55
toggleMute(state) {
56
state.muted = !state.muted
57
set('mute', state.muted)
58
},
59
60
setPlayable(state, playable: boolean) {
61
if (!playable && state.playing) {
62
state.playing = false
63
}
64
state.playable = playable
65
},
66
67
setResolution(state, { width, height, rate }: { width: number; height: number; rate: number }) {
68
state.width = width
69
state.height = height
70
state.rate = rate
71
72
if ((height == 0 && width == 0) || (height == 0 && width != 0) || (height != 0 && width == 0)) {
73
return
74
}
75
76
if (height == width) {
77
return {
78
horizontal: 1,
79
vertical: 1,
80
}
81
}
82
83
let dividend = width
84
let divisor = height
85
let gcd = -1
86
87
if (height > width) {
88
dividend = height
89
divisor = width
90
}
91
92
while (gcd == -1) {
93
const remainder = dividend % divisor
94
if (remainder == 0) {
95
gcd = divisor
96
} else {
97
dividend = divisor
98
divisor = remainder
99
}
100
}
101
102
state.horizontal = width / gcd
103
state.vertical = height / gcd
104
},
105
106
setConfigurations(state, configurations: ScreenConfigurations) {
107
const data: ScreenResolution[] = []
108
109
for (const i of Object.keys(configurations)) {
110
const { width, height, rates } = configurations[i]
111
if (width >= 600 && height >= 300) {
112
for (const j of Object.keys(rates)) {
113
const rate = rates[j]
114
if (rate === 30 || rate === 60) {
115
data.push({
116
width,
117
height,
118
rate,
119
})
120
}
121
}
122
}
123
}
124
125
state.configurations = data.sort((a, b) => {
126
if (b.width === a.width && b.height == a.height) {
127
return b.rate - a.rate
128
} else if (b.width === a.width) {
129
return b.height - a.height
130
}
131
return b.width - a.width
132
})
133
},
134
135
setVolume(state, volume: number) {
136
state.volume = volume
137
set('volume', volume)
138
},
139
140
setStream(state, index: number) {
141
state.index = index
142
},
143
144
addTrack(state, [track, stream]: [MediaStreamTrack, MediaStream]) {
145
state.tracks = state.tracks.concat([track])
146
state.streams = state.streams.concat([stream])
147
},
148
149
delTrack(state, index: number) {
150
state.streams = state.streams.filter((_, i) => i !== index)
151
state.tracks = state.tracks.filter((_, i) => i !== index)
152
},
153
154
reset(state) {
155
state.index = -1
156
state.tracks = []
157
state.streams = []
158
state.configurations = []
159
state.width = 1280
160
state.height = 720
161
state.rate = 30
162
state.horizontal = 16
163
state.vertical = 9
164
state.playing = false
165
state.playable = false
166
},
167
})
168
169
export const actions = actionTree(
170
{ state, getters, mutations },
171
{
172
screenConfiguations() {
173
if (!accessor.connected || !accessor.user.admin) {
174
return
175
}
176
177
$client.sendMessage(EVENT.SCREEN.CONFIGURATIONS)
178
},
179
180
screenGet() {
181
if (!accessor.connected) {
182
return
183
}
184
185
$client.sendMessage(EVENT.SCREEN.RESOLUTION)
186
},
187
188
screenSet(store, resolution: ScreenResolution) {
189
if (!accessor.connected || !accessor.user.admin) {
190
return
191
}
192
193
$client.sendMessage(EVENT.SCREEN.SET, resolution)
194
},
195
},
196
)
197
198