// ==UserScript== // @name 职业成长刷课脚本 // @namespace https://www.zyczedu.com/ // @version 0.1.2 // @description 自动播放视频、学完后点击“我已学完”,并切换到下一个未完成视频。 // @author 脚本喵 // @match https://www.zyczedu.com/player/study/index* // @match https://www.zyczedu.com/js/player/pages/play.html* // @icon https://jiaobenmiao.com/img/logo2.jpg // @grant none // @run-at document-idle // ==/UserScript== (function () { 'use strict'; const LOOP_MS = 2000; const NEXT_DELAY_MS = 4000; const SUBMIT_COOLDOWN_MS = 8000; const STORAGE_KEY_ENABLED = 'zyczedu-auto-study-enabled'; const STORAGE_KEY_COLLAPSED = 'zyczedu-auto-study-collapsed'; const isMainPage = location.pathname.indexOf('/player/study/index') !== -1; const isPlayerFrame = location.pathname.indexOf('/js/player/pages/play.html') !== -1; function log(message) { console.log('[zyczedu-auto-study]', message); } function isAutomationEnabled() { try { return localStorage.getItem(STORAGE_KEY_ENABLED) !== '0'; } catch (error) { return true; } } function setAutomationEnabled(enabled) { try { localStorage.setItem(STORAGE_KEY_ENABLED, enabled ? '1' : '0'); } catch (error) { void error; } } function isPanelCollapsed() { try { return localStorage.getItem(STORAGE_KEY_COLLAPSED) === '1'; } catch (error) { return false; } } function setPanelCollapsed(collapsed) { try { localStorage.setItem(STORAGE_KEY_COLLAPSED, collapsed ? '1' : '0'); } catch (error) { void error; } } function isVisible(element) { if (!element) { return false; } const style = window.getComputedStyle(element); return style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0'; } function parseTimeToSeconds(value) { if (!value) { return 0; } const parts = value.trim().split(':').map(Number); if (parts.some(Number.isNaN)) { return 0; } if (parts.length === 3) { return parts[0] * 3600 + parts[1] * 60 + parts[2]; } if (parts.length === 2) { return parts[0] * 60 + parts[1]; } return parts[0] || 0; } function formatSeconds(value) { const totalSeconds = Math.max(0, Math.floor(Number(value) || 0)); const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; return [hours, minutes, seconds] .map(function (part) { return String(part).padStart(2, '0'); }) .join(':'); } function click(element) { if (!element) { return false; } element.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true })); return true; } function getVideosFromDocument(doc) { if (!doc) { return []; } return Array.from(doc.querySelectorAll('video')); } function tryPlayVideo(video) { if (!video) { return; } if (!video.paused && !video.ended) { return; } const playPromise = video.play(); if (playPromise && typeof playPromise.catch === 'function') { playPromise.catch(function () { try { video.muted = true; video.play().catch(function () {}); } catch (error) { void error; } }); } } function pauseVideo(video) { if (!video) { return; } if (!video.paused) { video.pause(); } } function frameVideoHelper() { function tick() { const videos = getVideosFromDocument(document); if (isAutomationEnabled()) { videos.forEach(tryPlayVideo); return; } videos.forEach(pauseVideo); } tick(); window.setInterval(tick, LOOP_MS); } function mainPageHelper() { let lastCourseId = ''; let lastSubmitAt = 0; let lastNextAt = 0; let endedCourseId = ''; let lastAction = '等待开始'; let panelElements = null; function text(selector) { const element = document.querySelector(selector); return element ? element.textContent.trim() : ''; } function value(selector) { const element = document.querySelector(selector); return element ? String(element.value || '').trim() : ''; } function getFrameDocument() { const iframe = document.querySelector('#container'); if (!iframe) { return null; } try { return iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document) || null; } catch (error) { return null; } } function getActiveSection() { return document.querySelector('#list_chapter .section.active'); } function getCurrentCourseId() { const active = getActiveSection(); return value('#hiddenCourseId') || (active && active.getAttribute('data-jhx-res')) || ''; } function getCurrentVideo() { const frameDoc = getFrameDocument(); const videos = getVideosFromDocument(frameDoc).concat(getVideosFromDocument(document)); return videos[0] || null; } function getPendingSections() { return Array.from(document.querySelectorAll('#list_chapter .section')).filter(function (section) { return !section.querySelector('.status-done'); }); } function getCurrentTitle() { const title = document.querySelector('.player-wrapper .info .title'); return title ? title.textContent.trim() : '未识别课程'; } function ensurePlayback() { const frameDoc = getFrameDocument(); const videos = getVideosFromDocument(frameDoc).concat(getVideosFromDocument(document)); videos.forEach(tryPlayVideo); } function pausePlayback() { const frameDoc = getFrameDocument(); const videos = getVideosFromDocument(frameDoc).concat(getVideosFromDocument(document)); videos.forEach(pauseVideo); } function setLastAction(message) { if (lastAction === message) { updatePanel(); return; } lastAction = message; log(message); updatePanel(); } function createPanel() { if (panelElements) { return panelElements; } const style = document.createElement('style'); style.textContent = [ '#zy-auto-study-panel { position: fixed; top: 90px; right: 24px; z-index: 999999; width: 240px; padding: 14px; border-radius: 12px; background: rgba(18, 28, 39, 0.92); color: #f3f7fb; box-shadow: 0 12px 30px rgba(0, 0, 0, 0.22); font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }', '#zy-auto-study-panel.is-collapsed { width: 240px; }', '#zy-auto-study-panel .zy-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; }', '#zy-auto-study-panel .zy-title { margin: 0 0 10px; font-size: 15px; font-weight: 700; }', '#zy-auto-study-panel .zy-collapse { border: 0; border-radius: 8px; padding: 6px 10px; cursor: pointer; color: #f3f7fb; background: rgba(255, 255, 255, 0.12); font-size: 12px; font-weight: 700; }', '#zy-auto-study-panel .zy-toggle { width: 100%; border: 0; border-radius: 8px; padding: 9px 12px; cursor: pointer; color: #fff; font-size: 13px; font-weight: 700; background: #1f9d55; }', '#zy-auto-study-panel .zy-toggle.is-paused { background: #2563eb; }', '#zy-auto-study-panel .zy-grid { margin-top: 12px; display: grid; gap: 8px; }', '#zy-auto-study-panel.is-collapsed .zy-grid, #zy-auto-study-panel.is-collapsed .zy-toggle { display: none; }', '#zy-auto-study-panel.is-collapsed .zy-title { margin-bottom: 0; }', '#zy-auto-study-panel .zy-item { padding: 8px 10px; border-radius: 8px; background: rgba(255, 255, 255, 0.08); }', '#zy-auto-study-panel .zy-label { display: block; margin-bottom: 2px; color: #a9b7c6; font-size: 12px; }', '#zy-auto-study-panel .zy-value { display: block; color: #f8fbff; word-break: break-word; }' ].join(''); document.head.appendChild(style); const panel = document.createElement('div'); panel.id = 'zy-auto-study-panel'; panel.innerHTML = [ '