Video.js 暂停后继续播放(通过 IMA 播放广告时)

问题描述 投票:0回答:1

我使用 IMA 在我的 Video.js 播放器中播放广告。我已经这样设置了几个月,直到最近一切都很好。问题是视频和广告同时播放。我在播放广告之前暂停视频,但它仍在播放。我只能在 Android 上的 Chrome 上复制此问题,但其他用户声称在不同的情况下遇到此问题。在生产中,这种情况经常发生,但在我的 CodePen 示例中很少发生。

我正在做的事情:我有两个用于 VAST 响应的端点 - 一个内部源(通常为空)和一个外部源,当内部源失败时我使用该外部源。我需要从我的域请求它们,因此我手动获取此端点并将响应放入 IMA。

事情是这样的:

  1. 用户按下播放或自动播放发生
  2. 视频暂停 - 问题就在这里,有时它会继续播放
  3. 第一个 VAST 已获取,但它是空的
  4. 第二个 VAST 被获取并放入 IMA
  5. 广告正在播放
  6. 广告结束,视频恢复 - 出现问题时,视频恢复 已经在进行中

我尝试手动检查广告是否正在播放并暂停视频(如果是),但这并不能解决问题并会中断 iOS 上的播放。

这里是示例:https://codepen.io/davlasq/pen/RwOpJJV

<html>

<head>
  <link href="https://unpkg.com/[email protected]/dist/video-js.css" rel="stylesheet">
  <link href="https://unpkg.com/[email protected]/dist/videojs.ima.css" rel="stylesheet">
  <meta charset="utf-8">
  <title>Video.js Starter Template</title>
</head>

<body>
  <video id="my_video" class="video-js" controls width="300">
    <source src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8" type="application/x-mpegURL">
  </video>
  <script src="//imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/video.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/videojs.ads.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/videojs.ima.js"></script>
</body>

</html>

const Plugin = videojs.getPlugin("plugin");

// without initializing plugins in setTimeout they don't work for some reason
// so I created this wrapper
class Delay extends Plugin {
  constructor(player, options) {
    super(player, options);

    setTimeout(() => {
      Object.keys(options).forEach((pluginName) => {
        if (pluginName === "ima" && typeof google === "undefined") {
          return;
        }
        player[pluginName](options[pluginName]);
      });
    });
  }
}

videojs.registerPlugin("delay", Delay);

class MyPlugin extends Plugin {
  constructor(player, options) {
    super(player, options);
    this.options = options;
    this.setAds();
  }

  setAds() {
    if (
      !this.options.ads?.vast ||
      !this.player.ima ||
      typeof google === "undefined" ||
      !google?.ima
    ) {
      return;
    }

    this.player.one("play", () => {
      this.playAds(this.options.ads.vast, () => {
        if (this.options.ads.vast_programmatic) {
          this.playAds(this.options.ads.vast_programmatic);
        }
      });
    });
  }

  async playAds(url, onError) {
    this.player.pause();

    const handleError = () => {
      if (typeof onError === "function") {
        onError();
      } else {
        this.player.play();
      }
    };

    try {
      const vast = await (await fetch(url, { mode: "cors" })).text();

      if (!vast) {
        handleError();
        return;
      }

      this.player.ima.controller.settings.adsResponse = vast;

      this.player.ima.controller.settings.adsManagerLoadedCallback = () => {
        this.player.ima.addEventListener(
          google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED,
          () => {
            this.player.play();
          }
        );
      };

      this.player.one("adserror", handleError);
      this.player.ima.requestAds();
    } catch (error) {
      handleError();
    }
  }
}

videojs.registerPlugin("myplugin", MyPlugin);

const config = {
  plugins: {
    delay: {
      ima: {},
      myplugin: {
        ads: {
          vast: "https://some.failing.url/", // internal ads (often empty)
          vast_programmatic:
            "https://cdnzone.nuevodevel.com/pub/5.0/e-v-1/vmap_ad_sample.xml" // external ads (used when no internal ads)
        }
      }
    }
  }
};

document.addEventListener("DOMContentLoaded", () => {
  const video = document.querySelector("video");
  videojs(video, config);
});
javascript ads video.js ima
1个回答
0
投票

IMA 的问题:https://github.com/googleads/videojs-ima/issues/1098 这是我的解决方法:

let tempVolume;

player.ima.addEventListener(google.ima.AdEvent.Type.STARTED, () => {
  const adVideoEl = player.el().querySelector(".ima-ad-container video[src]");
  tempVolume = player.volume();
  player.volume(0);
  adVideoEl.volume = tempVolume;
});

player.ima.addEventListener(google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, () => {
    player.currentTime(0);
    player.volume(tempVolume);
    player.src(player.src());
    player.play();
  }
);

所以基本上我在广告开始时将视频静音,然后在广告结束时取消静音并重新加载。

© www.soinside.com 2019 - 2024. All rights reserved.