Peng Xiao 899ffd1ad3
feat(native): windows audio monitoring & recording (#12615)
fix AF-2692

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added comprehensive Windows support for audio and application capture,
including real-time microphone usage detection, combined microphone and
system audio recording, and application state monitoring.
  - The "meetings" setting is now enabled on Windows as well as macOS.
- Conditional UI styling and attributes introduced for Windows
environments in the Electron renderer.

- **Bug Fixes**
- Enhanced file path handling and validation for Windows in Electron
file requests.

- **Refactor**
- Unified application info handling across platforms by consolidating
types into a single `ApplicationInfo` structure.
- Updated native module APIs by removing deprecated types, refining
method signatures, and improving error messages.
- Streamlined audio tapping APIs to use process IDs and consistent
callback types.

- **Documentation**
- Added detailed documentation for the Windows-specific audio recording
and microphone listener modules.

- **Chores**
  - Updated development dependencies in multiple packages.
- Reorganized and added platform-specific dependencies and configuration
for Windows support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->





#### PR Dependency Tree


* **PR #12615** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

---------

Co-authored-by: LongYinan <lynweklm@gmail.com>
2025-06-18 13:57:01 +08:00

191 lines
7.1 KiB
TypeScript

/* auto-generated by NAPI-RS */
/* eslint-disable */
export declare class ApplicationInfo {
processId: number
name: string
objectId: number
constructor(processId: number, name: string, objectId: number)
get processGroupId(): number
get bundleIdentifier(): string
get icon(): Buffer
}
export declare class ApplicationListChangedSubscriber {
unsubscribe(): void
}
export declare class ApplicationStateChangedSubscriber {
unsubscribe(): void
}
export declare class AudioCaptureSession {
get sampleRate(): number
get channels(): number
get actualSampleRate(): number
stop(): void
}
export declare class ShareableContent {
static onApplicationListChanged(callback: ((err: Error | null, ) => void)): ApplicationListChangedSubscriber
static onAppStateChanged(app: ApplicationInfo, callback: ((err: Error | null, ) => void)): ApplicationStateChangedSubscriber
constructor()
static applications(): Array<ApplicationInfo>
static applicationWithProcessId(processId: number): ApplicationInfo | null
static tapAudio(processId: number, audioStreamCallback: ((err: Error | null, arg: Float32Array) => void)): AudioCaptureSession
static tapGlobalAudio(excludedProcesses: Array<ApplicationInfo> | undefined | null, audioStreamCallback: ((err: Error | null, arg: Float32Array) => void)): AudioCaptureSession
static isUsingMicrophone(processId: number): boolean
}
export declare function decodeAudio(buf: Uint8Array, destSampleRate?: number | undefined | null, filename?: string | undefined | null, signal?: AbortSignal | undefined | null): Promise<Float32Array>
/** Decode audio file into a Float32Array */
export declare function decodeAudioSync(buf: Uint8Array, destSampleRate?: number | undefined | null, filename?: string | undefined | null): Float32Array
export declare function mintChallengeResponse(resource: string, bits?: number | undefined | null): Promise<string>
export declare function verifyChallengeResponse(response: string, bits: number, resource: string): Promise<boolean>
export declare class DocStorage {
constructor(path: string)
validate(): Promise<boolean>
setSpaceId(spaceId: string): Promise<void>
}
export declare class DocStoragePool {
constructor()
/** Initialize the database and run migrations. */
connect(universalId: string, path: string): Promise<void>
disconnect(universalId: string): Promise<void>
checkpoint(universalId: string): Promise<void>
setSpaceId(universalId: string, spaceId: string): Promise<void>
pushUpdate(universalId: string, docId: string, update: Uint8Array): Promise<Date>
getDocSnapshot(universalId: string, docId: string): Promise<DocRecord | null>
setDocSnapshot(universalId: string, snapshot: DocRecord): Promise<boolean>
getDocUpdates(universalId: string, docId: string): Promise<Array<DocUpdate>>
markUpdatesMerged(universalId: string, docId: string, updates: Array<Date>): Promise<number>
deleteDoc(universalId: string, docId: string): Promise<void>
getDocClocks(universalId: string, after?: Date | undefined | null): Promise<Array<DocClock>>
getDocClock(universalId: string, docId: string): Promise<DocClock | null>
getBlob(universalId: string, key: string): Promise<Blob | null>
setBlob(universalId: string, blob: SetBlob): Promise<void>
deleteBlob(universalId: string, key: string, permanently: boolean): Promise<void>
releaseBlobs(universalId: string): Promise<void>
listBlobs(universalId: string): Promise<Array<ListedBlob>>
getPeerRemoteClocks(universalId: string, peer: string): Promise<Array<DocClock>>
getPeerRemoteClock(universalId: string, peer: string, docId: string): Promise<DocClock | null>
setPeerRemoteClock(universalId: string, peer: string, docId: string, clock: Date): Promise<void>
getPeerPulledRemoteClocks(universalId: string, peer: string): Promise<Array<DocClock>>
getPeerPulledRemoteClock(universalId: string, peer: string, docId: string): Promise<DocClock | null>
setPeerPulledRemoteClock(universalId: string, peer: string, docId: string, clock: Date): Promise<void>
getPeerPushedClocks(universalId: string, peer: string): Promise<Array<DocClock>>
getPeerPushedClock(universalId: string, peer: string, docId: string): Promise<DocClock | null>
setPeerPushedClock(universalId: string, peer: string, docId: string, clock: Date): Promise<void>
clearClocks(universalId: string): Promise<void>
setBlobUploadedAt(universalId: string, peer: string, blobId: string, uploadedAt?: Date | undefined | null): Promise<void>
getBlobUploadedAt(universalId: string, peer: string, blobId: string): Promise<Date | null>
}
export interface Blob {
key: string
data: Uint8Array
mime: string
size: number
createdAt: Date
}
export interface DocClock {
docId: string
timestamp: Date
}
export interface DocRecord {
docId: string
bin: Uint8Array
timestamp: Date
}
export interface DocUpdate {
docId: string
timestamp: Date
bin: Uint8Array
}
export interface ListedBlob {
key: string
size: number
mime: string
createdAt: Date
}
export interface SetBlob {
key: string
data: Uint8Array
mime: string
}
export declare class SqliteConnection {
constructor(path: string)
connect(): Promise<void>
addBlob(key: string, blob: Uint8Array): Promise<void>
getBlob(key: string): Promise<BlobRow | null>
deleteBlob(key: string): Promise<void>
getBlobKeys(): Promise<Array<string>>
getUpdates(docId?: string | undefined | null): Promise<Array<UpdateRow>>
getDocTimestamps(): Promise<Array<DocTimestampRow>>
deleteUpdates(docId?: string | undefined | null): Promise<void>
getUpdatesCount(docId?: string | undefined | null): Promise<number>
getAllUpdates(): Promise<Array<UpdateRow>>
insertUpdates(updates: Array<InsertRow>): Promise<void>
replaceUpdates(docId: string | undefined | null, updates: Array<InsertRow>): Promise<void>
getServerClock(key: string): Promise<BlobRow | null>
setServerClock(key: string, data: Uint8Array): Promise<void>
getServerClockKeys(): Promise<Array<string>>
clearServerClock(): Promise<void>
delServerClock(key: string): Promise<void>
getSyncMetadata(key: string): Promise<BlobRow | null>
setSyncMetadata(key: string, data: Uint8Array): Promise<void>
getSyncMetadataKeys(): Promise<Array<string>>
clearSyncMetadata(): Promise<void>
delSyncMetadata(key: string): Promise<void>
initVersion(): Promise<void>
setVersion(version: number): Promise<void>
getMaxVersion(): Promise<number>
close(): Promise<void>
get isClose(): boolean
static validate(path: string): Promise<ValidationResult>
migrateAddDocId(): Promise<void>
/**
* Flush the WAL file to the database file.
* See https://www.sqlite.org/pragma.html#pragma_wal_checkpoint:~:text=PRAGMA%20schema.wal_checkpoint%3B
*/
checkpoint(): Promise<void>
}
export interface BlobRow {
key: string
data: Buffer
timestamp: Date
}
export interface DocTimestampRow {
docId?: string
timestamp: Date
}
export interface InsertRow {
docId?: string
data: Uint8Array
}
export interface UpdateRow {
id: number
timestamp: Date
data: Buffer
docId?: string
}
export declare enum ValidationResult {
MissingTables = 0,
MissingDocIdColumn = 1,
MissingVersionColumn = 2,
GeneralError = 3,
Valid = 4
}