4

自助设备广告屏自动播放视频功能实现

 3 years ago
source link: https://www.wyr.me/post/684
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
自助设备广告屏自动播放视频功能实现 - 轶哥
自助设备广告屏自动播放视频功能实现

接到一个需求,基于Electron开发Windows下的自助设备广告屏(上屏)自动播放视频的功能。设备下屏是带触控功能的屏幕,可以进行业务咨询、业务办理、视频咨询,上屏是不带触控功能的1080P屏幕。

%E8%87%AA%E5%8A%A9%E8%AE%BE%E5%A4%87.jpg 两个屏幕接入了同一个主机,下屏是主屏幕,上屏是分屏(扩展屏)。为了避免下屏进行视频咨询的时候,上屏播放视频的声音影响到对话,因此上屏播放视频功能需要开放相应的API接口,在下屏播放视频或进行音视频咨询的时候,相关的开发者能够通过API对上屏视频禁音。

由于我们已经开发了Android平台的同款设备,因此Electron平台需要和Android平台保持一致的API。

Android平台的双屏播放视频API接口如下:

// 视频播放地址/下载地址:  
SpeakerManager.videoUrl({0: "https://qiniu.laway.cn/mp4"})

// 视频静音  
SpeakerManager.videoMute()   

// 视频打开声音
SpeakerManager.videoUnMute() 

// 控制上屏声音
SpeakerManager.videoVolume(0.2) 

Electron获取副屏

const displays = screen.getAllDisplays()
const externalDisplay = displays.find((display) => {
  return display.bounds.x !== 0 || display.bounds.y !== 0
})

根据Electron官方文档说明,上述方法可以获取到副屏(扩展屏、上屏)。

创建上屏窗口并传递消息

if (externalDisplay) {
    const { width, height } = externalDisplay.workAreaSize
    const externalWin = new BrowserWindow({
      x: externalDisplay.bounds.x,
      y: externalDisplay.bounds.y,
      width,
      height,
      alwaysOnTop: false, // 总在最顶
      useContentSize: true,
      frame: false, // 显示标题栏
      resizable: false, // 不可改变尺寸
      center: true,
      minimizable: false,
      maximizable: true,
      focusable: true,
      kiosk: true,
      show: true,
      autoHideMenuBar: true,
      disableAutoHideCursor: true,
      webPreferences: {
        webSecurity: false,
        nodeIntegration: true,
        nodeIntegrationInWorker: true,
        nodeIntegrationInSubframes: true,
        contextIsolation: false
      }
    })
    externalWin.loadURL(`file://${__dirname}/video/index.html`)

    ipcMain.on('SpeakerManager', (_event, action, value) => {
      externalWin.webContents.send(action, value)
    })
}

单独打开一个窗口显示在副屏。监听渲染进程传递过来的SpeackerManager事件并传递给副屏。

自动循环播放视频、控制音量的页面实现

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>视频播放</title>
  <style>
    html,
    body,
    #loading,
    #my-player {
      padding: 0;
      margin: 0;
      width: 100%;
      height: 100%;
    }
  </style>
  <link href="video-js/video-js.min.css" rel="stylesheet">
  <script src="video-js/video.min.js"></script>
</head>

<body>
  <h1 id="loading">载入中...</h1>
  <video id="my-player" class="video-js" preload="auto" data-setup='{}'>
    <p class="vjs-no-js">
      To view this video please enable JavaScript, and consider upgrading to a
      web browser that
      <a href="https://videojs.com/html5-video-support/" target="_blank">
        supports HTML5 video
      </a>
    </p>
  </video>
  <script>
    const { ipcRenderer } = require("electron");

    var player = null;

    ipcRenderer.on('videoUrl', (e, list) => {
      var curr = 0;
      var options = {
        "width": "1920px",
        "height": "1080px",
        "autoplay": true,
        "controls": false,
        "muted": false,
        "sources": [{
          src: list[curr],
          type: 'video/mp4'
        }],
      };

      player = videojs('my-player', options, function onPlayerReady() {
        this.src({ type: 'video/mp4', src: list[curr] });
        this.load();
        document.getElementById('loading').style.display = 'none';
        this.play();
        this.on('ended', () => {
          curr++
          if (curr >= list.length) {
            curr = 0; //重新循环播放
          }
          this.src({ type: 'video/mp4', src: list[curr] });
          this.load();
          this.play();
        });
      });
    })

    ipcRenderer.on('videoMute', (e) => {
      if (player) player.muted(true)
    })

    ipcRenderer.on('videoUnMute', (e) => {
      if (player) player.muted(false)
    })

    ipcRenderer.on('videoVolume', (e, volume) => {
      if (player) player.volume(volume); //Volume range 0.0 to 1 (0.0, 0.1, 0.2 ...)
    })

  </script>
</body>

</html>

上述代码中,引入了开源项目video.js,通过ipcRenderer监听了相应的操作,实现对视频进行自动播放、循环播放,控制音量、禁音、取消禁音。

渲染进程注入控制方法

const { ipcRenderer } = require("electron");
var SpeakerManager = {
  videoUrl(list) { // 设置播放列表
    ipcRenderer.send('SpeakerManager', 'videoUrl', list)
  },
  videoMute() { // 静音
    ipcRenderer.send('SpeakerManager', 'videoMute')
  },
  videoUnMute() { // 取消静音
    ipcRenderer.send('SpeakerManager', 'videoUnMute')
  },
  videoVolume(num) { // 设置音量
    ipcRenderer.send('SpeakerManager', 'videoVolume', num)
  }
}
window.SpeakerManager = SpeakerManager

setTimeout(() => {
  SpeakerManager.videoUrl(['http://vjs.zencdn.net/v/oceans.mp4']) // 必须先启动
}, 3000)

setTimeout(() => {
  SpeakerManager.videoVolume(0.5) // 控制音量
}, 6000)

绑定到window全局变量,这样一来就可以实现和Android平台一致的API,开发人员可以一套代码同时运行在Windows平台和Android平台。

开源Demo

以上测试Demo的源代码已放到仓库:

https://github.com/yi-ge/electron-video


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK