neko/src/component/screencast.vue

91 lines
1.8 KiB
Vue
Raw Normal View History

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
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()
}
}
onImageLoad() {
2022-03-12 12:16:27 +13:00
URL.revokeObjectURL(this.imageSrc)
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>