refactor(audio-pipelines-transcribe): use @proj-airi/audio (#1990)
--------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by-agent: Codex
This commit is contained in:
+2
-1
@@ -34,7 +34,8 @@
|
||||
"build:packages": "turbo run build -F=\"./packages/*\"",
|
||||
"build:engines": "turbo run build -F=\"./engines/*\"",
|
||||
"test": "vitest --coverage",
|
||||
"test:run": "vitest run && pnpm run test-vishot:run && pnpm run test-ui:run",
|
||||
"test:run": "vitest run && pnpm run test-audio-pipelines-transcribe:run && pnpm run test-vishot:run && pnpm run test-ui:run",
|
||||
"test-audio-pipelines-transcribe:run": "vitest run --config packages/audio-pipelines-transcribe/vitest.config.ts",
|
||||
"test-vishot:run": "vitest run --config packages/vishot-runtime/vitest.config.ts",
|
||||
"test-ui:run": "vitest run --config packages/stage-ui/vitest.config.ts",
|
||||
"lint": "moeru-lint .",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@moeru/std": "catalog:",
|
||||
"@proj-airi/audio": "workspace:^",
|
||||
"uncrypto": "catalog:"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './utils'
|
||||
@@ -0,0 +1,31 @@
|
||||
import { toWav } from '@proj-airi/audio/encoding'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { mediaStreamFromAudioFile } from '.'
|
||||
|
||||
function createSineWaveFile() {
|
||||
const sampleRate = 44_100
|
||||
const durationSeconds = 0.05
|
||||
const sampleCount = Math.floor(sampleRate * durationSeconds)
|
||||
const samples = new Float32Array(sampleCount)
|
||||
|
||||
for (let index = 0; index < sampleCount; index += 1) {
|
||||
const phase = (index / sampleRate) * 440 * Math.PI * 2
|
||||
samples[index] = Math.sin(phase)
|
||||
}
|
||||
|
||||
return new File([toWav(samples.buffer, sampleRate)], 'tone.wav', { type: 'audio/wav' })
|
||||
}
|
||||
|
||||
describe('mediaStreamFromAudioFile', () => {
|
||||
it('decodes a browser audio file into a media stream and releases resources', async () => {
|
||||
const result = await mediaStreamFromAudioFile(createSineWaveFile())
|
||||
|
||||
expect(result.stream).toBeInstanceOf(MediaStream)
|
||||
expect(result.stream.getAudioTracks()).toHaveLength(1)
|
||||
|
||||
await result.cleanup()
|
||||
|
||||
expect(result.stream.getAudioTracks()[0]?.readyState).toBe('ended')
|
||||
})
|
||||
})
|
||||
@@ -1,5 +1,12 @@
|
||||
import { tryCatch } from '@moeru/std'
|
||||
|
||||
/**
|
||||
* Decodes an audio file into a playable {@link MediaStream}.
|
||||
*
|
||||
* Use this when browser transcription code needs to feed file-backed audio
|
||||
* into APIs that consume live media streams. The returned cleanup function
|
||||
* stops the one-shot buffer source and releases the owned {@link AudioContext}.
|
||||
*/
|
||||
export async function mediaStreamFromAudioFile(file: File): Promise<{
|
||||
cleanup: () => Promise<void>
|
||||
stream: MediaStream
|
||||
@@ -26,10 +33,15 @@ export async function mediaStreamFromAudioFile(file: File): Promise<{
|
||||
try {
|
||||
source.stop()
|
||||
}
|
||||
|
||||
catch { /* noop */ }
|
||||
catch {
|
||||
// `AudioBufferSourceNode.stop()` throws if playback already ended or
|
||||
// was stopped by the caller; cleanup should remain idempotent.
|
||||
}
|
||||
source.disconnect()
|
||||
destination.disconnect()
|
||||
for (const track of destination.stream.getTracks()) {
|
||||
track.stop()
|
||||
}
|
||||
await audioContext.close()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export default defineConfig(({ mode }) => ({
|
||||
browser: {
|
||||
provider: playwright(),
|
||||
enabled: true,
|
||||
// at least one instance is required
|
||||
// Vitest browser mode requires an explicit browser instance list.
|
||||
instances: [
|
||||
{ browser: 'chromium' },
|
||||
],
|
||||
|
||||
Generated
+3
@@ -3300,6 +3300,9 @@ importers:
|
||||
'@moeru/std':
|
||||
specifier: 'catalog:'
|
||||
version: 0.1.0-beta.17
|
||||
'@proj-airi/audio':
|
||||
specifier: workspace:^
|
||||
version: link:../audio
|
||||
uncrypto:
|
||||
specifier: 'catalog:'
|
||||
version: 0.1.3
|
||||
|
||||
@@ -7,7 +7,6 @@ export default defineConfig({
|
||||
'apps/ui-server-auth',
|
||||
'apps/ui-admin',
|
||||
'apps/stage-tamagotchi',
|
||||
'packages/audio-pipelines-transcribe',
|
||||
'packages/cap-vite',
|
||||
'packages/core-agent',
|
||||
'packages/vishot-runner-browser',
|
||||
|
||||
Reference in New Issue
Block a user