refactor(audio-pipelines-transcribe): remove package

This commit is contained in:
Neko Ayaka
2026-08-29 18:28:08 +08:00
parent 9ebce86a9a
commit 7bf1dc6ae6
7 changed files with 0 additions and 169 deletions
@@ -1,15 +0,0 @@
{
"name": "@proj-airi/audio-pipelines-transcribe",
"type": "module",
"private": true,
"exports": "./src/index.ts",
"scripts": {
"test": "vitest",
"test:run": "vitest run"
},
"dependencies": {
"@moeru/std": "catalog:",
"@proj-airi/audio": "workspace:^",
"uncrypto": "catalog:"
}
}
@@ -1 +0,0 @@
export * from './utils'
@@ -1,31 +0,0 @@
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,48 +0,0 @@
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
}> {
const audioContext = new AudioContext()
const arrayBuffer = await file.arrayBuffer()
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer)
const source = audioContext.createBufferSource()
source.buffer = audioBuffer
const destination = audioContext.createMediaStreamDestination()
source.connect(destination)
source.connect(audioContext.destination)
source.start(0)
await tryCatch(async () => {
await audioContext.resume()
})
return {
stream: destination.stream,
cleanup: async () => {
try {
source.stop()
}
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()
},
}
}
@@ -1,24 +0,0 @@
{
"compilerOptions": {
"target": "ESNext",
"lib": [
"ESNext",
"DOM",
"DOM.Iterable"
],
"module": "ESNext",
"moduleResolution": "bundler",
"types": [
"vitest",
"vite/client"
],
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
},
"include": [
"src/**/*.ts"
]
}
@@ -1,38 +0,0 @@
import { dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import { playwright } from '@vitest/browser-playwright'
import { loadEnv } from 'vite'
import { defineConfig } from 'vitest/config'
export default defineConfig(({ mode }) => ({
test: {
projects: [
{
test: {
name: 'node',
root: dirname(fileURLToPath(import.meta.url)),
env: loadEnv(mode, dirname(fileURLToPath(import.meta.url))),
exclude: ['**/*.browser.{spec,test}.ts', '**/node_modules/**'],
},
},
{
test: {
name: 'browser',
root: dirname(fileURLToPath(import.meta.url)),
include: ['**/*.browser.{spec,test}.ts'],
exclude: ['**/node_modules/**'],
browser: {
provider: playwright(),
enabled: true,
headless: true,
// Vitest browser mode requires an explicit browser instance list.
instances: [
{ browser: 'chromium' },
],
},
},
},
],
},
}))