fix(speech): surface streaming playback compatibility
This commit is contained in:
58
packages/ui/src/lib/speech-playback-support.ts
Normal file
58
packages/ui/src/lib/speech-playback-support.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import type { SpeechCapabilitiesResponse } from "../../../server/src/api-types"
|
||||
import type { SpeechPlaybackMode, SpeechTtsFormat } from "../stores/preferences"
|
||||
|
||||
export interface SpeechPlaybackSupportResult {
|
||||
available: boolean
|
||||
reason?: "unsupported-environment" | "provider-streaming-unavailable" | "browser-streaming-unavailable"
|
||||
}
|
||||
|
||||
export function formatToMimeType(format: SpeechTtsFormat): string {
|
||||
if (format === "wav") return "audio/wav"
|
||||
if (format === "opus") return getSupportedMimeType(format)
|
||||
if (format === "aac") return "audio/aac"
|
||||
return "audio/mpeg"
|
||||
}
|
||||
|
||||
export function getCandidateMimeTypes(format: SpeechTtsFormat): string[] {
|
||||
if (format === "wav") return ["audio/wav"]
|
||||
if (format === "opus") {
|
||||
return ['audio/ogg; codecs="opus"', 'audio/webm; codecs="opus"', "audio/opus"]
|
||||
}
|
||||
if (format === "aac") return ["audio/aac", "audio/mp4", 'audio/mp4; codecs="mp4a.40.2"']
|
||||
return ["audio/mpeg"]
|
||||
}
|
||||
|
||||
export function getSupportedMimeType(format: SpeechTtsFormat): string {
|
||||
const candidates = getCandidateMimeTypes(format)
|
||||
if (typeof MediaSource === "undefined") {
|
||||
return candidates[0]
|
||||
}
|
||||
return candidates.find((candidate) => MediaSource.isTypeSupported(candidate)) ?? candidates[0]
|
||||
}
|
||||
|
||||
export function getSpeechPlaybackSupport(options: {
|
||||
playbackMode: SpeechPlaybackMode
|
||||
ttsFormat: SpeechTtsFormat
|
||||
capabilities?: SpeechCapabilitiesResponse | null
|
||||
}): SpeechPlaybackSupportResult {
|
||||
if (typeof window === "undefined" || typeof window.Audio === "undefined") {
|
||||
return { available: false, reason: "unsupported-environment" }
|
||||
}
|
||||
|
||||
if (options.playbackMode !== "streaming") {
|
||||
return { available: true }
|
||||
}
|
||||
|
||||
if (!options.capabilities?.supportsStreamingTts) {
|
||||
return { available: false, reason: "provider-streaming-unavailable" }
|
||||
}
|
||||
|
||||
if (
|
||||
typeof MediaSource === "undefined" ||
|
||||
!getCandidateMimeTypes(options.ttsFormat).some((candidate) => MediaSource.isTypeSupported(candidate))
|
||||
) {
|
||||
return { available: false, reason: "browser-streaming-unavailable" }
|
||||
}
|
||||
|
||||
return { available: true }
|
||||
}
|
||||
Reference in New Issue
Block a user