feat: add native Windows recorder helper
This commit is contained in:
@@ -54,8 +54,8 @@ const PRETTY_NATIVE_CURSOR_ASSETS: Partial<Record<NativeCursorType, PrettyNative
|
||||
imageDataUrl: arrowUrl,
|
||||
width: 32,
|
||||
height: 32,
|
||||
hotspotX: 5.8,
|
||||
hotspotY: 3.2,
|
||||
hotspotX: 16.25,
|
||||
hotspotY: 15.03,
|
||||
},
|
||||
text: {
|
||||
imageDataUrl: textUrl,
|
||||
@@ -67,9 +67,9 @@ const PRETTY_NATIVE_CURSOR_ASSETS: Partial<Record<NativeCursorType, PrettyNative
|
||||
pointer: {
|
||||
imageDataUrl: pointerUrl,
|
||||
width: 32,
|
||||
height: 32,
|
||||
hotspotX: 11.8,
|
||||
hotspotY: 2.6,
|
||||
height: 33,
|
||||
hotspotX: 16.65,
|
||||
hotspotY: 14.24,
|
||||
},
|
||||
crosshair: {
|
||||
imageDataUrl: crosshairUrl,
|
||||
@@ -131,15 +131,15 @@ const PRETTY_NATIVE_CURSOR_ASSETS: Partial<Record<NativeCursorType, PrettyNative
|
||||
imageDataUrl: appStartingUrl,
|
||||
width: 32,
|
||||
height: 32,
|
||||
hotspotX: 5.8,
|
||||
hotspotY: 3.2,
|
||||
hotspotX: 7.25,
|
||||
hotspotY: 4.03,
|
||||
},
|
||||
help: {
|
||||
imageDataUrl: helpUrl,
|
||||
width: 32,
|
||||
height: 32,
|
||||
hotspotX: 5.8,
|
||||
hotspotY: 3.2,
|
||||
hotspotX: 7.25,
|
||||
hotspotY: 4.03,
|
||||
},
|
||||
"up-arrow": {
|
||||
imageDataUrl: upArrowUrl,
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { SpeedRegion, TrimRegion } from "@/components/video-editor/types";
|
||||
import type { VideoMuxer } from "./muxer";
|
||||
|
||||
const AUDIO_BITRATE = 128_000;
|
||||
const EXPORT_AUDIO_CODEC = "mp4a.40.2";
|
||||
const DECODE_BACKPRESSURE_LIMIT = 20;
|
||||
const MIN_SPEED_REGION_DELTA_MS = 0.0001;
|
||||
const SEEK_TIMEOUT_MS = 5_000;
|
||||
@@ -138,7 +139,7 @@ export class AudioProcessor {
|
||||
const channels = audioConfig.numberOfChannels || 2;
|
||||
|
||||
const encodeConfig: AudioEncoderConfig = {
|
||||
codec: "opus",
|
||||
codec: EXPORT_AUDIO_CODEC,
|
||||
sampleRate,
|
||||
numberOfChannels: channels,
|
||||
bitrate: AUDIO_BITRATE,
|
||||
@@ -146,7 +147,7 @@ export class AudioProcessor {
|
||||
|
||||
const encodeSupport = await AudioEncoder.isConfigSupported(encodeConfig);
|
||||
if (!encodeSupport.supported) {
|
||||
console.warn("[AudioProcessor] Opus encoding not supported, skipping audio");
|
||||
console.warn("[AudioProcessor] AAC encoding not supported, skipping audio");
|
||||
for (const frame of decodedFrames) frame.close();
|
||||
return;
|
||||
}
|
||||
@@ -397,28 +398,7 @@ export class AudioProcessor {
|
||||
|
||||
try {
|
||||
await demuxer.load(file);
|
||||
const audioConfig = await demuxer.getDecoderConfig("audio");
|
||||
const reader = demuxer.read("audio").getReader();
|
||||
let isFirstChunk = true;
|
||||
|
||||
try {
|
||||
while (!this.cancelled) {
|
||||
const { done, value: chunk } = await reader.read();
|
||||
if (done || !chunk) break;
|
||||
if (isFirstChunk) {
|
||||
await muxer.addAudioChunk(chunk, { decoderConfig: audioConfig });
|
||||
isFirstChunk = false;
|
||||
} else {
|
||||
await muxer.addAudioChunk(chunk);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
await reader.cancel();
|
||||
} catch {
|
||||
/* reader already closed */
|
||||
}
|
||||
}
|
||||
await this.processTrimOnlyAudio(demuxer, muxer, []);
|
||||
} finally {
|
||||
try {
|
||||
demuxer.destroy();
|
||||
|
||||
@@ -40,7 +40,7 @@ export class VideoMuxer {
|
||||
|
||||
// Create audio source if needed
|
||||
if (this.hasAudio) {
|
||||
this.audioSource = new EncodedAudioPacketSource("opus");
|
||||
this.audioSource = new EncodedAudioPacketSource("aac");
|
||||
this.output.addAudioTrack(this.audioSource);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
export type NativeWindowsSourceType = "display" | "window";
|
||||
|
||||
export type NativeWindowsRecordingRequest = {
|
||||
recordingId?: number;
|
||||
source: {
|
||||
type: NativeWindowsSourceType;
|
||||
sourceId: string;
|
||||
displayId?: number;
|
||||
windowHandle?: string;
|
||||
};
|
||||
video: {
|
||||
fps: number;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
audio: {
|
||||
system: {
|
||||
enabled: boolean;
|
||||
};
|
||||
microphone: {
|
||||
enabled: boolean;
|
||||
deviceId?: string;
|
||||
gain: number;
|
||||
};
|
||||
};
|
||||
webcam: {
|
||||
enabled: boolean;
|
||||
deviceId?: string;
|
||||
width: number;
|
||||
height: number;
|
||||
fps: number;
|
||||
};
|
||||
};
|
||||
|
||||
export type NativeWindowsRecordingStartResult = {
|
||||
success: boolean;
|
||||
recordingId?: number;
|
||||
path?: string;
|
||||
helperPath?: string;
|
||||
error?: string;
|
||||
};
|
||||
Reference in New Issue
Block a user