Auto Play Audio Sequentially

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

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

  1. // ==UserScript==
  2. // @name Auto Play Audio Sequentially
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  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://192.168.10.2: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. playButton.style.backgroundColor = '#4CAF50'; // 设置按钮背景颜色
  37. playButton.style.color = 'white'; // 设置按钮文字颜色
  38. playButton.style.padding = '8px 16px'; // 设置按钮内边距
  39. playButton.style.border = 'none'; // 移除按钮边框
  40. playButton.style.borderRadius = '4px'; // 设置按钮圆角
  41. playButton.style.cursor = 'pointer'; // 设置鼠标指针样式
  42. div.parentNode.insertBefore(playButton, div.nextSibling);
  43.  
  44. playButton.addEventListener('click', async function() {
  45. const text = div.textContent.trim();
  46. const quotes = extractQuotes(text);
  47. for (const quote of quotes) {
  48. await fetchAudioAndAddToQueue(updateUrlWithText(currentUrl, quote));
  49. }
  50. });
  51.  
  52. boundDivs.add(div); // 将已经绑定过按钮的 div 元素添加到集合中
  53. }
  54. });
  55. }
  56.  
  57. // 每隔 5 秒检测一次 div 元素
  58. setInterval(checkAndInsertPlayButton, 5000);
  59.  
  60. // 获取音频并添加到播放队列
  61. async function fetchAudioAndAddToQueue(url) {
  62. try {
  63. const response = await fetch(url);
  64. const blob = await response.blob();
  65. const audioUrl = window.URL.createObjectURL(blob);
  66. audioQueue.push(audioUrl);
  67. playNextAudio();
  68. } catch (error) {
  69. console.error('获取音频失败:', error);
  70. }
  71. }
  72.  
  73. // 播放队列中的下一个音频
  74. function playNextAudio() {
  75. if (isPlaying || audioQueue.length === 0) {
  76. return;
  77. }
  78. isPlaying = true;
  79. const audioUrl = audioQueue.shift(); // 获取并移除队列中的第一个音频URL
  80. const audio = new Audio(audioUrl);
  81. audio.play();
  82. audio.onended = function() {
  83. isPlaying = false;
  84. playNextAudio(); // 播放完毕后继续播放下一个
  85. };
  86. }
  87.  
  88. // 提取文本中的双引号内容
  89. function extractQuotes(text) {
  90. const quotes = [];
  91. const regex = /"(.*?)"/g;
  92. const regex2 = /"(.*?)"/g;
  93. let text2=text;
  94. let match;
  95. while ((match = regex.exec(text)) !== null) {
  96. quotes.push(match[1]);
  97. }
  98. let match2;
  99. while ((match2 = regex2.exec(text2)) !== null) {
  100. quotes.push(match2[1]);
  101. }
  102. return quotes;
  103. }
  104.  
  105. // 更新 URL 中的 text 参数
  106. function updateUrlWithText(url, text) {
  107. const urlObj = new URL(url);
  108. urlObj.searchParams.set('text', text);
  109. return urlObj.toString();
  110. }
  111. })();