Auto Play Audio Sequentially

访问指定 URL 获取音频并自动播放,确保按顺序播放

当前为 2024-03-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Auto Play Audio Sequentially
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description 访问指定 URL 获取音频并自动播放,确保按顺序播放
  6. // @author Your Name
  7. // @match *://*/*
  8. // @grant none
  9. // ==/UserScript==
  10. (function() {
  11. 'use strict';
  12.  
  13. // 初始 URL
  14. const initialUrl = 'http://localhost:9880?text=你好,我是七七,是个小僵尸&text_lang=中文&ref_audio_path=./qiqi3.mp3&prompt_text=刮大风了…_拉手…拉手!要、要被吹跑了!…&prompt_lang=中文&sweight=SoVITS_weights/qiqi_e8_s136.pth&gweight=GPT_weights/qiqi-e15.ckpt';
  15.  
  16. // 当前 URL
  17. let currentUrl = initialUrl;
  18.  
  19. // 存储待播放的音频URL队列
  20. const audioQueue = [];
  21.  
  22. // 是否有音频正在播放
  23. let isPlaying = false;
  24.  
  25. // 存储已经绑定过按钮的 div 元素
  26. const boundDivs = new Set();
  27.  
  28. // 检测并插入播放按钮的函数
  29. function checkAndInsertPlayButton() {
  30. const divElements = document.querySelectorAll('div');
  31.  
  32. divElements.forEach(div => {
  33. if (div.getAttribute('dir') === 'auto' && !boundDivs.has(div)) {
  34. const playButton = document.createElement('button');
  35. playButton.textContent = 'Play Audio';
  36. div.parentNode.insertBefore(playButton, div.nextSibling);
  37.  
  38. playButton.addEventListener('click', async function() {
  39. const text = div.textContent.trim();
  40. const quotes = extractQuotes(text);
  41. for (const quote of quotes) {
  42. await fetchAudioAndAddToQueue(updateUrlWithText(currentUrl, quote));
  43. }
  44. });
  45.  
  46. boundDivs.add(div); // 将已经绑定过按钮的 div 元素添加到集合中
  47. }
  48. });
  49. }
  50.  
  51. // 每隔 5 秒检测一次 div 元素
  52. setInterval(checkAndInsertPlayButton, 5000);
  53.  
  54. // 获取音频并添加到播放队列
  55. async function fetchAudioAndAddToQueue(url) {
  56. try {
  57. const response = await fetch(url);
  58. const blob = await response.blob();
  59. const audioUrl = window.URL.createObjectURL(blob);
  60. audioQueue.push(audioUrl);
  61. playNextAudio();
  62. } catch (error) {
  63. console.error('获取音频失败:', error);
  64. }
  65. }
  66.  
  67. // 播放队列中的下一个音频
  68. function playNextAudio() {
  69. if (isPlaying || audioQueue.length === 0) {
  70. return;
  71. }
  72. isPlaying = true;
  73. const audioUrl = audioQueue.shift(); // 获取并移除队列中的第一个音频URL
  74. const audio = new Audio(audioUrl);
  75. audio.play();
  76. audio.onended = function() {
  77. isPlaying = false;
  78. playNextAudio(); // 播放完毕后继续播放下一个
  79. };
  80. }
  81.  
  82. // 提取文本中的双引号内容
  83. function extractQuotes(text) {
  84. const quotes = [];
  85. const regex = /“(.*?)”/g;
  86. const regex2 = /"(.*?)"/g;
  87. let text2=text;
  88. let match;
  89. while ((match = regex.exec(text)) !== null) {
  90. quotes.push(match[1]);
  91. }
  92. let match2;
  93. while ((match2 = regex2.exec(text2)) !== null) {
  94. quotes.push(match2[1]);
  95. }
  96. return quotes;
  97. }
  98.  
  99. // 更新 URL 中的 text 参数
  100. function updateUrlWithText(url, text) {
  101. const urlObj = new URL(url);
  102. urlObj.searchParams.set('text', text);
  103. return urlObj.toString();
  104. }
  105. })();