ChatGPT TTS Grabber

Automatically downloads ChatGPT's TTS audio whenever playback is triggered.

目前為 2025-05-23 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         ChatGPT TTS Grabber
// @namespace    https://github.com/dudebot/greasyfork-scripts/tree/main/ChatGPT
// @version      1.0.0
// @description  Automatically downloads ChatGPT's TTS audio whenever playback is triggered.
// @author       dudebot
// @license      MIT
// @supportURL   https://github.com/dudebot/greasyfork-scripts/issues
// @match        https://chat.openai.com/*
// @match        https://chatgpt.com/*
// @grant        none
// ==/UserScript==

(() => {
  const OrigMS = window.MediaSource;
  window.MediaSource = function() {
    const ms = new OrigMS();
    const origAdd = ms.addSourceBuffer.bind(ms);
    ms.addSourceBuffer = mime => {
      const sb = origAdd(mime);
      if (mime.startsWith('audio/')) {
        const chunks = [];
        const origAppend = sb.appendBuffer.bind(sb);
        sb.appendBuffer = buf => {
          chunks.push(buf.slice(0));
          origAppend(buf);
        };
        // when the player calls endOfStream:
        ms.addEventListener('sourceended', () => {
          const blob = new Blob(chunks, { type: mime });
          const url = URL.createObjectURL(blob);
          const a = document.createElement('a');
          a.href = url;
          a.download = `chatgpt-${Date.now()}.${mime.split('/')[1]}`;
          a.click();
        });
      }
      return sb;
    };
    return ms;
  };
  window.MediaSource.prototype = OrigMS.prototype;
  MediaSource.isTypeSupported = OrigMS.isTypeSupported;
})();