mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-12 16:55:37 +02:00
✨ feat: Host a relay on Hetzner (#114)
We are hosting a [MoQ](https://quic.video) relay on a remote (bare metal) server on Hetzner With a lot of help from @victorpahuus
This commit is contained in:
75
packages/moq/contribute/audio.ts
Normal file
75
packages/moq/contribute/audio.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
const SUPPORTED = [
|
||||
// TODO support AAC
|
||||
// "mp4a"
|
||||
"Opus",
|
||||
]
|
||||
|
||||
export class Encoder {
|
||||
#encoder!: AudioEncoder
|
||||
#encoderConfig: AudioEncoderConfig
|
||||
#decoderConfig?: AudioDecoderConfig
|
||||
|
||||
frames: TransformStream<AudioData, AudioDecoderConfig | EncodedAudioChunk>
|
||||
|
||||
constructor(config: AudioEncoderConfig) {
|
||||
this.#encoderConfig = config
|
||||
|
||||
this.frames = new TransformStream({
|
||||
start: this.#start.bind(this),
|
||||
transform: this.#transform.bind(this),
|
||||
flush: this.#flush.bind(this),
|
||||
})
|
||||
}
|
||||
|
||||
#start(controller: TransformStreamDefaultController<AudioDecoderConfig | EncodedAudioChunk>) {
|
||||
this.#encoder = new AudioEncoder({
|
||||
output: (frame, metadata) => {
|
||||
this.#enqueue(controller, frame, metadata)
|
||||
},
|
||||
error: (err) => {
|
||||
throw err
|
||||
},
|
||||
})
|
||||
|
||||
this.#encoder.configure(this.#encoderConfig)
|
||||
}
|
||||
|
||||
#transform(frame: AudioData) {
|
||||
this.#encoder.encode(frame)
|
||||
frame.close()
|
||||
}
|
||||
|
||||
#enqueue(
|
||||
controller: TransformStreamDefaultController<AudioDecoderConfig | EncodedAudioChunk>,
|
||||
frame: EncodedAudioChunk,
|
||||
metadata?: EncodedAudioChunkMetadata,
|
||||
) {
|
||||
const config = metadata?.decoderConfig
|
||||
if (config && !this.#decoderConfig) {
|
||||
const config = metadata.decoderConfig
|
||||
if (!config) throw new Error("missing decoder config")
|
||||
|
||||
controller.enqueue(config)
|
||||
this.#decoderConfig = config
|
||||
}
|
||||
|
||||
controller.enqueue(frame)
|
||||
}
|
||||
|
||||
#flush() {
|
||||
this.#encoder.close()
|
||||
}
|
||||
|
||||
static async isSupported(config: AudioEncoderConfig) {
|
||||
// Check if we support a specific codec family
|
||||
const short = config.codec.substring(0, 4)
|
||||
if (!SUPPORTED.includes(short)) return false
|
||||
|
||||
const res = await AudioEncoder.isConfigSupported(config)
|
||||
return !!res.supported
|
||||
}
|
||||
|
||||
get config() {
|
||||
return this.#encoderConfig
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user