{"version":3,"sources":["../src/index.ts","../src/utils/packagePaths.ts"],"sourcesContent":["import os from \"node:os\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport * as macosVersion from \"macos-version\";\nimport { execa, type ExecaChildProcess } from \"execa\";\nimport { resolvePackagePath } from \"./utils/packagePaths.js\";\nconst BIN = resolvePackagePath(\"./screencapturekit\"); // Simplified path\n\n/**\n * Generates a random identifier composed of alphanumeric characters.\n * @returns {string} A random identifier as a string.\n * @private\n */\nconst getRandomId = () => Math.random().toString(36).slice(2, 15);\n\n/**\n * Checks if the system supports HEVC (H.265) hardware encoding.\n * @returns {boolean} True if the system supports HEVC hardware encoding, false otherwise.\n * @private\n */\nconst supportsHevcHardwareEncoding = (() => {\n  const cpuModel = os.cpus()[0].model;\n\n  // All Apple silicon Macs support HEVC hardware encoding.\n  if (cpuModel.startsWith(\"Apple \")) {\n    // Source string example: 'Apple M1'\n    return true;\n  }\n\n  // Get the Intel Core generation, the `4` in `Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz`\n  // More info: https://www.intel.com/content/www/us/en/processors/processor-numbers.html\n  // Example strings:\n  // - `Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz`\n  // - `Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz`\n  const result = /Intel.*Core.*i\\d+-(\\d)/.exec(cpuModel);\n\n  // Intel Core generation 6 or higher supports HEVC hardware encoding\n  return result && Number.parseInt(result[1], 10) >= 6;\n})();\n\n/**\n * Checks if the system supports HDR capture.\n * @returns {boolean} True if the system supports HDR capture (macOS 13.0+), false otherwise.\n * @private\n */\nconst supportsHDR = (() => {\n  return macosVersion.isMacOSVersionGreaterThanOrEqualTo(\"13.0\"); // HDR requires macOS 13.0+ (Ventura)\n})();\n\n/**\n * Checks if the system supports the direct recording API.\n * @returns {boolean} True if the system supports direct recording API (macOS 15.0+), false otherwise.\n * @private\n */\nconst supportsDirectRecordingAPI = (() => {\n  return macosVersion.isMacOSVersionGreaterThanOrEqualTo(\"15.0\"); // Direct Recording API requires macOS 15.0+\n})();\n\n/**\n * Checks if the system supports microphone capture.\n * @returns {boolean} True if the system supports microphone capture (macOS 15.0+), false otherwise.\n * @private\n */\nconst supportsMicrophoneCapture = (() => {\n  return macosVersion.isMacOSVersionGreaterThanOrEqualTo(\"15.0\"); // Microphone support with SCStream requires macOS 15.0+\n})();\n\n/**\n * Interface defining a cropping area for recording.\n * @typedef {Object} CropArea\n * @property {number} x - The X position of the starting point of the area.\n * @property {number} y - The Y position of the starting point of the area.\n * @property {number} width - The width of the area to capture.\n * @property {number} height - The height of the area to capture.\n */\ntype CropArea = {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n};\n\nexport type { CropArea };\n\ntype Screen = {\n  id: number;\n  width: number;\n  height: number;\n};\n\nexport type { Screen };\n\ntype AudioDevice = {\n  id: string;\n  name: string;\n  manufacturer: string;\n};\n\nexport type { AudioDevice };\n\ntype MicrophoneDevice = AudioDevice;\n\nexport type { MicrophoneDevice };\n\n/**\n * Options for screen recording.\n * @typedef {Object} RecordingOptions\n * @property {number} fps - Frames per second.\n * @property {CropArea} [cropArea] - Area of the screen to capture.\n * @property {boolean} showCursor - Show the cursor in the recording.\n * @property {boolean} highlightClicks - Highlight mouse clicks.\n * @property {number} screenId - Identifier of the screen to capture.\n * @property {string} [audioDeviceId] - Identifier of the system audio device.\n * @property {string} [microphoneDeviceId] - Identifier of the microphone device.\n * @property {string} videoCodec - Video codec to use.\n * @property {boolean} [enableHDR] - Enable HDR recording (on macOS 13.0+).\n * @property {boolean} [recordToFile] - Use the direct recording API (on macOS 14.0+).\n * @property {boolean} [audioOnly] - Record audio only, will convert to mp3 after recording.\n */\ntype RecordingOptions = {\n  fps: number;\n  cropArea?: CropArea;\n  showCursor: boolean;\n  highlightClicks: boolean;\n  screenId: number;\n  audioDeviceId?: string;\n  microphoneDeviceId?: string;\n  videoCodec?: string;\n  enableHDR?: boolean;\n  recordToFile?: boolean;\n  audioOnly?: boolean;\n};\n\nexport type { RecordingOptions };\n\n/**\n * Internal options for recording with ScreenCaptureKit.\n * @typedef {Object} RecordingOptionsForScreenCaptureKit\n * @property {string} destination - URL of the destination file.\n * @property {number} framesPerSecond - Frames per second.\n * @property {boolean} showCursor - Show the cursor in the recording.\n * @property {boolean} highlightClicks - Highlight mouse clicks.\n * @property {number} screenId - Identifier of the screen to capture.\n * @property {string} [audioDeviceId] - Identifier of the system audio device.\n * @property {string} [microphoneDeviceId] - Identifier of the microphone device.\n * @property {string} [videoCodec] - Video codec to use.\n * @property {Array} [cropRect] - Coordinates of the cropping area.\n * @property {boolean} [enableHDR] - Enable HDR recording.\n * @property {boolean} [useDirectRecordingAPI] - Use the direct recording API.\n * @private\n */\ntype RecordingOptionsForScreenCaptureKit = {\n  destination: string;\n  framesPerSecond: number;\n  showCursor: boolean;\n  highlightClicks: boolean;\n  screenId: number;\n  audioDeviceId?: string;\n  microphoneDeviceId?: string;\n  videoCodec?: string;\n  cropRect?: [[x: number, y: number], [width: number, height: number]];\n  enableHDR?: boolean;\n  useDirectRecordingAPI?: boolean;\n};\n\nexport type { RecordingOptionsForScreenCaptureKit };\n\n/**\n * Main class for screen recording with ScreenCaptureKit.\n * Allows capturing the screen using Apple's native APIs.\n */\nexport class ScreenCaptureKit {\n  /** Path to the output video file. */\n  videoPath: string | null = null;\n  /** The ongoing recording process. */\n  recorder?: ExecaChildProcess;\n  /** Unique identifier of the recording process. */\n  processId: string | null = null;\n  /** Options used for recording */\n  private currentOptions?: Partial<RecordingOptions>;\n  /** Path to the final processed video file */\n  processedVideoPath: string | null = null;\n\n  /**\n   * Creates a new instance of ScreenCaptureKit.\n   * Checks that the macOS version is compatible (10.13+).\n   * @throws {Error} If the macOS version is not supported.\n   */\n  constructor() {\n    macosVersion.assertMacOSVersionGreaterThanOrEqualTo(\"10.13\");\n  }\n\n  /**\n   * Checks that recording has been started.\n   * @throws {Error} If recording has not been started.\n   * @private\n   */\n  throwIfNotStarted() {\n    if (this.recorder === undefined) {\n      throw new Error(\"Call `.startRecording()` first\");\n    }\n  }\n\n  /**\n   * Starts screen recording.\n   * @param {Partial<RecordingOptions>} options - Recording options.\n   * @param {number} [options.fps=30] - Frames per second.\n   * @param {CropArea} [options.cropArea] - Area of the screen to capture.\n   * @param {boolean} [options.showCursor=true] - Show the cursor.\n   * @param {boolean} [options.highlightClicks=false] - Highlight mouse clicks.\n   * @param {number} [options.screenId=0] - Screen ID to capture.\n   * @param {string} [options.audioDeviceId] - System audio device ID.\n   * @param {string} [options.microphoneDeviceId] - Microphone device ID.\n   * @param {string} [options.videoCodec=\"h264\"] - Video codec to use.\n   * @param {boolean} [options.enableHDR=false] - Enable HDR recording.\n   * @param {boolean} [options.recordToFile=false] - Use the direct recording API.\n   * @returns {Promise<void>} A promise that resolves when recording starts.\n   * @throws {Error} If recording is already in progress or if the options are invalid.\n   */\n  async startRecording({\n    fps = 30,\n    cropArea = undefined,\n    showCursor = true,\n    highlightClicks = false,\n    screenId = 0,\n    audioDeviceId = undefined,\n    microphoneDeviceId = undefined,\n    videoCodec = \"h264\",\n    enableHDR = false,\n    recordToFile = false,\n    audioOnly = false,\n  }: Partial<RecordingOptions> = {}) {\n    this.processId = getRandomId();\n    // Stocke les options actuelles pour utilisation ultérieure\n    this.currentOptions = {\n      fps,\n      cropArea,\n      showCursor,\n      highlightClicks,\n      screenId,\n      audioDeviceId,\n      microphoneDeviceId,\n      videoCodec,\n      enableHDR,\n      recordToFile,\n      audioOnly,\n    };\n    \n    return new Promise((resolve, reject) => {\n      if (this.recorder !== undefined) {\n        reject(new Error(\"Call `.stopRecording()` first\"));\n        return;\n      }\n\n      this.videoPath = createTempFile({ extension: \"mp4\" });\n      \n      console.log(this.videoPath);\n      const recorderOptions: RecordingOptionsForScreenCaptureKit = {\n        destination: fileUrlFromPath(this.videoPath as string),\n        framesPerSecond: fps,\n        showCursor,\n        highlightClicks,\n        screenId,\n        audioDeviceId,\n      };\n\n      if (highlightClicks === true) {\n        showCursor = true;\n      }\n\n      if (\n        typeof cropArea === \"object\" &&\n        (typeof cropArea.x !== \"number\" ||\n          typeof cropArea.y !== \"number\" ||\n          typeof cropArea.width !== \"number\" ||\n          typeof cropArea.height !== \"number\")\n      ) {\n        reject(new Error(\"Invalid `cropArea` option object\"));\n        return;\n      }\n\n      if (videoCodec) {\n        if (!videoCodecs.has(videoCodec)) {\n          throw new Error(`Unsupported video codec specified: ${videoCodec}`);\n        }\n\n        recorderOptions.videoCodec = videoCodecs.get(videoCodec);\n      }\n\n      if (enableHDR) {\n        if (!supportsHDR) {\n          console.warn(\n            \"HDR requested but not supported on this macOS version. Falling back to SDR.\"\n          );\n        } else {\n          recorderOptions.enableHDR = true;\n        }\n      }\n\n      if (microphoneDeviceId) {\n        if (!supportsMicrophoneCapture) {\n          console.warn(\n            \"Microphone capture requested but requires macOS 15.0+. This feature will be ignored.\"\n          );\n        } else {\n          recorderOptions.microphoneDeviceId = microphoneDeviceId;\n        }\n      }\n\n      if (recordToFile) {\n        if (!supportsDirectRecordingAPI) {\n          console.warn(\n            \"Direct recording API requested but requires macOS 15.0+. Falling back to manual recording.\"\n          );\n        } else {\n          recorderOptions.useDirectRecordingAPI = true;\n        }\n      }\n\n      if (cropArea) {\n        recorderOptions.cropRect = [\n          [cropArea.x, cropArea.y],\n          [cropArea.width, cropArea.height],\n        ];\n      }\n\n      const timeout = setTimeout(resolve, 1000);\n      this.recorder = execa(BIN, [\"record\", JSON.stringify(recorderOptions)]);\n\n      this.recorder?.catch((error) => {\n        clearTimeout(timeout);\n        delete this.recorder;\n        reject(error);\n      });\n\n      this.recorder?.stdout?.setEncoding(\"utf8\");\n      this.recorder?.stdout?.on(\"data\", (data) => {\n        console.log(\"From swift executable: \", data);\n      });\n    });\n  }\n\n  /**\n   * Stops the ongoing recording and processes the video to merge audio tracks if needed.\n   * @returns {Promise<string|null>} A promise that resolves with the path to the processed video file.\n   * @throws {Error} If recording has not been started.\n   */\n  async stopRecording() {\n    this.throwIfNotStarted();\n    console.log(\"Arrêt de l'enregistrement\");\n    this.recorder?.kill();\n    await this.recorder;\n    console.log(\"Enregistrement arrêté\");\n    this.recorder = undefined;\n\n    if (!this.videoPath) {\n      return null;\n    }\n\n    // Ajoutons un délai pour s'assurer que le fichier est complètement écrit\n    await new Promise(resolve => setTimeout(resolve, 1000));\n    \n    let currentFile = this.videoPath;\n\n    // Vérifier si le fichier existe et a une taille\n    try {\n      const stats = fs.statSync(currentFile);\n      if (stats.size === 0) {\n        console.error(\"Le fichier d'enregistrement est vide\");\n        return null;\n      }\n    } catch (error) {\n      console.error(\"Erreur lors de la vérification du fichier d'enregistrement:\", error);\n      return null;\n    }\n\n    // Si nous avons plusieurs sources audio, nous devons les fusionner\n    const hasMultipleAudioTracks = !!(\n      this.currentOptions?.audioDeviceId && \n      this.currentOptions?.microphoneDeviceId\n    );\n\n    if (hasMultipleAudioTracks) {\n      try {\n        console.log(\"Fusion des pistes audio avec ffmpeg\");\n        this.processedVideoPath = createTempFile({ extension: \"mp4\" });\n        \n        // Vérifier la structure du fichier avec ffprobe\n        const { stdout: probeOutput } = await execa(\"ffprobe\", [\n          \"-v\", \"error\",\n          \"-show_entries\", \"stream=index,codec_type\",\n          \"-of\", \"json\",\n          currentFile\n        ]);\n        \n        const probeResult = JSON.parse(probeOutput);\n        const streams = probeResult.streams || [];\n        \n        // Identifier les indices des flux audio et vidéo\n        const audioStreams = streams\n          .filter((stream: {codec_type: string; index: number}) => stream.codec_type === \"audio\")\n          .map((stream: {index: number}) => stream.index);\n          \n        const videoStream = streams\n          .find((stream: {codec_type: string; index: number}) => stream.codec_type === \"video\")?.index;\n          \n        if (audioStreams.length < 2 || videoStream === undefined) {\n          console.log(\"Pas assez de pistes audio pour fusionner ou pas de piste vidéo\");\n        } else {\n          const systemAudioIndex = audioStreams[0];\n          const microphoneIndex = audioStreams[1];\n          \n          const filterComplex = `[0:${systemAudioIndex}]volume=1[a1];[0:${microphoneIndex}]volume=3[a2];[a1][a2]amerge=inputs=2[aout]`;\n          \n          // Traitement vidéo\n          await execa(\"ffmpeg\", [\n            \"-i\", currentFile,\n            \"-filter_complex\", filterComplex,\n            \"-map\", \"[aout]\",\n            \"-map\", `0:${videoStream}`,\n            \"-c:v\", \"copy\",\n            \"-c:a\", \"aac\",\n            \"-b:a\", \"256k\",\n            \"-ac\", \"2\",\n            \"-y\",\n            this.processedVideoPath\n          ]);\n          \n          currentFile = this.processedVideoPath;\n        }\n      } catch (error) {\n        console.error(\"Erreur lors de la fusion des pistes audio:\", error);\n      }\n    }\n\n    // Si audioOnly est activé, convertir en MP3\n    if (this.currentOptions?.audioOnly) {\n      try {\n        console.log(\"Conversion en MP3\");\n        const audioPath = createTempFile({ extension: \"mp3\" });\n        \n        await execa(\"ffmpeg\", [\n          \"-i\", currentFile,\n          \"-vn\",\n          \"-c:a\", \"libmp3lame\",\n          \"-b:a\", \"192k\",\n          \"-y\",\n          audioPath\n        ]);\n        \n        return audioPath;\n      } catch (error) {\n        console.error(\"Erreur lors de la conversion en MP3:\", error);\n        return currentFile;\n      }\n    }\n\n    return currentFile;\n  }\n}\n\n/**\n * Creates and returns a new instance of ScreenCaptureKit.\n * @returns {ScreenCaptureKit} A new instance of the screen recorder.\n */\nexport default function () {\n  return new ScreenCaptureKit();\n}\n\n/**\n * Retrieves the video codecs available on the system.\n * @returns {Map<string, string>} A map of available video codecs.\n * @private\n */\nfunction getCodecs() {\n  const codecs = new Map([\n    [\"h264\", \"H264\"],\n    [\"hevc\", \"HEVC\"],\n    [\"proRes422\", \"Apple ProRes 422\"],\n    [\"proRes4444\", \"Apple ProRes 4444\"],\n  ]);\n\n  if (!supportsHevcHardwareEncoding) {\n    codecs.delete(\"hevc\");\n  }\n\n  return codecs;\n}\n\n/**\n * Specific error for ScreenCaptureKit operations\n */\nexport class ScreenCaptureKitError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = 'ScreenCaptureKitError';\n  }\n}\n\n/**\n * Retrieves the list of screens available for recording.\n * @returns {Promise<Screen[]>} A promise that resolves with an array of objects representing the screens.\n * @throws {ScreenCaptureKitError} If screen retrieval fails.\n */\nexport const screens = async (): Promise<Screen[]> => {\n  const { stderr } = await execa(BIN, [\"list\", \"screens\"]);\n  try {\n    return JSON.parse(stderr);\n  } catch {\n    throw new ScreenCaptureKitError(`Failed to retrieve screens: ${stderr}`);\n  }\n};\n\n/**\n * Retrieves the list of system audio devices available for recording.\n * @returns {Promise<AudioDevice[]>} A promise that resolves with an array of objects representing the audio devices.\n * @throws {ScreenCaptureKitError} If audio device retrieval fails.\n */\nexport const audioDevices = async (): Promise<AudioDevice[]> => {\n  const { stderr } = await execa(BIN, [\"list\", \"audio-devices\"]);\n  try {\n    return JSON.parse(stderr);\n  } catch {\n    throw new ScreenCaptureKitError(`Failed to retrieve audio devices: ${stderr}`);\n  }\n};\n\n/**\n * Retrieves the list of microphone devices available for recording.\n * @returns {Promise<MicrophoneDevice[]>} A promise that resolves with an array of objects representing the microphones.\n * @throws {ScreenCaptureKitError} If microphone retrieval fails.\n */\nexport const microphoneDevices = async (): Promise<MicrophoneDevice[]> => {\n  const { stderr } = await execa(BIN, [\"list\", \"microphone-devices\"]);\n  try {\n    return JSON.parse(stderr);\n  } catch {\n    throw new ScreenCaptureKitError(`Failed to retrieve microphones: ${stderr}`);\n  }\n};\n\n/**\n * Indicates whether the current system supports HDR capture.\n * @type {boolean}\n */\nexport const supportsHDRCapture = supportsHDR;\n\n/**\n * Map of video codecs available on the system.\n * @type {Map<string, string>}\n */\nexport const videoCodecs = getCodecs();\n\n// Fonction de remplacement pour temporaryFile sans créer le fichier\nfunction createTempFile(options: { extension?: string } = {}): string {\n  const tempDir = os.tmpdir();\n  const randomId = uuidv4();\n  const extension = options.extension ? `.${options.extension}` : '';\n  const tempFilePath = path.join(tempDir, `${randomId}${extension}`);\n  \n  // Ne pas créer le fichier, juste retourner le chemin\n  return tempFilePath;\n}\n\n// Fonction personnalisée pour remplacer fileUrl\nfunction fileUrlFromPath(filePath: string): string {\n  // Encodage des caractères spéciaux\n  let pathName = filePath.replace(/\\\\/g, '/');\n  \n  // Assurez-vous que le chemin commence par un slash si ce n'est pas déjà le cas\n  if (pathName[0] !== '/') {\n    pathName = '/' + pathName;\n  }\n  \n  // Encodage des caractères spéciaux dans l'URL\n  pathName = encodeURI(pathName)\n    // Encodage supplémentaire pour les caractères qui ne sont pas gérés par encodeURI\n    .replace(/#/g, '%23')\n    .replace(/\\?/g, '%3F');\n  \n  return `file://${pathName}`;\n}","import path from \"path\";\nimport { fileURLToPath } from \"url\";\n\ndeclare global {\n  namespace NodeJS {\n    interface Process {\n      resourcesPath?: string;\n    }\n  }\n}\n\nexport const getPackageRoot = () => {\n  if (process.env.NODE_ENV === \"test\") {\n    return path.join(__dirname, \"..\", \"..\", \"dist\");\n  }\n  try {\n    // Résolution via le point d'entrée du package\n    const app = require(\"electron\").app;\n    const packageMainPath = require.resolve(\"screencapturekit\");\n    if (typeof process.resourcesPath === \"string\" && app?.isPackaged) {\n      const finalPath = path.join(process.resourcesPath);\n      return finalPath;\n    }\n    const finalPath = path.dirname(packageMainPath);\n    return finalPath;\n  } catch (e) {\n    // Fallback pour le développement ES modules\n    const __filename = fileURLToPath(import.meta.url);\n    const finalPath = path.join(path.dirname(__filename));\n    console.log(\"finalPath : ESM\", finalPath);\n    return finalPath;\n  }\n};\n\nexport const resolvePackagePath = (...segments: string[]) =>\n  path.join(getPackageRoot(), ...segments);\n"],"mappings":"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","names":["path","finalPath","os","fs","uuidv4","path"]}