mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-09 09:20:54 +00:00
UBERF-9731 Some recorder fixes
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
parent
6f26cf0511
commit
59b8cdb5a1
@ -180,7 +180,7 @@
|
||||
{:else}
|
||||
{#await getBlobRef(value.file, value.name, sizeToWidth('large')) then valueRef}
|
||||
<a
|
||||
class="no-line"
|
||||
class="no-line no-underline"
|
||||
style:flex-shrink={0}
|
||||
href={valueRef.src}
|
||||
download={value.name}
|
||||
@ -211,7 +211,7 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="info-content flex-row-center">
|
||||
{#if value.size != null}{filesize(value.size, { spacer: '' })}{/if}
|
||||
{#if value.size != null && value.size !== 0}{filesize(value.size, { spacer: '' })}{/if}
|
||||
<span class="actions inline-flex clear-mins ml-1 gap-1">
|
||||
<span>•</span>
|
||||
<a class="no-line colorInherit" href={valueRef.src} download={value.name} bind:this={download}>
|
||||
|
@ -103,6 +103,7 @@
|
||||
|
||||
$: if (state !== null && state.state === 'stopped') {
|
||||
dispatch('close')
|
||||
recording.set(null)
|
||||
}
|
||||
|
||||
async function updateCameraStream (
|
||||
@ -269,6 +270,8 @@
|
||||
|
||||
async function handleStopRecording (): Promise<void> {
|
||||
await stopRecording()
|
||||
camEnabled = false
|
||||
micEnabled = false
|
||||
}
|
||||
|
||||
async function handleRestartRecording (): Promise<void> {
|
||||
@ -412,6 +415,8 @@
|
||||
}
|
||||
|
||||
function onKeyDown (e: KeyboardEvent): void {
|
||||
if (state?.state === 'stopping') return
|
||||
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
@ -455,7 +460,7 @@
|
||||
>
|
||||
<div class="container p-3">
|
||||
{#if state !== null && state.state === 'stopped'}
|
||||
<div class="placeholder flex-col-center justify-center">OK</div>
|
||||
<!-- Maybe show recording result -->
|
||||
{:else if mainStream === null}
|
||||
<div class="placeholder flex-col-center justify-center">
|
||||
{#if cameraStreamPromise === null}
|
||||
@ -590,6 +595,8 @@
|
||||
icon={IconStop}
|
||||
iconProps={{ size: 'small' }}
|
||||
label={plugin.string.Stop}
|
||||
disabled={state.state === 'stopping'}
|
||||
loading={state.state === 'stopping'}
|
||||
noFocus
|
||||
on:click={handleStopRecording}
|
||||
/>
|
||||
|
@ -1,15 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { DropdownLabels, DropdownTextItem, Label } from '@hcengineering/ui'
|
||||
import { DropdownLabelsIntl, DropdownIntlItem, Label } from '@hcengineering/ui'
|
||||
import plugin from '../plugin'
|
||||
import { recordingCameraPosition, recordingCameraSize } from '../stores'
|
||||
|
||||
const sizes: DropdownTextItem[] = [
|
||||
const sizes: DropdownIntlItem[] = [
|
||||
{ label: plugin.string.Small, id: 'small' },
|
||||
{ label: plugin.string.Medium, id: 'medium' },
|
||||
{ label: plugin.string.Large, id: 'large' }
|
||||
]
|
||||
|
||||
const poses: DropdownTextItem[] = [
|
||||
const poses: DropdownIntlItem[] = [
|
||||
{ label: plugin.string.TopLeft, id: 'top-left' },
|
||||
{ label: plugin.string.TopRight, id: 'top-right' },
|
||||
{ label: plugin.string.BottomLeft, id: 'bottom-left' },
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
<div class="antiPopup p-4 grid">
|
||||
<Label label={plugin.string.CameraSize} />
|
||||
<DropdownLabels
|
||||
<DropdownLabelsIntl
|
||||
items={sizes}
|
||||
placeholder={plugin.string.CameraSize}
|
||||
enableSearch={false}
|
||||
@ -32,7 +32,7 @@
|
||||
/>
|
||||
|
||||
<Label label={plugin.string.CameraPos} />
|
||||
<DropdownLabels
|
||||
<DropdownLabelsIntl
|
||||
items={poses}
|
||||
placeholder={plugin.string.CameraPos}
|
||||
enableSearch={false}
|
||||
|
@ -96,13 +96,56 @@ export class Recorder {
|
||||
return this.chunkStream
|
||||
}
|
||||
|
||||
public stop (): void {
|
||||
public async stop (): Promise<void> {
|
||||
if (this.lastStartTime !== null) {
|
||||
this.elapsedMs += Date.now() - this.lastStartTime
|
||||
this.lastStartTime = null
|
||||
}
|
||||
|
||||
// If the recorder is paused, we need to resume it before stopping
|
||||
try {
|
||||
if (this.mediaRecorder.state === 'paused') {
|
||||
const resumed = new Promise<void>((resolve) => {
|
||||
const timeout = setTimeout(resolve, 500)
|
||||
this.mediaRecorder.addEventListener(
|
||||
'resume',
|
||||
() => {
|
||||
clearTimeout(timeout)
|
||||
resolve()
|
||||
},
|
||||
{ once: true }
|
||||
)
|
||||
})
|
||||
this.mediaRecorder.resume()
|
||||
await resumed
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Recorder: error resuming MediaRecorder:', err)
|
||||
}
|
||||
|
||||
// Ensure we wait for any pending data to be available
|
||||
try {
|
||||
if (this.mediaRecorder.state === 'recording') {
|
||||
const dataavailable = new Promise<void>((resolve) => {
|
||||
const timeout = setTimeout(resolve, 500)
|
||||
this.mediaRecorder.addEventListener(
|
||||
'dataavailable',
|
||||
() => {
|
||||
clearTimeout(timeout)
|
||||
resolve()
|
||||
},
|
||||
{ once: true }
|
||||
)
|
||||
})
|
||||
this.mediaRecorder.requestData()
|
||||
await dataavailable
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Recorder: error requesting data from MediaRecorder:', err)
|
||||
}
|
||||
|
||||
try {
|
||||
// After requesting data, we can safely stop the recorder
|
||||
this.mediaRecorder.stop()
|
||||
} catch (err) {
|
||||
console.error('Recorder: error stopping MediaRecorder:', err)
|
||||
@ -111,6 +154,7 @@ export class Recorder {
|
||||
track.stop()
|
||||
}
|
||||
}
|
||||
|
||||
console.debug('Recorder: recording stopped, duration:', this.getRecordedTimeMs(), 'ms')
|
||||
}
|
||||
|
||||
|
@ -51,12 +51,11 @@ export async function stopRecording (): Promise<void> {
|
||||
const current = get(recording)
|
||||
const popup = get(recorder)
|
||||
if (current !== null && current.state === 'recording') {
|
||||
recording.set({ ...current, state: 'stopped' })
|
||||
|
||||
recording.set({ ...current, state: 'stopping' })
|
||||
const result = await current.recorder.stop()
|
||||
await current.options.onSuccess?.(result)
|
||||
|
||||
recording.set(null)
|
||||
recording.set({ ...current, state: 'stopped' })
|
||||
popup?.close()
|
||||
} else {
|
||||
console.warn('Recording is not in `recording` state', current)
|
||||
@ -80,7 +79,7 @@ export async function restartRecording (): Promise<void> {
|
||||
await current.recorder.start()
|
||||
recording.set({ ...current, state: 'recording' })
|
||||
} else {
|
||||
console.warn('Recording is not in `paused` state', current)
|
||||
console.warn('Recording not started', current)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,12 +67,12 @@ export class ScreenRecorder {
|
||||
}
|
||||
|
||||
public async stop (): Promise<RecordingResult> {
|
||||
this.recorder.stop()
|
||||
await this.recorder.stop()
|
||||
return await this.uploader.wait()
|
||||
}
|
||||
|
||||
public async cancel (): Promise<void> {
|
||||
this.recorder.stop()
|
||||
await this.recorder.stop()
|
||||
await this.uploader.cancel()
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ export interface RecordingState {
|
||||
recorder: ScreenRecorder
|
||||
options: RecordingOptions
|
||||
stream: MediaStream
|
||||
state: 'recording' | 'paused' | 'stopped'
|
||||
state: 'recording' | 'paused' | 'stopping' | 'stopped'
|
||||
}
|
||||
|
||||
export interface RecordingOptions {
|
||||
|
Loading…
Reference in New Issue
Block a user