// ==UserScript== // @name 숙제 // @namespace 숙제 // @version 1.1 // @description 롤캐 숙제 직링 // @match https://insagirl-toto.appspot.com/chatting/lgic/* // @grant GM_xmlhttpRequest // @downloadURL none // ==/UserScript== (function() { 'use strict'; // YouTube Channels const CHANNELS = { homework: { id: 'UCw1DsweY9b2AKGjV4kGJP1A', buttonLabel: '숙제', }, }; const LOLCAST_REDIRECT_BASE_URL = 'https://lolcast.kr/#/player/youtube'; // Fetch the live video ID from the YouTube channel's live page async function fetchLiveVideoId(channelId) { const YOUTUBE_LIVE_URL = `https://www.youtube.com/channel/${channelId}/live`; return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: YOUTUBE_LIVE_URL, onload: function(response) { const videoIdMatch = response.responseText.match(/"videoId":"([\w-]+)"/); const isLiveNow = response.responseText.includes('"isLiveNow":true') || response.responseText.includes('"isLive":true'); const liveBroadcastContentMatch = response.responseText.match(/"liveBroadcastContent":"(\w+)"/); const isLiveBroadcast = liveBroadcastContentMatch && liveBroadcastContentMatch[1] === 'live'; if (videoIdMatch && videoIdMatch[1] && (isLiveNow || isLiveBroadcast)) { resolve(videoIdMatch[1]); } else { console.log(`No live video found for channel: ${channelId}`); reject('No live video found.'); } }, onerror: function(error) { console.error('Error fetching live video ID:', error); reject(error); } }); }); } const controlPanel = document.createElement('div'); controlPanel.style.position = 'fixed'; controlPanel.style.top = '20px'; controlPanel.style.right = '0'; controlPanel.style.backgroundColor = 'white'; controlPanel.style.padding = '5px'; controlPanel.style.border = '1px solid black'; controlPanel.style.zIndex = '1000'; controlPanel.style.transition = 'right 0.3s ease'; // Container for channel buttons const buttonContainer = document.createElement('div'); buttonContainer.style.display = 'flex'; buttonContainer.style.gap = '5px'; // Function to create a button for each channel function createChannelButton(channel) { const button = document.createElement('button'); button.textContent = channel.buttonLabel; button.style.margin = '0'; button.onclick = async () => { try { const liveVideoId = await fetchLiveVideoId(channel.id); const redirectUrl = `${LOLCAST_REDIRECT_BASE_URL}/${liveVideoId}`; window.open(redirectUrl, '_blank'); } catch (error) { console.error(`Failed to redirect to Lolcast for channel ${channel.id}:`, error); alert(`${channel.buttonLabel} 라이브 스트림을 찾을 수 없습니다.`); } }; return button; } // Add buttons for each channel const homeworkButton = createChannelButton(CHANNELS.homework); buttonContainer.appendChild(homeworkButton); // Toggle Button const toggleButton = document.createElement('button'); toggleButton.textContent = '◀'; toggleButton.style.marginLeft = '5px'; toggleButton.onclick = () => { if (controlPanel.style.right === '0px') { controlPanel.style.right = `-${buttonContainer.offsetWidth + 50}px`; toggleButton.textContent = '▶'; } else { controlPanel.style.right = '0px'; toggleButton.textContent = '◀'; } }; buttonContainer.appendChild(toggleButton); controlPanel.appendChild(buttonContainer); document.body.appendChild(controlPanel); })();