吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1392|回复: 13
收起左侧

[其他原创] 南京广播电视台油猴脚本

[复制链接]
huangmin1111 发表于 2026-3-14 22:04
本帖最后由 huangmin1111 于 2026-3-15 10:30 编辑

南京广播电视台:https://www.nbs.cn/live/,这个脚本再次修改,终于接近完美了。
请各位测试下。

image.png


image.png

[JavaScript] 纯文本查看 复制代码
// ==UserScript==
// @name          南京广播电视台
// @namespace     http://tampermonkey.net/
// @version       2.3
// @description   南京广电:看电视/听广播,双击视频全屏,右侧滑动频道列表
// @author        基于南京广播电视台页面调试
// @match         https://www.nbs.cn/live/*
// @match         http://www.nbs.cn/live/*
// @match         http://www.njgb.com/live*
// @match         https://www.njgb.com/live*
// @grant         GM_addStyle
// @run-at        document-start
// ==/UserScript==

(function() {
    'use strict';

    // 南京广播电视台频道数据
    const NJ_CHANNELS = [
        // 电视频道
        { n: '📺 新闻综合频道', u: '/live/?id=109152', icon: '📰', type: 'tv', id: '109152' },
        { n: '📺 教育科技频道', u: '/live/?id=109153', icon: '🎓', type: 'tv', id: '109153' },
        { n: '📺 十八·生活频道', u: '/live/?id=110094', icon: '🏠', type: 'tv', id: '110094' },
        { n: '📺 文旅纪录频道', u: '/live/?id=110093', icon: '✈️', type: 'tv', id: '110093' },
        { n: '📺 少儿频道', u: '/live/?id=110095', icon: '🧸', type: 'tv', id: '110095' },

        // 广播频率
        { n: '📻 新闻综合广播 FM106.9', u: 'http://www.njgb.com/live/?id=fm1069', icon: '🎙️', type: 'fm', id: 'fm1069' },
        { n: '📻 交通广播 FM102.4', u: 'http://www.njgb.com/live/?id=fm1024', icon: '🚗', type: 'fm', id: 'fm1024' },
        { n: '📻 音乐广播 FM105.8', u: 'http://www.njgb.com/live/?id=fm1058', icon: '🎵', type: 'fm', id: 'fm1058' },
        { n: '📻 体育广播 FM104.3', u: 'http://www.njgb.com/live/?id=fm1043', icon: '⚽', type: 'fm', id: 'fm1043' },
        { n: '📻 城市管理广播 FM96.6', u: 'http://www.njgb.com/live/?id=fm966', icon: '🏙️', type: 'fm', id: 'fm966' },
        { n: '📻 经济广播 FM98.1', u: 'http://www.njgb.com/live/?id=fm981', icon: '💰', type: 'fm', id: 'fm981' }
    ];

    // 先添加基础样式,确保页面布局正确但不干扰DPlayer初始化
    GM_addStyle(`
        /* 只隐藏广告和导航等干扰元素,保留播放器区域完全不受影响 */
        header, .header-main, .menu-box, .wrap1_2014_mod3, .wrap1_hot_main,
        .mian_list_1, .mian_list_3, .footer, .d2,
        .wrap2_2014_mian .mian_t, .fl, .mt10,
        .mian_db, .mian_zb, .channel_list, .main-top,
        .main-bottom, .time-list, .program-list,
        .head2015, .content-nav, .footer_c, .clear, .mb15,
        .zb_c .content-nav ul, .zb_c .content-nav li,
        .zb_contit, .zb_con .zb_contit,
        .nav_search, .header-right, .niuka-box, .logo-icon, .menu-list,
        .menu-item, .wrap1_hot_main ul, .wrap1_hot_main li,
        [class*="ad"], [class*="banner"], [class*="copyright"],
        iframe:not([src*="m3u8"]):not([src*="hls"]),
        .breadcrumb, .recommend, .comment, .share {
            display: none !important;
        }

        /* 保留页面基本结构,确保播放器能正常初始化 */
        html, body {
            margin: 0 !important;
            padding: 0 !important;
            background: #000 !important;
            height: 100vh !important;
            width: 100vw !important;
            overflow: hidden !important;
        }

        /* 播放器容器 - 全屏显示 */
        .page-main, .wrap2_2014, .wrap2_2014_mian {
            margin: 0 !important;
            padding: 0 !important;
            width: 100vw !important;
            height: 100vh !important;
            background: #000 !important;
            position: fixed !important;
            top: 0 !important;
            left: 0 !important;
            overflow: hidden !important;
        }

        .videochannel, .video_c {
            width: 100vw !important;
            height: 100vh !important;
            margin: 0 !important;
            padding: 0 !important;
            background: #000 !important;
        }

        .video_a {
            width: 100% !important;
            height: 100% !important;
            margin: 0 !important;
            padding: 0 !important;
            background: #000 !important;
            position: relative !important;
        }

        /* DPlayer容器 - 确保全屏 */
        #dplayer {
            width: 100% !important;
            height: 100% !important;
            margin: 0 !important;
            padding: 0 !important;
            background: #000 !important;
        }

        /* 保留原生频道切换栏但移到顶部 */
        .mian_list_2 {
            display: block !important;
            position: fixed !important;
            top: 20px !important;
            left: 50% !important;
            transform: translateX(-50%) !important;
            z-index: 1000 !important;
            background: rgba(0,0,0,0.7) !important;
            border-radius: 30px !important;
            padding: 5px !important;
            backdrop-filter: blur(10px) !important;
            border: 1px solid rgba(204,145,29,0.3) !important;
        }

        .mian_list_2 .tv_list {
            background: none !important;
            width: auto !important;
            height: auto !important;
            display: flex !important;
            gap: 2px !important;
            margin: 0 !important;
            padding: 0 !important;
        }

        .mian_list_2 .tv_list li {
            width: auto !important;
            height: auto !important;
            line-height: normal !important;
            margin: 0 !important;
            padding: 8px 16px !important;
            color: #fff !important;
            border-radius: 25px !important;
            cursor: pointer !important;
            font-size: 14px !important;
            transition: all 0.3s !important;
            background: transparent !important;
            list-style: none !important;
            border: 1px solid transparent !important;
        }

        .mian_list_2 .tv_list li:hover {
            background: rgba(204,145,29,0.3) !important;
            border-color: rgba(204,145,29,0.5) !important;
        }

        .mian_list_2 .tv_list li.current {
            background: #cc911d !important;
            color: #fff !important;
        }

        /* 广播页面样式 */
        .zb_c, .zb_con {
            width: 100vw !important;
            height: 100vh !important;
            margin: 0 !important;
            padding: 0 !important;
            background: #000 !important;
            position: fixed !important;
            top: 0 !important;
            left: 0 !important;
        }

        .video_cont {
            width: 100% !important;
            height: 100% !important;
            padding: 0 !important;
            margin: 0 !important;
            background: #000 !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            position: relative !important;
        }

        /* 广播页面隐藏原生音频控件 */
        #Html5Video, .video_cont audio, .video_cont video {
            width: 0 !important;
            height: 0 !important;
            opacity: 0 !important;
            pointer-events: none !important;
            position: absolute !important;
        }

        /* 自定义广播播放器 */
        .nj-fm-player {
            position: fixed !important;
            top: 0 !important;
            left: 0 !important;
            width: 100vw !important;
            height: 100vh !important;
            background: linear-gradient(145deg, #111 0%, #1a1a1a 100%) !important;
            display: flex !important;
            flex-direction: column !important;
            align-items: center !important;
            justify-content: center !important;
            color: white !important;
            font-family: 'Microsoft YaHei', sans-serif !important;
            z-index: 2000 !important;
            backdrop-filter: blur(5px) !important;
        }

        .nj-fm-background {
            position: absolute !important;
            top: 0 !important;
            left: 0 !important;
            width: 100% !important;
            height: 100% !important;
            background: radial-gradient(circle at 30% 30%, #333, #000) !important;
            opacity: 0.4 !important;
            z-index: -1 !important;
        }

        .nj-fm-cover {
            width: 280px !important;
            height: 280px !important;
            border-radius: 50% !important;
            background: #222 !important;
            box-shadow: 0 20px 40px rgba(0,0,0,0.8), 0 0 0 4px rgba(204,145,29,0.3) !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            margin-bottom: 40px !important;
            transition: transform 0.5s ease !important;
        }

        .nj-fm-cover.playing {
            animation: rotate 20s linear infinite !important;
        }

        @keyframes rotate {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }

        .nj-fm-cover span {
            font-size: 120px !important;
            filter: drop-shadow(0 10px 10px rgba(0,0,0,0.5)) !important;
        }

        .nj-fm-info {
            text-align: center !important;
            margin-bottom: 30px !important;
        }

        .nj-fm-title {
            font-size: 32px !important;
            font-weight: bold !important;
            color: #fff !important;
            text-shadow: 0 2px 10px rgba(204,145,29,0.5) !important;
            margin-bottom: 8px !important;
        }

        .nj-fm-subtitle {
            font-size: 16px !important;
            color: #aaa !important;
            letter-spacing: 2px !important;
        }

        .nj-fm-controls {
            display: flex !important;
            align-items: center !important;
            gap: 30px !important;
            background: rgba(30,30,30,0.7) !important;
            backdrop-filter: blur(10px) !important;
            padding: 15px 40px !important;
            border-radius: 60px !important;
            border: 1px solid rgba(204,145,29,0.2) !important;
            box-shadow: 0 10px 30px rgba(0,0,0,0.5) !important;
        }

        .nj-fm-btn {
            width: 50px !important;
            height: 50px !important;
            border-radius: 50% !important;
            background: #333 !important;
            border: none !important;
            color: #cc911d !important;
            font-size: 24px !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            cursor: pointer !important;
            transition: all 0.2s ease !important;
            box-shadow: 0 4px 8px rgba(0,0,0,0.3) !important;
        }

        .nj-fm-btn:hover {
            background: #cc911d !important;
            color: #fff !important;
            transform: scale(1.1) !important;
        }

        .nj-fm-btn.play-pause {
            width: 70px !important;
            height: 70px !important;
            background: #cc911d !important;
            color: #fff !important;
            font-size: 32px !important;
        }

        .nj-fm-btn.play-pause:hover {
            background: #e6a72a !important;
        }

        .nj-fm-volume {
            display: flex !important;
            align-items: center !important;
            gap: 10px !important;
            margin-left: 20px !important;
        }

        .nj-fm-volume-slider {
            width: 100px !important;
            height: 4px !important;
            -webkit-appearance: none !important;
            background: #444 !important;
            border-radius: 2px !important;
            outline: none !important;
        }

        .nj-fm-volume-slider::-webkit-slider-thumb {
            -webkit-appearance: none !important;
            width: 16px !important;
            height: 16px !important;
            border-radius: 50% !important;
            background: #cc911d !important;
            cursor: pointer !important;
            box-shadow: 0 0 8px #cc911d !important;
        }

        .nj-fm-volume-icon {
            color: #cc911d !important;
            font-size: 20px !important;
            width: 30px !important;
            text-align: center !important;
        }

        /* 右侧滑动菜单 */
        .nj-right-menu {
            position: fixed !important;
            right: -320px !important;
            top: 0 !important;
            width: 300px !important;
            height: 100vh !important;
            background: rgba(10, 10, 10, 0.98) !important;
            backdrop-filter: blur(20px) !important;
            border-left: 1px solid rgba(204, 145, 29, 0.3) !important;
            z-index: 1000000 !important;
            display: flex !important;
            flex-direction: column !important;
            box-shadow: -2px 0 20px rgba(0,0,0,0.5) !important;
            font-family: "Microsoft YaHei", sans-serif !important;
            transition: right 0.3s ease !important;
        }

        .nj-right-menu.open {
            right: 0 !important;
        }

        .nj-menu-header {
            padding: 25px 20px !important;
            background: linear-gradient(135deg, #cc911d 0%, #b37b1a 100%) !important;
            border-bottom: 1px solid rgba(255,255,255,0.1) !important;
            display: block !important;
            visibility: visible !important;
            opacity: 1 !important;
            position: relative !important;
            z-index: 1000001 !important;
        }

        .nj-menu-header h2 {
            color: #fff !important;
            margin: 0 0 8px 0 !important;
            font-size: 22px !important;
            font-weight: bold !important;
            text-shadow: 0 2px 4px rgba(0,0,0,0.3) !important;
        }

        .nj-menu-header p {
            color: rgba(255,255,255,0.9) !important;
            margin: 0 !important;
            font-size: 14px !important;
            font-weight: normal !important;
        }

        .nj-menu-tabs {
            display: flex !important;
            padding: 15px 15px 10px !important;
            gap: 10px !important;
            border-bottom: 1px solid #333 !important;
        }

        .nj-tab-btn {
            flex: 1 !important;
            padding: 8px 12px !important;
            background: transparent !important;
            border: 1px solid #444 !important;
            color: #999 !important;
            border-radius: 20px !important;
            cursor: pointer !important;
            font-size: 14px !important;
            font-weight: 500 !important;
            transition: all 0.2s ease !important;
        }

        .nj-tab-btn:hover {
            background: rgba(204, 145, 29, 0.2) !important;
            border-color: #cc911d !important;
            color: #cc911d !important;
        }

        .nj-tab-btn.active {
            background: #cc911d !important;
            border-color: #cc911d !important;
            color: #fff !important;
        }

        .nj-channel-list {
            flex: 1 !important;
            overflow-y: auto !important;
            padding: 15px !important;
        }

        .nj-channel-item {
            display: flex !important;
            align-items: center !important;
            padding: 12px 15px !important;
            margin: 6px 0 !important;
            color: #ccc !important;
            text-decoration: none !important;
            border-radius: 12px !important;
            transition: all 0.2s ease !important;
            border: 1px solid transparent !important;
            background: rgba(255,255,255,0.03) !important;
            cursor: pointer !important;
        }

        .nj-channel-item:hover {
            background: rgba(204, 145, 29, 0.15) !important;
            border-color: rgba(204, 145, 29, 0.3) !important;
            transform: translateX(-5px) !important;
        }

        .nj-channel-item.active {
            background: #cc911d !important;
            color: #fff !important;
            box-shadow: 0 4px 10px rgba(204, 145, 29, 0.3) !important;
        }

        .nj-channel-icon {
            width: 40px !important;
            height: 40px !important;
            background: rgba(255,255,255,0.1) !important;
            border-radius: 10px !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            margin-right: 12px !important;
            font-size: 22px !important;
        }

        .nj-channel-item.active .nj-channel-icon {
            background: rgba(255,255,255,0.2) !important;
        }

        .nj-channel-info {
            flex: 1 !important;
        }

        .nj-channel-name {
            font-size: 15px !important;
            font-weight: 500 !important;
            margin-bottom: 4px !important;
        }

        .nj-channel-type {
            font-size: 11px !important;
            opacity: 0.7 !important;
        }

        .nj-menu-footer {
            padding: 15px 20px !important;
            border-top: 1px solid #333 !important;
            color: #888 !important;
            font-size: 12px !important;
            text-align: center !important;
            background: rgba(0,0,0,0.3) !important;
        }

        .nj-menu-toggle {
            position: fixed !important;
            right: 20px !important;
            top: 50% !important;
            transform: translateY(-50%) !important;
            width: 48px !important;
            height: 48px !important;
            background: #cc911d !important;
            border-radius: 24px 0 0 24px !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            color: #fff !important;
            font-size: 24px !important;
            cursor: pointer !important;
            z-index: 1000001 !important;
            box-shadow: -2px 0 15px rgba(0,0,0,0.4) !important;
            transition: right 0.3s ease, background 0.2s ease !important;
            border: 2px solid rgba(255,255,255,0.2) !important;
            border-right: none !important;
            padding: 0 !important;
        }

        .nj-menu-toggle:hover {
            background: #e6a72a !important;
            transform: translateY(-50%) scale(1.05) !important;
        }

        .nj-menu-toggle.menu-open {
            right: 300px !important;
        }

        .nj-current-channel-hint {
            position: fixed !important;
            top: 20px !important;
            left: 20px !important;
            background: rgba(0,0,0,0.7) !important;
            color: #fff !important;
            padding: 10px 20px !important;
            border-radius: 30px !important;
            font-size: 15px !important;
            font-weight: 500 !important;
            z-index: 999999 !important;
            backdrop-filter: blur(10px) !important;
            border: 1px solid rgba(204,145,29,0.3) !important;
            pointer-events: none !important;
            box-shadow: 0 4px 15px rgba(0,0,0,0.3) !important;
        }

        .nj-fullscreen-hint {
            position: fixed !important;
            bottom: 20px !important;
            right: 80px !important;
            color: rgba(255,255,255,0.7) !important;
            font-size: 13px !important;
            background: rgba(0,0,0,0.5) !important;
            padding: 6px 14px !important;
            border-radius: 30px !important;
            z-index: 999999 !important;
            backdrop-filter: blur(5px) !important;
            border: 1px solid rgba(255,255,255,0.1) !important;
            pointer-events: none !important;
            transition: opacity 0.3s ease !important;
            letter-spacing: 0.5px !important;
        }

        .nj-fullscreen-hint.hidden {
            opacity: 0 !important;
        }

        .nj-channel-list::-webkit-scrollbar {
            width: 4px !important;
        }
        .nj-channel-list::-webkit-scrollbar-track {
            background: #222 !important;
        }
        .nj-channel-list::-webkit-scrollbar-thumb {
            background: #cc911d !important;
            border-radius: 2px !important;
        }
    `);

    // 当前选中的标签
    let currentTab = 'tv';
    let menuOpen = false;
    let fmPlayer = null;
    let audioElement = null;
    let dplayerInitialized = false;

    // 判断页面类型
    function getPageType() {
        return location.hostname.includes('njgb.com') ? 'fm' : 'tv';
    }

    // 获取当前频道
    function getCurrentChannel() {
        const searchParams = new URLSearchParams(location.search);
        const id = searchParams.get('id');

        if (id) {
            const channel = NJ_CHANNELS.find(c => c.id === id);
            if (channel) return channel;
        }

        return NJ_CHANNELS.find(c => location.href.includes(c.u)) || NJ_CHANNELS[0];
    }

    // 切换频道
    function switchChannel(channel) {
        if (channel.type === 'tv') {
            location.href = channel.u.startsWith('http') ? channel.u : 'https://www.nbs.cn' + channel.u;
        } else {
            location.href = channel.u;
        }
    }

    // 更新标签按钮状态
    function updateTabsState() {
        const menu = document.querySelector('.nj-right-menu');
        if (!menu) return;
        menu.querySelectorAll('.nj-tab-btn').forEach(btn => {
            btn.classList.toggle('active', btn.dataset.tab === currentTab);
        });
    }

    // 渲染频道列表
    function renderChannelList(filter) {
        const menu = document.querySelector('.nj-right-menu');
        if (!menu) return;
        const list = menu.querySelector('#nj-channel-list');
        if (!list) return;

        list.innerHTML = '';
        NJ_CHANNELS.forEach(item => {
            if (item.type !== filter) return;
            const div = document.createElement('div');
            div.className = 'nj-channel-item';
            if (location.href.includes(item.u) || location.search.includes(item.id)) {
                div.classList.add('active');
            }
            div.innerHTML = `
                <div class="nj-channel-icon">${item.icon}</div>
                <div class="nj-channel-info">
                    <div class="nj-channel-name">${item.n.replace(/[&#128250;&#128251;]\s/, '')}</div>
                    <div class="nj-channel-type">${item.type === 'tv' ? '电视频道' : '广播频率'}</div>
                </div>
            `;
            div.addEventListener('click', (e) => {
                e.preventDefault();
                switchChannel(item);
            });
            list.appendChild(div);
        });
    }

    // 创建右侧滑动菜单
    function createRightMenu() {
        if (document.querySelector('.nj-right-menu')) {
            console.log('菜单已存在,跳过创建');
            return;
        }

        console.log('创建右侧菜单');
        const now = new Date();
        const timeStr = now.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
        currentTab = getPageType();

        console.log('当前时间:', timeStr);
        console.log('频道数量:', NJ_CHANNELS.length);

        const menu = document.createElement('div');
        menu.className = 'nj-right-menu';
        menu.innerHTML = `
            <div class="nj-menu-header">
                <h2>&#128225; 南京广播电视台</h2>
                <p>${timeStr} · ${NJ_CHANNELS.length}个频道</p>
            </div>
            <div class="nj-menu-tabs">
                <button class="nj-tab-btn ${currentTab === 'tv' ? 'active' : ''}" data-tab="tv">&#128250; 电视 (${NJ_CHANNELS.filter(c => c.type === 'tv').length})</button>
                <button class="nj-tab-btn ${currentTab === 'fm' ? 'active' : ''}" data-tab="fm">&#128251; 广播 (${NJ_CHANNELS.filter(c => c.type === 'fm').length})</button>
            </div>
            <div class="nj-channel-list" id="nj-channel-list"></div>
            <div class="nj-menu-footer">
                <span>&#9889; 点击频道快速切换 | 双击视频全屏</span>
            </div>
        `;

        menu.querySelectorAll('.nj-tab-btn').forEach(btn => {
            btn.addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();
                currentTab = e.target.dataset.tab;
                updateTabsState();
                renderChannelList(currentTab);
            });
        });

        document.body.appendChild(menu);
        console.log('菜单已添加到页面');

        const toggleBtn = document.createElement('div');
        toggleBtn.className = 'nj-menu-toggle';
        toggleBtn.innerHTML = '&#128250;';
        toggleBtn.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            toggleMenu();
        });
        document.body.appendChild(toggleBtn);

        renderChannelList(currentTab);
    }

    function toggleMenu() {
        const menu = document.querySelector('.nj-right-menu');
        const toggle = document.querySelector('.nj-menu-toggle');
        if (!menu || !toggle) return;
        menuOpen = !menuOpen;
        menu.classList.toggle('open', menuOpen);
        toggle.classList.toggle('menu-open', menuOpen);
        toggle.innerHTML = menuOpen ? '&#10005;' : '&#128250;';
    }

    function createChannelHint() {
        if (document.querySelector('.nj-current-channel-hint')) return;
        const channel = getCurrentChannel();
        const hint = document.createElement('div');
        hint.className = 'nj-current-channel-hint';
        hint.textContent = `${channel.icon} ${channel.n.replace(/[&#128250;&#128251;]\s/, '')}`;
        document.body.appendChild(hint);
    }

    function createFullscreenHint() {
        if (document.querySelector('.nj-fullscreen-hint')) return;
        const hint = document.createElement('div');
        hint.className = 'nj-fullscreen-hint';
        hint.textContent = '&#9974; 双击视频全屏';
        document.body.appendChild(hint);

        let timeout;
        document.addEventListener('mousemove', () => {
            hint.classList.remove('hidden');
            clearTimeout(timeout);
            timeout = setTimeout(() => {
                hint.classList.add('hidden');
            }, 2000);
        });
    }

    // 广播页面自定义播放器
    function createFmPlayer(audio) {
        if (document.querySelector('.nj-fm-player')) return;
        audioElement = audio;

        const channel = getCurrentChannel();
        const playerDiv = document.createElement('div');
        playerDiv.className = 'nj-fm-player';

        playerDiv.innerHTML = `
            <div class="nj-fm-background"></div>
            <div class="nj-fm-cover ${audio.paused ? '' : 'playing'}">
                <span>${channel.icon}</span>
            </div>
            <div class="nj-fm-info">
                <div class="nj-fm-title">${channel.n.replace(/[&#128250;&#128251;]\s/, '')}</div>
                <div class="nj-fm-subtitle">南京广播电视台 · 直播中</div>
            </div>
            <div class="nj-fm-controls">
                <button class="nj-fm-btn prev" title="上一个广播">&#9198;</button>
                <button class="nj-fm-btn play-pause">${audio.paused ? '&#9654;' : '&#9208;'}</button>
                <button class="nj-fm-btn next" title="下一个广播">&#9197;</button>
                <div class="nj-fm-volume">
                    <span class="nj-fm-volume-icon">&#128266;</span>
                    <input type="range" class="nj-fm-volume-slider" min="0" max="1" step="0.01" value="${audio.volume}">
                </div>
            </div>
        `;

        document.body.appendChild(playerDiv);
        fmPlayer = playerDiv;

        const playBtn = playerDiv.querySelector('.play-pause');
        const prevBtn = playerDiv.querySelector('.prev');
        const nextBtn = playerDiv.querySelector('.next');
        const volumeSlider = playerDiv.querySelector('.nj-fm-volume-slider');
        const cover = playerDiv.querySelector('.nj-fm-cover');

        playBtn.addEventListener('click', () => {
            if (audio.paused) {
                audio.play().then(() => {
                    playBtn.textContent = '&#9208;';
                    cover.classList.add('playing');
                }).catch(e => console.log('播放失败', e));
            } else {
                audio.pause();
                playBtn.textContent = '&#9654;';
                cover.classList.remove('playing');
            }
        });

        prevBtn.addEventListener('click', () => {
            const channels = NJ_CHANNELS.filter(c => c.type === 'fm');
            const current = getCurrentChannel();
            const index = channels.findIndex(c => c.id === current.id);
            const prev = channels[(index - 1 + channels.length) % channels.length];
            switchChannel(prev);
        });

        nextBtn.addEventListener('click', () => {
            const channels = NJ_CHANNELS.filter(c => c.type === 'fm');
            const current = getCurrentChannel();
            const index = channels.findIndex(c => c.id === current.id);
            const next = channels[(index + 1) % channels.length];
            switchChannel(next);
        });

        volumeSlider.addEventListener('input', (e) => {
            audio.volume = e.target.value;
        });

        audio.addEventListener('play', () => {
            playBtn.textContent = '&#9208;';
            cover.classList.add('playing');
        });
        audio.addEventListener('pause', () => {
            playBtn.textContent = '&#9654;';
            cover.classList.remove('playing');
        });
        audio.addEventListener('volumechange', () => {
            volumeSlider.value = audio.volume;
        });
    }

    // 激活当前电视频道高亮
    function highlightCurrentTVChannel() {
        const searchParams = new URLSearchParams(location.search);
        const id = searchParams.get('id');
        if (!id) return;

        document.querySelectorAll('.tv_list li').forEach(li => {
            li.classList.remove('current');
            if (li.classList.contains(`tv_c${id}`)) {
                li.classList.add('current');
            }
        });
    }

    // 为原生频道按钮添加点击事件
    function setupNativeChannelButtons() {
        document.querySelectorAll('.tv_list li').forEach(li => {
            li.removeEventListener('click', handleNativeChannelClick);
            li.addEventListener('click', handleNativeChannelClick);
        });
    }

    function handleNativeChannelClick() {
        const classes = this.className.split(' ');
        const tvClass = classes.find(c => c.startsWith('tv_c'));
        if (tvClass) {
            const id = tvClass.replace('tv_c', '');
            const channel = NJ_CHANNELS.find(c => c.id === id);
            if (channel) {
                switchChannel(channel);
            }
        }
    }

    // 电视页面初始化
    function initTVPage() {
        console.log('[南京广电] 电视页面初始化');

        setTimeout(() => {
            setupNativeChannelButtons();
            highlightCurrentTVChannel();

            const checkVideo = setInterval(() => {
                const video = document.querySelector('video');
                if (video && !dplayerInitialized) {
                    dplayerInitialized = true;
                    console.log('[南京广电] 检测到视频元素');
                    video.controls = true;
                    addDoubleClickFullscreen();
                    clearInterval(checkVideo);
                }
            }, 500);

            setTimeout(() => {
                clearInterval(checkVideo);
            }, 10000);

        }, 2000);

        createRightMenu();
        createChannelHint();
        createFullscreenHint();
    }

    // 广播页面初始化
    function initFMPage() {
        console.log('[南京广电] 广播页面初始化');

        const checkAudio = setInterval(() => {
            const audio = document.getElementById('Html5Video') || document.querySelector('audio') || document.querySelector('video');
            if (audio) {
                clearInterval(checkAudio);
                console.log('[南京广电] 找到音频元素');

                audio.controls = false;
                audio.style.cssText = 'width:0;height:0;opacity:0;pointer-events:none;position:absolute;';

                setTimeout(() => {
                    audio.play().then(() => {
                        console.log('音频自动播放成功');
                    }).catch(e => {
                        console.log('自动播放失败,等待用户交互');
                        const clickPlay = () => {
                            audio.play();
                            document.removeEventListener('click', clickPlay);
                        };
                        document.addEventListener('click', clickPlay, { once: true });
                    });
                }, 500);

                createFmPlayer(audio);
            }
        }, 500);

        createRightMenu();
        createChannelHint();
    }

    function addDoubleClickFullscreen() {
        const video = document.querySelector('video');
        const dplayer = document.getElementById('dplayer');
        const container = document.querySelector('.video_a');

        const elements = [video, dplayer, container].filter(el => el);

        elements.forEach(el => {
            if (el) {
                el.removeEventListener('dblclick', handleDoubleClick);
                el.addEventListener('dblclick', handleDoubleClick);
            }
        });
    }

    function handleDoubleClick(e) {
        e.preventDefault();
        e.stopPropagation();

        if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement) {
            if (document.exitFullscreen) document.exitFullscreen();
            else if (document.webkitExitFullscreen) document.webkitExitFullscreen();
            else if (document.mozCancelFullScreen) document.mozCancelFullScreen();
        } else {
            const player = document.querySelector('#dplayer') || document.querySelector('video') || document.querySelector('.video_a');
            if (player) {
                if (player.requestFullscreen) player.requestFullscreen();
                else if (player.webkitRequestFullscreen) player.webkitRequestFullscreen();
                else if (player.mozRequestFullScreen) player.mozRequestFullScreen();
            }
        }
    }

    // 更新时间
    function updateTime() {
        const timeDisplay = document.querySelector('.nj-menu-header p');
        if (timeDisplay) {
            const now = new Date();
            const timeStr = now.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
            timeDisplay.textContent = `${timeStr} · ${NJ_CHANNELS.length}个频道`;
        }

        const hint = document.querySelector('.nj-current-channel-hint');
        if (hint) {
            const channel = getCurrentChannel();
            hint.textContent = `${channel.icon} ${channel.n.replace(/[&#128250;&#128251;]\s/, '')}`;
        }

        if (getPageType() === 'tv') {
            highlightCurrentTVChannel();
        }
    }

    setInterval(updateTime, 1000);

    function init() {
        console.log('[南京广电] 脚本启动', location.href);
        const pageType = getPageType();

        setTimeout(() => {
            if (pageType === 'tv') {
                initTVPage();
            } else {
                initFMPage();
            }
        }, 1000);
    }

    // 监听页面变化
    let lastUrl = location.href;
    const observer = new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;
            console.log('[南京广电] 页面切换:', url);
            dplayerInitialized = false;
            document.querySelectorAll('.nj-right-menu, .nj-menu-toggle, .nj-current-channel-hint, .nj-fullscreen-hint, .nj-fm-player').forEach(el => el.remove());
            setTimeout(init, 1500);
        }
    });
    observer.observe(document, { subtree: true, childList: true });

    // 在DOM加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();

免费评分

参与人数 3吾爱币 +9 热心值 +3 收起 理由
laozhang4201 + 1 + 1 热心回复!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
ku-yu + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Mi3na4 发表于 2026-3-15 12:07
專注于地方台與廣播,這個腳本有計劃加上其他地方台嗎。
想來央視網頁和學習強國軟件都有看廣電和聽廣播的說
 楼主| huangmin1111 发表于 2026-3-15 11:20
梅球王 发表于 2026-3-15 11:24
本帖最后由 beyond0729 于 2026-3-15 15:35 编辑

感谢大佬分享,不知道有没有时间看下河南的有些节目隐藏了
男生 发表于 2026-3-15 11:30
一般我都是手机下载电视直播软件。
戰龍在野 发表于 2026-3-15 12:37
老大,怎么使用呢,谢谢
easonrose 发表于 2026-3-15 13:22
有没有安卓电视版
cnmi 发表于 2026-3-15 13:56
电视有什么好用的直播软件
daymissed 发表于 2026-3-15 15:02
谢谢分享,测试一下感觉速度还可以。
xxx123444 发表于 2026-3-15 16:16
有机会其他电视台吗?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-5-7 16:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表