You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shaka Player中video.ui未定义问题排查求助

问题

我搭建了一个测试Shaka Player的Demo页面,用于播放MPD格式的直播内容。页面代码如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link rel="stylesheet" href="main.css">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.3.2/shaka-player.compiled.js"></script>
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/shaka-player/4.3.2/controls.css">
    <script defer src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script>

    <script src="main.js"></script>
    <title>Salt TV Client</title>
</head>

<body>
    <header id="header">
<h1 class="display-6 text-center">Salt TV Client</h1>
<hr />
</header>
    <nav class="navbar navbar-expand-lg navbar-dark">
  <div class="container-fluid">
  <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNav">
      <ul class="navbar-nav">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="/">Home</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Features</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Pricing</a>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
        </li>
      </ul>
    </div>
  </div>
</nav>
    <br>
    <main class="container">
        <h1>Guarda RSI La1 HD</h1>
        <br />

        <div class="ratio ratio-16x9" id="video-container">
      <video controls id="video" playsinline></video>
        </div>

    </main>
    <footer>
<hr />
<div class="container">
<span id="digital-clock"></span>
</div>
</footer>

</body>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js" integrity="sha384-mQ93GR66B00ZXjt0YO5KlohRA5SY2XofN4zfuZxLkoj1gXtW8ANNCe9d5Y3eG5eD" crossorigin="anonymous"></script>

<script>
const manifestUri = /* My URL */

function initApp() {
      // Install built-in polyfills to patch browser incompatibilities.
      shaka.polyfill.installAll();

      // Check to see if the browser supports the basic APIs Shaka needs.
      if (shaka.Player.isBrowserSupported()) {
        // Everything looks good!
        initPlayer();
      } else {
        // This browser does not have the minimum set of APIs we need.
        console.error('Browser not supported!');
      }
    }

    async function initPlayer() {
      // Create a Player instance.
      const video = document.getElementById('video');
      const player = new shaka.Player(video);

      // Attach player to the window to make it easy to access in the JS console.
      window.player = player;

      // Listen for error events.
      player.addEventListener('error', onErrorEvent);

      // Try to load a manifest.
      // This is an asynchronous process.
      try {
        await player.load(manifestUri);
        await video.play();
        // This runs if the asynchronous load is successful.
        console.log('The video has now been loaded!');
      } catch (e) {
        // onError is executed if the asynchronous load fails.
        onError(e);
      }
    }

    function onErrorEvent(event) {
      // Extract the shaka.util.Error object from the event.
      onError(event.detail);
    }

    function onError(error) {
      // Log the error.
      console.error('Error code', error.code, 'object', error);
    }

    document.addEventListener('DOMContentLoaded', initApp);
</script>
</html>

当尝试访问video.ui以配置播放器UI时,发现video.ui为undefined,希望video.ui对象可正常定义,从而对Shaka Player的UI进行配置。

原因分析

Shaka Player的UI控制组件(shaka.ui.Overlay)不会自动挂载到video元素上,当前代码仅初始化了核心的shaka.Player实例,未初始化UI层。video.ui是在创建shaka.ui.Overlay实例并关联video和player后才会被赋值的。

解决方案

需要手动初始化Shaka的UI组件,步骤如下:

  1. 确认已引入Shaka Player的UI样式文件(代码中已引入controls.css,此步骤无需修改)。
  2. 在initPlayer函数中,创建shaka.ui.Overlay实例,关联video元素和player实例:
async function initPlayer() {
  const video = document.getElementById('video');
  const player = new shaka.Player(video);

  // 初始化UI组件,关联播放器、视频元素和容器
  const ui = new shaka.ui.Overlay(player, video, document.getElementById('video-container'));
  
  // 此时video.ui不再是undefined
  console.log(video.ui);

  // 后续原有代码保持不变...
}
  1. 若需自定义UI配置,可在创建Overlay时传入配置对象,例如隐藏部分控件:
const uiConfig = {
  controlPanelElements: ['play_pause', 'volume', 'fullscreen'],
  seekBarColors: {
    base: '#eee',
    buffered: '#ccc',
    played: '#00ff00'
  }
};
const ui = new shaka.ui.Overlay(player, video, document.getElementById('video-container'), uiConfig);

内容的提问来源于stack exchange,提问作者Niccolò Cavallini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 01:25:23