Command Prompt
Command Prompt - Video Downloader
 
❐
✕
Microsoft Windows [Version 10.0.19045.6456]
(c) Microsoft Corporation. All rights reserved.
 
C:\WINDOWS\system32>
_
// API設定 const API_BASE = '/api'; // DOM要素 const cmdContent = document.getElementById('cmdContent'); let cmdInput = document.getElementById('cmdInput'); let cursor = document.getElementById('cursor'); const currentPrompt = document.getElementById('currentPrompt'); let currentInputLine = document.getElementById('currentInputLine'); // コマンド履歴 let commandHistory = []; let historyIndex = -1; let currentDirectory = 'C:\\WINDOWS\\system32'; let currentTask = null; // カーソル位置の更新 function updateCursorPosition() { const text = cmdInput.value; const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); context.font = '16px "MS Gothic", "MSゴシック", "Courier New", monospace'; const width = context.measureText(text).width; cursor.style.left = `${width}px`; } // 入力フォーカス cmdInput.focus(); updateCursorPosition(); // コマンド実行 function executeCommand(cmd) { // 現在の入力行を出力行に変換 currentInputLine.className = 'output-line'; currentInputLine.innerHTML = `${currentPrompt.textContent}${cmd}`; const args = cmd.trim().split(' '); const command = args[0].toLowerCase(); switch(command) { case 'download': if (args.length < 2) { addOutputLine('Usage: download [URL]'); addOutputLine(''); createNewInputLine(); break; } const url = args[1]; downloadVideo(url); break; case 'help': showHelp(); createNewInputLine(); break; case 'cls': case 'clear': clearScreen(); createNewInputLine(); break; case 'exit': addOutputLine(''); break; case 'cd': if (args.length > 1) { changeDirectory(args[1]); } else { addOutputLine(currentDirectory); addOutputLine(''); } createNewInputLine(); break; case 'dir': showDirectory(); createNewInputLine(); break; case '': addOutputLine(''); createNewInputLine(); break; default: addOutputLine(`'${command}' is not recognized as an internal or external command,`); addOutputLine('operable program or batch file.'); addOutputLine(''); createNewInputLine(); } // 履歴に追加 if (cmd.trim()) { commandHistory.unshift(cmd); historyIndex = -1; } } // 新しい入力行を作成 function createNewInputLine() { const inputLine = document.createElement('div'); inputLine.className = 'input-line'; inputLine.innerHTML = ` ${currentDirectory}>
_
`; cmdContent.appendChild(inputLine); const newInput = inputLine.querySelector('input'); const newCursor = inputLine.querySelector('.cursor'); // グローバル変数を更新 cmdInput = newInput; cursor = newCursor; currentInputLine = inputLine; // 新しい入力にフォーカス cmdInput.focus(); // イベントリスナーを設定 setupInputEvents(); // カーソル位置を更新 updateCursorPosition(); // スクロールを最下部に cmdContent.scrollTop = cmdContent.scrollHeight; } // 入力イベントの設定 function setupInputEvents() { // 既存のイベントリスナーを削除 cmdInput.replaceWith(cmdInput.cloneNode(true)); cmdInput = document.querySelector('.input-line:last-child .input-text'); cursor = document.querySelector('.input-line:last-child .cursor'); cmdInput.addEventListener('keydown', function(e) { // 履歴ナビゲーション if (e.key === 'ArrowUp') { e.preventDefault(); if (commandHistory.length > 0) { if (historyIndex < commandHistory.length - 1) { historyIndex++; } cmdInput.value = commandHistory[historyIndex] || ''; updateCursorPosition(); } } else if (e.key === 'ArrowDown') { e.preventDefault(); if (historyIndex > 0) { historyIndex--; cmdInput.value = commandHistory[historyIndex] || ''; } else { historyIndex = -1; cmdInput.value = ''; } updateCursorPosition(); } else if (e.key === 'Enter') { e.preventDefault(); const command = cmdInput.value.trim(); if (currentTask && currentTask.type === 'quality_selection') { // 品質選択モード handleQualitySelection(command); } else { // 通常コマンドモード executeCommand(command); } } else if (e.key === 'Tab') { e.preventDefault(); // タブ補完(シンプルな実装) const commands = ['download', 'help', 'cls', 'exit', 'cd', 'dir']; const currentText = cmdInput.value.toLowerCase(); const match = commands.find(cmd => cmd.startsWith(currentText)); if (match) { cmdInput.value = match; updateCursorPosition(); } } }); // 入力変更時にカーソル位置を更新 cmdInput.addEventListener('input', updateCursorPosition); } // 初期イベント設定 setupInputEvents(); // ダウンロード処理 async function downloadVideo(url) { if (!url.startsWith('http')) { addOutputLine('Invalid URL format'); addOutputLine(''); createNewInputLine(); return; } addOutputLine('Analyzing video URL...'); try { // 動画情報取得 const response = await fetch(`${API_BASE}/info`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: url }) }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Analysis failed'); } addOutputLine(`Title: ${data.title}`); addOutputLine(`Uploader: ${data.uploader}`); addOutputLine(`Duration: ${formatDuration(data.duration)}`); addOutputLine(''); addOutputLine('Available formats:'); addOutputLine(' 1. MP4 - 1080p (Best quality)'); addOutputLine(' 2. MP4 - 720p (Balanced)'); addOutputLine(' 3. MP4 - 480p (Small size)'); addOutputLine(' 4. MP3 - Audio only'); addOutputLine(''); addOutputLine('Enter choice [1-4]:'); // 品質選択モード currentTask = { type: 'quality_selection', url: url, videoInfo: data }; createNewInputLine(); } catch (error) { addOutputLine(`Error: ${error.message}`); addOutputLine(''); createNewInputLine(); } } // 品質選択処理 function handleQualitySelection(choice) { const qualityMap = { '1': '1080p', '2': '720p', '3': '480p', '4': 'audio' }; const quality = qualityMap[choice]; if (!quality) { addOutputLine('Invalid choice. Please enter 1, 2, 3, or 4.'); addOutputLine(''); createNewInputLine(); return; } addOutputLine(`Selected: ${quality}`); addOutputLine('Starting download...'); // ダウンロード開始 startDownload(currentTask.url, quality); currentTask = null; } // ダウンロード開始 async function startDownload(url, quality) { try { const response = await fetch(`${API_BASE}/download`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url, quality }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Download failed'); } const blob = await response.blob(); // ファイル名を生成 const contentDisposition = response.headers.get('Content-Disposition'); let filename = 'video.mp4'; if (contentDisposition) { const match = contentDisposition.match(/filename="(.+)"/); if (match) filename = match[1]; } // ダウンロード const urlObj = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = urlObj; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(urlObj); addOutputLine('Download completed successfully!'); addOutputLine(''); createNewInputLine(); } catch (error) { addOutputLine(`Error: ${error.message}`); addOutputLine(''); createNewInputLine(); } } // ヘルプ表示 function showHelp() { addOutputLine('Video Downloader Commands:'); addOutputLine(' download [URL] Download video from URL'); addOutputLine(' help Show this help'); addOutputLine(' cls Clear screen'); addOutputLine(' exit Exit command prompt'); addOutputLine(' cd [dir] Change directory'); addOutputLine(' dir List directory contents'); addOutputLine(''); } // ディレクトリ変更 function changeDirectory(path) { if (path === '..' || path === '..\\') { if (currentDirectory !== 'C:\\') { const parts = currentDirectory.split('\\'); parts.pop(); currentDirectory = parts.join('\\') || 'C:\\'; } } else if (path === '\\' || path === 'C:\\') { currentDirectory = 'C:\\'; } else if (path.startsWith('C:\\')) { currentDirectory = path; } else { currentDirectory = currentDirectory + '\\' + path; } currentDirectory = currentDirectory.replace(/\\+/g, '\\'); if (currentDirectory.endsWith('\\') && currentDirectory.length > 3) { currentDirectory = currentDirectory.slice(0, -1); } currentPrompt.textContent = `${currentDirectory}>`; } // ディレクトリ表示 function showDirectory() { const now = new Date(); addOutputLine(` Directory of ${currentDirectory}`); addOutputLine(''); addOutputLine(`${now.toLocaleDateString()} ${now.toLocaleTimeString().replace(/:/g, '.')} .`); addOutputLine(`${now.toLocaleDateString()} ${now.toLocaleTimeString().replace(/:/g, '.')} ..`); addOutputLine(' 0 File(s) 0 bytes'); addOutputLine(' 2 Dir(s) 1,000,000,000 bytes free'); addOutputLine(''); } // 画面クリア function clearScreen() { cmdContent.innerHTML = ''; addOutputLine('Microsoft Windows [Version 10.0.19045.6456]'); addOutputLine('(c) Microsoft Corporation. All rights reserved.'); addOutputLine(''); addOutputLine('VIDEO DOWNLOADER - CLOUDFLARE WORKERS EDITION'); addOutputLine(''); createNewInputLine(); } // 出力行を追加 function addOutputLine(text) { const line = document.createElement('div'); line.className = 'output-line'; line.textContent = text; cmdContent.appendChild(line); cmdContent.scrollTop = cmdContent.scrollHeight; } // 時間フォーマット function formatDuration(seconds) { if (!seconds) return 'Unknown'; const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`; } // ウィンドウコントロール document.querySelector('.control-btn.close').addEventListener('click', function() { if (confirm('Close window?')) { window.close(); } }); document.querySelector('.control-btn:nth-child(2)').addEventListener('click', function() { if (!document.fullscreenElement) { document.documentElement.requestFullscreen(); } else { document.exitFullscreen(); } }); // クリックでフォーカス document.addEventListener('click', function() { cmdInput.focus(); });