<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/rss/stylesheet/" type="text/xsl"?>
<rss xmlns:content='http://purl.org/rss/1.0/modules/content/' xmlns:taxo='http://purl.org/rss/1.0/modules/taxonomy/' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:itunes='http://www.itunes.com/dtds/podcast-1.0.dtd' xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0" xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:atom='http://www.w3.org/2005/Atom' xmlns:podbridge='http://www.podbridge.com/podbridge-ad.dtd' version='2.0'>
<channel>
  <title>DBD-博客</title>
  <language>zh-cn</language>
  <generator>microfeed.org</generator>
  <itunes:type>episodic</itunes:type>
  <itunes:explicit>false</itunes:explicit>
  <atom:link rel="self" href="https://cms.4km.qzz.io/rss/" type="application/rss+xml"/>
  <link>https://my-microfeed.z2326173351-8c6.workers.dev</link>
  <description>
    <![CDATA[<style>
        #api-text-container {
            font-size: 20px;
            max-width: 100%;
            text-align: center;
            line-height: 1.6;
            padding: 20px;
            border-left: 4px solid #4CAF50;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
@media (max-width: 768px) {
            #api-text-container {
                font-size: 19px; /* 移动端减小到18px */
                max-width: 100%; /* 移动端宽度占比更大（减少留白） */
                padding: 15px; /* 移动端内边距减小 */
            }
    </style>
<p id="api-text-container"></p>
<script>
  // 调用文字API（以「一言」为例，返回随机句子）
  fetch("https://v1.hitokoto.cn/?c=d") // API地址（返回JSON）
    .then(response => response.json())
    .then(data => {
      // 将API返回的文字填入容器（不添加任何样式，使用网站默认文本样式）
      document.getElementById("api-text-container").textContent = data.hitokoto;
    })
    .catch(error => {
      // 加载失败时显示提示（同样使用默认样式）
      document.getElementById("api-text-container").textContent = "加载失败，请稍后刷新";
    });
</script>
<p>这是一款轻量级的内容管理系统（CMS），可自行托管于Cloudflare平台。通过microfeed，您能够便捷地发布多种形式的内容——包括音频、视频、照片、文档、博客文章及外部链接，并以网页、RSS订阅和JSON格式输出信息流。</p>]]>
  </description>
  <itunes:author>DBD制作组</itunes:author>
  <itunes:image href="https://cms.4km.qzz.io/assets/default/channel-image.png"/>
  <image>
    <title>DBD-博客</title>
    <url>https://cms.4km.qzz.io/assets/default/channel-image.png</url>
    <link>https://my-microfeed.z2326173351-8c6.workers.dev</link>
  </image>
  <copyright>©2026</copyright>
  <item>
    <title>随机播放器 - 简易版</title>
    <guid>xAP2KEv6gm5</guid>
    <pubDate>Sun, 06 Sep 2026 20:55:51 GMT</pubDate>
    <itunes:explicit>false</itunes:explicit>
    <description>
      <![CDATA[<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>随机跳舞视频播放器</title>
<style>
  /* ===== 性能优化：GPU 加速 & 最小化重绘 ===== */
  * { margin: 0; padding: 0; box-sizing: border-box; }
  :root {
    --bg: #0a0a0a;
    --accent: #ff2d95;
    --accent2: #7b2dff;
    --text: #fff;
    --radius: 14px;
  }
  //body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    background: var(--bg);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
  }

  /* ===== 播放器容器 ===== */
  .player-wrap {
    margin: 0 auto;
    width: 100%;
    max-width: 480px;
    background: #111;
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0,0,0,.5);
    position: relative;
    /* contain 提示浏览器优化渲染 */
    contain: layout style paint;
  }

  /* ===== 视频区域 ===== */
  .video-container {
    position: relative;
    width: 100%;
    aspect-ratio: 9 / 16;
    background: #000;
    overflow: hidden;
  }
  .video-container video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* 硬件加速 */
    transform: translateZ(0);
    will-change: auto;
  }

  /* 加载动画 */
  .loader {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background: rgba(0,0,0,.75);
    z-index: 10;
    transition: opacity .3s;
    pointer-events: none;
  }
  .loader.hidden { opacity: 0; }
  .spinner {
    width: 42px;
    height: 42px;
    border: 3px solid rgba(255,255,255,.2);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin .7s linear infinite;
  }
  @keyframes spin { to { transform: rotate(360deg); } }
  .loader-text {
    color: rgba(255,255,255,.7);
    font-size: 13px;
    margin-top: 12px;
  }

  /* ===== 顶部信息栏 ===== */
  .top-bar {
    position: absolute;
    top: 0; left: 0; right: 0;
    padding: 14px 16px 40px;
    background: linear-gradient(180deg, rgba(0,0,0,.6), transparent);
    z-index: 5;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .badge {
    background: rgba(255,45,149,.9);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 4px 10px;
    border-radius: 20px;
    letter-spacing: .5px;
  }
  .api-indicator {
    font-size: 11px;
    color: rgba(255,255,255,.6);
    background: rgba(0,0,0,.4);
    padding: 4px 8px;
    border-radius: 6px;
  }

  /* ===== 控制栏 ===== */
  .controls {
    position: absolute;
    bottom: 0; left: 0; right: 0;
    padding: 40px 14px 14px;
    background: linear-gradient(0deg, rgba(0,0,0,.75), transparent);
    z-index: 5;
    display: flex;
    gap: 10px;
    align-items: center;
  }
  .btn {
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform .15s, opacity .2s;
    -webkit-tap-highlight-color: transparent;
  }
  .btn:active { transform: scale(.92); }
  .btn:disabled { opacity(.4); cursor: not-allowed; }

  /* 刷新/切换按钮（主按钮） */
  .btn-refresh {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), var(--accent2));
    color: #fff;
    flex-shrink: 0;
    box-shadow: 0 4px 15px rgba(255,45,149,.4);
  }
  .btn-refresh svg { width: 22px; height: 22px; fill: #fff; }
  .btn-refresh.spinning svg { animation: spin .7s linear infinite; }

  /* 播放/暂停 */
  .btn-play {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: rgba(255,255,255,.15);
    backdrop-filter: blur(10px);
    color: #fff;
    flex-shrink: 0;
  }
  .btn-play svg { width: 20px; height: 20px; fill: #fff; }

  /* 进度条 */
  .progress-wrap {
    flex: 1;
    height: 4px;
    background: rgba(255,255,255,.25);
    border-radius: 2px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }
  .progress-bar {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, var(--accent), var(--accent2));
    border-radius: 2px;
    transition: width .1s linear;
  }

  /* 时间 */
  .time {
    font-size: 11px;
    color: rgba(255,255,255,.8);
    font-variant-numeric: tabular-nums;
    min-width: 42px;
    text-align: right;
  }

  /* ===== Toast 提示 ===== */
  .toast {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(.8);
    background: rgba(0,0,0,.85);
    color: #fff;
    font-size: 14px;
    padding: 10px 22px;
    border-radius: 10px;
    z-index: 20;
    opacity: 0;
    transition: all .25s;
    pointer-events: none;
    white-space: nowrap;
    backdrop-filter: blur(8px);
  }
  .toast.show {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }

  /* ===== 错误状态 ===== */
  .error-state {
    position: absolute;
    inset: 0;
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background: rgba(0,0,0,.85);
    z-index: 15;
    color: #fff;
    text-align: center;
    padding: 20px;
  }
  .error-state.show { display: flex; }
  .error-state svg { width: 40px; height: 40px; fill: #ff4757; margin-bottom: 10px; }
  .error-state p { font-size: 14px; opacity: .8; margin-bottom: 14px; }
  .error-state button {
    background: var(--accent);
    color: #fff;
    border: none;
    padding: 8px 24px;
    border-radius: 20px;
    font-size: 14px;
    cursor: pointer;
  }
</style>
</head>
<body>

<!--
=============================================
  可嵌入博客的用法：
  复制下面的代码片段直接粘贴到博客 HTML 中即可

  <iframe src="https://你的域名/dance-player.html" width="100%" height="700" frameborder="0" allowfullscreen></iframe>

  或者如果你想要自适应高度：
  <div style="max-width:480px;margin:0 auto;">
    <iframe src="dance-player.html" width="100%" height="750" frameborder="0" allow="autoplay; fullscreen" style="border-radius:14px;"></iframe>
  </div>
=============================================
-->
<br><br>
<div class="player-wrap" id="playerWrap"><!-- 视频容器 -->
  <div class="video-container"><video id="videoEl" playsinline loop preload="metadata"></video>

    <!-- 顶部栏 -->
    <div class="top-bar"><span class="badge">🔥 随机舞蹈</span>
      <span class="api-indicator" id="apiIndicator">API #1</span></div>
    <!-- 加载动画 -->
    <div class="loader" id="loader">
      <div class="spinner"></div>
      <div class="loader-text">正在加载视频...</div>
    </div>
    <!-- Toast -->
    <div class="toast" id="toast"></div>
    <!-- 错误状态 -->
    <div class="error-state" id="errorState"><svg viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>
      <p id="errorText">加载失败</p>
      <button onclick="player.fetchVideo()">重试</button>
    </div>
    <!-- 控制栏 -->
    <div class="controls"><button class="btn btn-play" id="playBtn" title="播放/暂停">
        <svg id="playIcon" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
        <svg id="pauseIcon" viewBox="0 0 24 24" style="display:none"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
      </button>
      <div class="progress-wrap" id="progressWrap">
        <div class="progress-bar" id="progressBar"></div>
      </div>
      <span class="time" id="timeEl">0:00</span>
      <button class="btn btn-refresh" id="refreshBtn" title="切换视频">
        <svg viewBox="0 0 24 24"><path d="M17.65 6.35A7.958 7.958 0 0012 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0112 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 9h7V2l-2.35 4.35z"/></svg>
      </button>
    </div>
  </div>
</div>
<script>
/* ============================================================
   高性能随机舞蹈视频播放器
   - 支持多个 API 切换（轮询 / 故障转移）
   - 视频预加载 & 缓存
   - 错误自动重试
   - 可嵌入博客（iframe 方式）
============================================================ */
(function () {
  'use strict';

  // ===== API 配置（可扩展多个） =====
  const API_ENDPOINTS = [
    'http://api.nonebot.top/api/v1/random/dance_video',
    // 在这里添加更多 API 地址实现故障转移：
    // 'http://api.nonebot.top/api/v1/random/dance_video',
  ];

  // ===== DOM 元素 =====
  const videoEl     = document.getElementById('videoEl');
  const loader      = document.getElementById('loader');
  const toast       = document.getElementById('toast');
  const errorState  = document.getElementById('errorState');
  const errorText   = document.getElementById('errorText');
  const refreshBtn  = document.getElementById('refreshBtn');
  const playBtn     = document.getElementById('playBtn');
  const playIcon    = document.getElementById('playIcon');
  const pauseIcon   = document.getElementById('pauseIcon');
  const progressBar = document.getElementById('progressBar');
  const progressWrap= document.getElementById('progressWrap');
  const timeEl      = document.getElementById('timeEl');
  const apiIndicator= document.getElementById('apiIndicator');

  // ===== 状态 =====
  let currentApiIndex = 0;
  let isLoading = false;
  let retryCount = 0;
  const MAX_RETRY = 2;
  // 简单缓存：避免短时间内重复同一个视频
  let lastVideoUrl = '';

  // ===== 工具函数 =====
  function showLoader(show) {
    loader.classList.toggle('hidden', !show);
  }

  function showToast(msg) {
    toast.textContent = msg;
    toast.classList.add('show');
    clearTimeout(toast._timer);
    toast._timer = setTimeout(() => toast.classList.remove('show'), 1500);
  }

  function formatTime(sec) {
    if (!sec || isNaN(sec)) return '0:00';
    const m = Math.floor(sec / 60);
    const s = Math.floor(sec % 60);
    return m + ':' + (s < 10 ? '0' : '') + s;
  }

  // ===== 核心：获取视频 =====
  async function fetchVideoUrl() {
    const apiUrl = API_ENDPOINTS[currentApiIndex];
    apiIndicator.textContent = 'API #' + (currentApiIndex + 1);

    try {
      const res = await fetch(apiUrl, {
        method: 'GET',
        headers: { 'Accept': 'application/json' },
        // 防止缓存导致一直拿到同一个视频
        cache: 'no-store'
      });

      if (!res.ok) throw new Error('HTTP ' + res.status);

      const json = await res.json();
      // 兼容不同返回格式
      const videoUrl = json.data || json.url || json.video_url || (json.result && json.result.url);

      if (!videoUrl) throw new Error('未获取到视频地址');

      return videoUrl;
    } catch (err) {
      console.warn('[DancePlayer] API 请求失败:', err.message);
      // 尝试切换到下一个 API
      if (currentApiIndex < API_ENDPOINTS.length - 1) {
        currentApiIndex++;
        return fetchVideoUrl(); // 递归尝试下一个
      }
      throw err;
    }
  }

  // ===== 加载并播放视频 =====
  async function loadVideo(isManualRefresh) {
    if (isLoading) return;
    isLoading = true;
    showLoader(true);
    errorState.classList.remove('show');
    if (isManualRefresh) {
      refreshBtn.classList.add('spinning');
    }

    try {
      let videoUrl = await fetchVideoUrl();

      // 如果跟上次一样，再请求一次（避免重复）
      if (videoUrl === lastVideoUrl && retryCount < MAX_RETRY) {
        retryCount++;
        videoUrl = await fetchVideoUrl();
      }
      retryCount = 0;
      lastVideoUrl = videoUrl;

      // 设置视频源
      videoEl.src = videoUrl;

      // 预加载元数据
      await new Promise((resolve, reject) => {
        const onLoaded = () => { cleanup(); resolve(); };
        const onError  = () => { cleanup(); reject(new Error('视频加载失败')); };
        function cleanup() {
          videoEl.removeEventListener('loadedmetadata', onLoaded);
          videoEl.removeEventListener('error', onError);
        }
        videoEl.addEventListener('loadedmetadata', onLoaded);
        videoEl.addEventListener('error', onError);
        // 超时保护
        setTimeout(() => { cleanup(); reject(new Error('加载超时')); }, 15000);
      });

      // 自动播放（移动端需要 muted，但这里是视频所以直接播）
      try {
        await videoEl.play();
      } catch (e) {
        console.info('[DancePlayer] 自动播放被阻止，等待用户交互');
      }

      showLoader(false);
      if (isManualRefresh) showToast('🎉 已切换新视频');

    } catch (err) {
      console.error('[DancePlayer] 加载失败:', err);
      showLoader(false);
      errorText.textContent = '网络异常，请检查连接';
      errorState.classList.add('show');
      if (isManualRefresh) showToast('❌ 加载失败');
    } finally {
      isLoading = false;
      refreshBtn.classList.remove('spinning');
    }
  }

  // ===== 事件绑定 =====

  // 刷新/切换按钮
  refreshBtn.addEventListener('click', function () {
    // 手动切换时轮转到下一个 API
    currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length;
    loadVideo(true);
  });

  // 播放/暂停
  playBtn.addEventListener('click', function () {
    if (videoEl.paused) {
      videoEl.play();
    } else {
      videoEl.pause();
    }
  });

  videoEl.addEventListener('play', function () {
    playIcon.style.display = 'none';
    pauseIcon.style.display = 'block';
  });
  videoEl.addEventListener('pause', function () {
    playIcon.style.display = 'block';
    pauseIcon.style.display = 'none';
  });

  // 进度条更新
  videoEl.addEventListener('timeupdate', function () {
    const pct = (videoEl.currentTime / videoEl.duration) * 100;
    progressBar.style.width = pct + '%';
    timeEl.textContent = formatTime(videoEl.currentTime);
  });

  // 点击进度条跳转
  progressWrap.addEventListener('click', function (e) {
    const rect = progressWrap.getBoundingClientRect();
    const pct = (e.clientX - rect.left) / rect.width;
    videoEl.currentTime = pct * videoEl.duration;
  });

  // 视频结束自动加载下一个
  videoEl.addEventListener('ended', function () {
    currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length;
    loadVideo(false);
  });

  // ===== 对外暴露 API（供父页面调用） =====
  window.DancePlayer = {
    refresh: function () { loadVideo(true); },
    play: function () { videoEl.play(); },
    pause: function () { videoEl.pause(); },
    setApi: function (index) {
      currentApiIndex = index % API_ENDPOINTS.length;
      loadVideo(true);
    }
  };

  // ===== 初始化 =====
  loadVideo(false);

})();
</script>
</body>]]>
    </description>
    <link>https://cms.4km.cc.cd/i/111-xAP2KEv6gm5/</link>
    <itunes:episodeType>full</itunes:episodeType>
  </item>
</channel>
</rss>