{"version":3,"sources":["../src/constants.ts","../src/edge-tts.ts","../src/generate-mp3.ts","../src/utils.ts"],"sourcesContent":["export enum OUTPUT_FORMAT {\n  AUDIO_24KHZ_48KBITRATE_MONO_MP3 = \"audio-24khz-48kbitrate-mono-mp3\",\n  AUDIO_24KHZ_96KBITRATE_MONO_MP3 = \"audio-24khz-96kbitrate-mono-mp3\",\n  WEBM_24KHZ_16BIT_MONO_OPUS = \"webm-24khz-16bit-mono-opus\",\n}\n\nexport enum PITCH {\n  X_LOW = \"x-low\",\n  LOW = \"low\",\n  MEDIUM = \"medium\",\n  HIGH = \"high\",\n  X_HIGH = \"x-high\",\n  DEFAULT = \"default\",\n}\n\nexport enum RATE {\n  X_SLOW = \"x-slow\",\n  SLOW = \"slow\",\n  MEDIUM = \"medium\",\n  FAST = \"fast\",\n  X_FAST = \"x-fast\",\n  DEFAULT = \"default\",\n}\n\nexport enum VOLUME {\n  SILENT = \"silent\",\n  X_SOFT = \"x-soft\",\n  SOFT = \"soft\",\n  MEDIUM = \"medium\",\n  LOUD = \"loud\",\n  X_LOUD = \"x-LOUD\",\n  DEFAULT = \"default\",\n}\n","import { Buffer } from 'buffer';\nimport type { PITCH, RATE, VOLUME } from './constants';\nimport { OUTPUT_FORMAT } from './constants';\nimport { WebSocket } from 'ws';\nimport fetch from 'node-fetch';\nimport { randomBytes } from 'crypto';\nimport { TextEncoder } from 'util';\n\n// Generates a random hex string of the specified length\nfunction generateRandomHex(length: number): string {\n  const randomBuffer = randomBytes(length);\n  return randomBuffer.toString('hex');\n}\n\ntype EventType = \"data\" | \"close\" | \"end\" | \"error\";\n\nclass EventEmitter {\n  private eventListeners: Record<EventType, ((...args: any[]) => void)[]>;\n\n  constructor() {\n    this.eventListeners = { data: [], close: [], end: [], error: [] };\n  }\n\n  on(event: EventType, callback: (...args: any[]) => void) {\n    this.eventListeners[event].push(callback);\n  }\n\n  emit(event: EventType, data: any) {\n    this.eventListeners[event].forEach((callback) => callback(data));\n  }\n}\n\nexport type Voice = {\n  Name: string;\n  ShortName: string;\n  Gender: string;\n  Locale: string;\n  SuggestedCodec: string;\n  FriendlyName: string;\n  Status: string;\n};\n\ntype Metadata = {\n  Type: \"WordBoundary\" | \"SentenceBoundary\";\n  Data: {\n    Offset: number;\n    Duration: number;\n    text: {\n      Text: string;\n      Length: number;\n      BoundaryType: \"WordBoundary\" | \"SentenceBoundary\";\n    };\n  };\n}[];\n\nexport class ProsodyOptions {\n  pitch: PITCH | string = \"+0Hz\";\n  rate: RATE | string | number = 1.0;\n  volume: VOLUME | string | number = 100.0;\n}\n\nexport class EdgeTTSClient {\n  static OUTPUT_FORMAT = OUTPUT_FORMAT;\n  private static CLIENT_TOKEN = \"6A5AA1D4EAFF4E9FB37E23D68491D6F4\";\n  private static VOICES_URL = `https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=${EdgeTTSClient.CLIENT_TOKEN}`;\n  private static SYNTH_URL = `wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1?TrustedClientToken=${EdgeTTSClient.CLIENT_TOKEN}`;\n  private static BINARY_DELIM = \"Path:audio\\r\\n\";\n  private static VOICE_LANG_REGEX = /\\w{2}-\\w{2}/;\n\n  private enableLogging: boolean;\n  private ws: WebSocket | null = null;\n  private voice: string | null = null;\n  private voiceLocale: string | null = null;\n  private outputFormat: OUTPUT_FORMAT | null = null;\n  private requestQueue: Record<string, EventEmitter> = {};\n  private connectionStartTime = 0;\n\n  constructor(enableLogging = false) {\n    this.enableLogging = enableLogging;\n  }\n\n  private log(...args: any[]) {\n    if (this.enableLogging) console.log(...args);\n  }\n\n  private async sendMessage(message: string) {\n    for (let attempt = 1; attempt <= 3 && (this.ws === null || this.ws.readyState !== WebSocket.OPEN); attempt++) {\n      if (attempt === 1) this.connectionStartTime = Date.now();\n      this.log(`Connecting... attempt ${attempt}`);\n      await this.initWebSocket();\n    }\n    this.ws?.send(message);\n  }\n\n  private initWebSocket() {\n    this.ws = new WebSocket(EdgeTTSClient.SYNTH_URL);\n    this.ws.binaryType = \"arraybuffer\";\n    let metadataBuffer: Metadata = [];\n\n    return new Promise<void>((resolve, reject) => {\n      this.ws!.onopen = () => {\n        this.log(\"Connected in\", (Date.now() - this.connectionStartTime) / 1000, \"seconds\");\n        this.sendMessage(this.getConfigMessage()).then(resolve);\n      };\n\n      this.ws!.onmessage = (event) => this.handleMessage(event, metadataBuffer);\n      this.ws!.onclose = () => this.handleClose();\n      this.ws!.onerror = (error: any) => reject(`Connection Error: ${error.message}`);\n    });\n  }\n\n  private handleMessage(event: any, metadataBuffer: Metadata) {\n    const buffer = Buffer.from(event.data as ArrayBuffer);\n    const message = buffer.toString();\n    const requestIdMatch = /X-RequestId:(.*?)\\r\\n/.exec(message);\n    const requestId = requestIdMatch ? requestIdMatch[1] : \"\";\n\n    if (message.includes(\"Path:turn.start\")) {\n      metadataBuffer.length = 0;\n    } else if (message.includes(\"Path:turn.end\")) {\n      this.requestQueue[requestId]?.emit(\"end\", metadataBuffer);\n    } else if (message.includes(\"Path:audio\")) {\n      this.cacheAudioData(buffer, requestId);\n    } else if (message.includes(\"Path:audio.metadata\")) {\n      const startIndex = message.indexOf(\"{\");\n      metadataBuffer.push(JSON.parse(message.slice(startIndex)).Metadata[0]);\n    } else {\n      this.log(\"Unknown Message\", message);\n    }\n  }\n\n  private handleClose() {\n    this.log(\"Disconnected after:\", (Date.now() - this.connectionStartTime) / 1000, \"seconds\");\n    for (const requestId in this.requestQueue) {\n      this.requestQueue[requestId].emit(\"close\", null);\n    }\n  }\n\n  private cacheAudioData(buffer: Buffer, requestId: string) {\n    // Convert the BINARY_DELIM string to a Uint8Array using TextEncoder\n    const binaryDelimBytes = new TextEncoder().encode(EdgeTTSClient.BINARY_DELIM);\n\n    // Use the helper function to find the delimiter index in the buffer\n    const delimiterIndex = this.findDelimiterIndex(buffer, binaryDelimBytes);\n    if (delimiterIndex === -1) {\n      this.log('Delimiter not found in the buffer.');\n      return;\n    }\n\n    const audioDataStart = delimiterIndex + binaryDelimBytes.length;\n    const audioData = buffer.subarray(audioDataStart); // Use subarray for Buffer\n    this.requestQueue[requestId]?.emit(\"data\", audioData);\n    this.log(\"Received audio chunk of size:\", audioData?.length);\n  }\n\n  // Helper function to find the index of a byte sequence within another byte sequence\n  private findDelimiterIndex(buffer: Buffer, delimiter: Uint8Array): number {\n    for (let i = 0; i <= buffer.length - delimiter.length; i++) {\n      let match = true;\n      for (let j = 0; j < delimiter.length; j++) {\n        if (buffer[i + j] !== delimiter[j]) {\n          match = false;\n          break;\n        }\n      }\n      if (match) return i;\n    }\n    return -1;\n  }\n\n  private getConfigMessage(): string {\n    return `Content-Type:application/json; charset=utf-8\\r\\nPath:speech.config\\r\\n\\r\\n{\n            \"context\": {\n                \"synthesis\": {\n                    \"audio\": {\n                        \"metadataoptions\": {\n                            \"sentenceBoundaryEnabled\": \"true\",\n                            \"wordBoundaryEnabled\": \"true\"\n                        },\n                        \"outputFormat\": \"${this.outputFormat}\"\n                    }\n                }\n            }\n        }`;\n  }\n\n  async getVoices(): Promise<Voice[]> {\n    try {\n      const response = await fetch(EdgeTTSClient.VOICES_URL);\n      if (!response.ok) {\n        throw new Error(`HTTP error! status: ${response.status}`);\n      }\n      return await response.json() as Voice[];\n    } catch (error) {\n      return Promise.reject(error);\n    }\n  }\n\n  async setMetadata(voiceName: string, outputFormat: OUTPUT_FORMAT, voiceLocale?: string) {\n    this.voice = voiceName;\n    this.outputFormat = outputFormat;\n    this.voiceLocale = voiceLocale || this.inferLocaleFromVoiceName(voiceName);\n\n    if (!this.voiceLocale) {\n      throw new Error(\"Could not infer voiceLocale from voiceName!\");\n    }\n\n    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n      this.connectionStartTime = Date.now();\n      await this.initWebSocket();\n    }\n  }\n\n  private inferLocaleFromVoiceName(voiceName: string): string | null {\n    const match = EdgeTTSClient.VOICE_LANG_REGEX.exec(voiceName);\n    return match ? match[0] : null;\n  }\n\n  close() {\n    this.ws?.close();\n  }\n\n  toStream(text: string, options: ProsodyOptions = new ProsodyOptions()): EventEmitter {\n    return this.sendSSMLRequest(this.buildSSML(text, options));\n  }\n\n  private buildSSML(text: string, options: ProsodyOptions): string {\n    return `<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"https://www.w3.org/2001/mstts\" xml:lang=\"${this.voiceLocale}\">\n            <voice name=\"${this.voice}\">\n                <prosody pitch=\"${options.pitch}\" rate=\"${options.rate}\" volume=\"${options.volume}\">\n                    ${text}\n                </prosody>\n            </voice>\n        </speak>`;\n  }\n\n  private sendSSMLRequest(ssml: string): EventEmitter {\n    if (!this.ws) {\n      throw new Error(\"WebSocket not initialized. Call setMetadata first.\");\n    }\n\n    const requestId = generateRandomHex(16);\n    const requestMessage = `X-RequestId:${requestId}\\r\\nContent-Type:application/ssml+xml\\r\\nPath:ssml\\r\\n\\r\\n${ssml.trim()}`;\n\n    const eventEmitter = new EventEmitter();\n    this.requestQueue[requestId] = eventEmitter;\n    this.sendMessage(requestMessage).then();\n\n    return eventEmitter;\n  }\n}","import * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { EdgeTTSClient, ProsodyOptions, Voice } from './edge-tts';\nimport { OUTPUT_FORMAT } from './constants';\nimport { filterMarkdown } from './utils';\n\nconst DEFAULT_OPTIONS: TextToSpeechOptions = {\n  voice: 'en-GB-RyanNeural',\n  speed: 1.1,\n  enableLogging: false,\n  disableFilter: false,\n}\n\nexport type TextToSpeechOptions = {\n  voice?: string;\n  speed?: number;\n  enableLogging?: boolean;\n  disableFilter?: boolean;\n}\n\nexport type TextToSpeechProps = {\n  text: string;\n  outputPath: string;\n  fileName: string;\n  options?: TextToSpeechOptions;\n}\n\nexport async function textToSpeechMp3({\n  text,\n  outputPath,\n  fileName,\n  options = DEFAULT_OPTIONS,\n}: TextToSpeechProps): Promise<void> {\n\n  const client = new EdgeTTSClient(options.enableLogging);\n\n  try {\n    // Ensure fileName ends with .mp3\n    const finalFileName = fileName.toLowerCase().endsWith('.mp3')\n      ? fileName\n      : `${fileName}.mp3`;\n\n    // Combine directory path and filename\n    const fullOutputPath = path.join(outputPath, finalFileName);\n\n    // Create output directory if it doesn't exist\n    await fs.mkdir(outputPath, { recursive: true });\n\n    // Not necessary\n    // const voices = await client.getVoices();\n    // const voiceSelection: Voice | undefined = voices.find(v => v.ShortName === options.voice);\n\n    // if (!voiceSelection) {\n    //   throw new Error(`Voice with short name \"${voiceSelection}\" not found.`);\n    // }\n\n    await client.setMetadata(options.voice, OUTPUT_FORMAT.AUDIO_24KHZ_48KBITRATE_MONO_MP3);\n\n    const prosodyOptions = new ProsodyOptions();\n    prosodyOptions.rate = options.speed ?? DEFAULT_OPTIONS.speed;\n\n    if (!options.disableFilter) {\n      text = filterMarkdown(text);\n    }\n\n    const stream = client.toStream(text, prosodyOptions);\n\n    const chunks: Buffer[] = [];\n    stream.on('data', (chunk: Buffer) => {\n      chunks.push(chunk);\n    });\n\n    return new Promise<void>((resolve, reject) => {\n      stream.on('end', async () => {\n        const audioBuffer = Buffer.concat(chunks);\n\n        try {\n          await fs.writeFile(fullOutputPath, audioBuffer);\n          console.log(`Audio saved to ${fullOutputPath}`);\n          resolve();\n        } catch (err) {\n          console.error('Error writing audio to file:', err);\n          reject(err);\n        } finally {\n          client.close();\n        }\n      });\n\n      stream.on('error', (error: any) => {\n        console.error('Stream error:', error);\n        client.close();\n        reject(error);\n      });\n    });\n\n  } catch (error) {\n    console.error('Error during text-to-speech:', error);\n    client.close();\n    throw error;\n  }\n}\n\nexport type TextToSpeechInput = {\n  text: string;\n  title: string;\n  options?: TextToSpeechOptions;\n}\n\nexport async function batchTextToSpeechMp3(\n  inputs: TextToSpeechInput[],\n  outputPath: string,\n  globalOptions: TextToSpeechOptions = DEFAULT_OPTIONS\n): Promise<void> {\n  // Create output directory if it doesn't exist\n  await fs.mkdir(outputPath, { recursive: true });\n\n  // Process all inputs sequentially to avoid overwhelming the TTS service\n  for (const input of inputs) {\n    try {\n      await textToSpeechMp3({\n        text: input.text,\n        outputPath,\n        fileName: input.title,\n        options: {\n          ...globalOptions,\n          ...input.options || {},\n        }\n      });\n    } catch (error) {\n      console.error(`Failed to process \"${input.title}\":`, error);\n      // Continue with next item even if one fails\n    }\n  }\n}\n\n// Example usage:\n// async function runBatchExample() {\n//   const inputs: TextToSpeechInput[] = [\n//     {\n//       text: \"This is the first audio file\",\n//       title: \"first-audio\",\n//       options: { voice: 'en-US-GuyNeural', speed: 1.0 }\n//     },\n//     {\n//       text: \"This is the second audio file\",\n//       title: \"second-audio\"\n//     }\n//   ];\n//\n//   const outputDir = './output';\n//\n//   try {\n//     await batchTextToSpeechMp3(\n//       inputs,\n//       outputDir,\n//       { \n//         voice: 'en-GB-RyanNeural',\n//         speed: 1.2,\n//         enableLogging: true \n//       }\n//     );\n//     console.log('Batch text-to-speech conversion completed!');\n//   } catch (error) {\n//     console.error('Batch conversion failed:', error);\n//   }\n// }","/* eslint-disable @typescript-eslint/no-inferrable-types */\n/* eslint-disable no-useless-escape */\n\n/**\n * Filters out the frontmatter from a Markdown text.\n * Frontmatter is defined as a block of YAML enclosed by `---` or `...` at the start of the file.\n * @param text - The Markdown text from which to remove frontmatter.\n * @returns The text without the frontmatter block.\n */\nexport function filterFrontmatter(text: string): string {\n  // Define the regular expression for frontmatter blocks\n  const frontmatterRegex = /^(---|\\.\\.\\.)([\\s\\S]*?)\\1\\n?/;\n\n  // Remove frontmatter if it exists\n  return text.replace(frontmatterRegex, '').trim();\n}\n\nexport function replaceComparisonSymbols(text: string): string {\n  return text\n    .replace(/>=/g, '≥') // Replace \">=\" with \"≥\"\n    .replace(/<=/g, '≤'); // Replace \"<=\" with \"≤\"\n}\n\nexport function escapeAmpersand(text: string): string {\n  return text.replace(/&/g, '&amp;')  // Escape '&'\n}\n\nexport function escapeXml(text: string): string {\n  return text\n    // .replace(/&/g, '&amp;')  // Escape '&' first to avoid double escaping\n    .replace(/</g, '&lt;')   // Escape '<'\n    .replace(/>/g, '&gt;')   // Escape '>'\n    .replace(/\"/g, '&quot;') // Escape '\"'\n    .replace(/'/g, '&apos;'); // Escape \"'\"\n}\n\nexport function filterMarkdown(text: string, overrideAmpersandEscape = false): string {\n  // Remove frontmatter (e.g., YAML between triple dashes \"---\")\n  const noFrontmatter = text.replace(/^-{3}[\\s\\S]*?-{3}\\n?/, '');\n\n  // Remove URLs\n  const noUrls = noFrontmatter.replace(/https?:\\/\\/[^\\s]+/g, '');\n\n  // Remove code blocks (e.g., fenced with ``` or indented by 4 spaces)\n  const noCodeBlocks = noUrls.replace(/```[\\s\\S]*?```/g, '').replace(/^( {4}|\\t).+/gm, '');\n\n  // Remove inline markdown syntax\n  let cleanedMarkdown = noCodeBlocks\n    // Remove bold (**text** or __text__) and italics (*text* or _text_)\n    .replace(/(\\*\\*|__)(.*?)\\1/g, '$2') // Bold\n    .replace(/(\\*|_)(.*?)\\1/g, '$2')   // Italics\n    // Remove inline code markers (`code`)\n    .replace(/`([^`]*)`/g, '$1')\n    // Remove strikethrough (~~text~~)\n    .replace(/~~(.*?)~~/g, '$1')\n    // Remove other markdown characters (e.g., #, -, *, etc., not part of inline code)\n    .replace(/^[#*-]+\\s*/gm, '')\n    // Remove unordered list markers (e.g., \"- \", \"* \", \"+ \")\n    .replace(/^[\\-\\+\\*]\\s+/gm, '')\n    // Remove ordered list numbers (e.g., \"1. \", \"2. \")\n    .replace(/^\\d+\\.\\s+/gm, '')\n    // Remove blockquote markers (e.g., \"> \") only at the start of a line\n    .replace(/^>\\s+/gm, '')\n    // Remove horizontal rules (e.g., \"---\", \"***\")\n    .replace(/^[-*]{3,}\\s*$/gm, '');\n\n  cleanedMarkdown = replaceComparisonSymbols(cleanedMarkdown);\n\n  // Remove HTML tags explicitly while preserving `<` and `>` symbols in text\n  cleanedMarkdown = cleanedMarkdown.replace(/<([^>\\s]+)[^>]*>/g, '');\n\n  // Trim leading and trailing whitespace and escape '&' if indicated\n  cleanedMarkdown = (overrideAmpersandEscape) ? cleanedMarkdown.trim() : escapeAmpersand(cleanedMarkdown.trim());\n\n  const finalText = escapeXml(cleanedMarkdown);\n\n  return finalText;\n}"],"mappings":"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","names":["OUTPUT_FORMAT","PITCH","RATE","VOLUME","Buffer","Buffer"]}