SOOP auto reload live

play.sooplive.co.kr 에서 대기하다가 방송이 시작되면 자동으로 새로고침해줘요

  1. // ==UserScript==
  2. // @name SOOP auto reload live
  3. // @version 2025-03-09
  4. // @description play.sooplive.co.kr 에서 대기하다가 방송이 시작되면 자동으로 새로고침해줘요
  5. // @author chatting banned
  6. // @match https://play.sooplive.co.kr/*
  7. // @icon https://res.sooplive.co.kr/favicon.ico
  8. // @grant none
  9. // @license MIT; https://opensource.org/licenses/MIT
  10. // @namespace https://greatest.deepsurf.us/users/1443830
  11. // ==/UserScript==
  12.  
  13. (async()=>{
  14. /**
  15. * wait and returns the HTMLElement until it is found.
  16. *
  17. * @param {String} selector sizzle selector for querySelector
  18. * @return {Promise<HTMLElement>}
  19. */
  20. const waitForElement = async (selector) => {
  21. return new Promise((resolve) => {
  22. let observedElement = document.querySelector(selector);
  23. if (observedElement) return resolve(observedElement);
  24.  
  25. let observer = new MutationObserver(() => {
  26. let observedElement = document.querySelector(selector);
  27. if (observedElement) {
  28. observer.disconnect();
  29. resolve(observedElement);
  30. }
  31. });
  32.  
  33. observer.observe(document.documentElement, {
  34. childList: !0,
  35. subtree: !0,
  36. });
  37. });
  38. };
  39.  
  40. /**
  41. * awaits for t ms.
  42. * @param {Number} t sleep time
  43. * @returns {Promise<null>}
  44. */
  45. const sleep = t => new Promise(r=>setTimeout(r,t));
  46.  
  47. const reloadBroadCastMain = async () => {
  48. const intl = new Intl.DateTimeFormat("ko-KR", {
  49. minute: "2-digit",
  50. hour: "2-digit",
  51. second: "2-digit",
  52. hour12: false,
  53. });
  54. let broadCastText = await waitForElement(`.notBroadingInfoTitle`);
  55. const bjid = location.pathname.split("/").at(1);
  56. let BNO = undefined;
  57. do {
  58. await sleep(1000);
  59. const { CHANNEL: resp } = await fetch(
  60. "https://live.sooplive.co.kr/afreeca/player_live_api.php",
  61. {
  62. headers: {"content-type": "application/x-www-form-urlencoded",},
  63. body: `bid=${bjid}&bno=null&type=live&pwd=&player_type=html5&stream_type=common&quality=HD&mode=landing&from_api=0&is_revive=false`,
  64. method: "POST",
  65. mode: "cors",
  66. credentials: "include",
  67. }
  68. ).then((r) => r.json());
  69. BNO = resp.BNO;
  70. if (broadCastText) {
  71. const textContent = `방송 시작을 기다리는 중이에요 (${intl.format(
  72. new Date(Date.now())
  73. )})`;
  74. broadCastText.textContent = textContent;
  75. // console.log(textContent);
  76. }
  77. if (BNO > 0) break;
  78. } while (BNO === undefined || location.pathname.split("/").at(-1) != BNO);
  79.  
  80. if (BNO != location.pathname.split("/").at(-1) && BNO) {
  81. location.pathname = `/${bjid}/${BNO}`;
  82. }
  83. };
  84.  
  85. await reloadBroadCastMain();
  86. await waitForElement(`#player > div.video_blind > div > div > div`); // detects broadcast End
  87. await reloadBroadCastMain();
  88. })();