refactor(audio-pipelines-transcribe): remove package
This commit is contained in:
@@ -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' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}))
|
||||
Generated
-12
@@ -3500,18 +3500,6 @@ importers:
|
||||
specifier: 'catalog:'
|
||||
version: 3.5.41(typescript@6.0.3)
|
||||
|
||||
packages/audio-pipelines-transcribe:
|
||||
dependencies:
|
||||
'@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
|
||||
|
||||
packages/better-ws:
|
||||
dependencies:
|
||||
'@moeru/eventa':
|
||||
|
||||
Reference in New Issue
Block a user