2021-07-15 01:37:23 +12:00
|
|
|
<template>
|
2022-03-12 12:16:27 +13:00
|
|
|
<img :src="imageSrc" @load="onImageLoad" @error="onImageError" />
|
2021-07-15 01:37:23 +12:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
import { Vue, Component, Ref, Watch, Prop } from 'vue-property-decorator'
|
|
|
|
import { RoomApi } from './api'
|
|
|
|
|
|
|
|
const REFRESH_RATE = 1e3
|
2021-08-03 21:14:38 +12:00
|
|
|
const ERROR_DELAY_MS = 2500
|
2021-07-15 01:37:23 +12:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
name: 'neko-screencast',
|
|
|
|
})
|
|
|
|
export default class extends Vue {
|
2022-03-12 12:16:27 +13:00
|
|
|
private imageSrc = ''
|
2021-07-28 10:07:20 +12:00
|
|
|
private running = false
|
|
|
|
private continue = false
|
2021-07-15 01:37:23 +12:00
|
|
|
|
2021-07-18 02:36:56 +12:00
|
|
|
@Prop()
|
|
|
|
private readonly enabled!: boolean
|
|
|
|
|
2021-07-15 01:37:23 +12:00
|
|
|
@Prop()
|
|
|
|
private readonly api!: RoomApi
|
|
|
|
|
|
|
|
async loop() {
|
2021-07-28 10:07:20 +12:00
|
|
|
if (this.running) return
|
|
|
|
this.running = true
|
|
|
|
|
|
|
|
while (this.continue) {
|
2021-07-15 01:37:23 +12:00
|
|
|
const lastLoad = Date.now()
|
|
|
|
|
2021-08-03 21:14:38 +12:00
|
|
|
try {
|
|
|
|
const res = await this.api.screenCastImage({ responseType: 'blob' })
|
2022-03-12 12:16:27 +13:00
|
|
|
this.imageSrc = URL.createObjectURL(res.data)
|
2021-07-15 01:37:23 +12:00
|
|
|
|
2021-08-03 21:14:38 +12:00
|
|
|
const delay = lastLoad - Date.now() + REFRESH_RATE
|
|
|
|
if (delay > 0) {
|
|
|
|
await new Promise((res) => setTimeout(res, delay))
|
|
|
|
}
|
2021-09-02 05:11:01 +12:00
|
|
|
} catch {
|
2021-08-03 21:14:38 +12:00
|
|
|
await new Promise((res) => setTimeout(res, ERROR_DELAY_MS))
|
|
|
|
}
|
2021-07-15 01:37:23 +12:00
|
|
|
}
|
2021-07-28 10:07:20 +12:00
|
|
|
|
|
|
|
this.running = false
|
2022-03-12 12:16:27 +13:00
|
|
|
this.imageSrc = ''
|
2021-07-15 01:37:23 +12:00
|
|
|
}
|
|
|
|
|
2021-07-18 02:36:56 +12:00
|
|
|
mounted() {
|
|
|
|
if (this.enabled) {
|
|
|
|
this.start()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
beforeDestroy() {
|
|
|
|
this.stop()
|
|
|
|
}
|
|
|
|
|
|
|
|
start() {
|
2021-07-28 10:07:20 +12:00
|
|
|
if (!this.running) {
|
|
|
|
this.continue = true
|
2021-07-27 10:22:21 +12:00
|
|
|
setTimeout(this.loop, 0)
|
|
|
|
}
|
2021-07-15 01:37:23 +12:00
|
|
|
}
|
|
|
|
|
2021-07-18 02:36:56 +12:00
|
|
|
stop() {
|
2021-07-28 10:07:20 +12:00
|
|
|
this.continue = false
|
2021-07-15 01:37:23 +12:00
|
|
|
}
|
2021-07-18 02:36:56 +12:00
|
|
|
|
|
|
|
@Watch('enabled')
|
|
|
|
onEnabledChanged(enabled: boolean) {
|
|
|
|
if (enabled) {
|
|
|
|
this.start()
|
|
|
|
} else {
|
|
|
|
this.stop()
|
|
|
|
}
|
|
|
|
}
|
2022-02-08 02:31:11 +13:00
|
|
|
|
|
|
|
onImageLoad() {
|
2022-03-12 12:16:27 +13:00
|
|
|
URL.revokeObjectURL(this.imageSrc)
|
2022-02-08 02:31:11 +13:00
|
|
|
this.$emit('imageReady', this.running)
|
|
|
|
}
|
2022-03-12 12:16:27 +13:00
|
|
|
|
|
|
|
onImageError() {
|
|
|
|
if (this.imageSrc) URL.revokeObjectURL(this.imageSrc)
|
|
|
|
this.$emit('imageReady', false)
|
|
|
|
}
|
2021-07-15 01:37:23 +12:00
|
|
|
}
|
|
|
|
</script>
|