轶哥

📚 Having fun with AI Agent. Always learning.

    自助设备广告屏自动播放视频功能实现
    •   更新:2021-04-06 18:28:01
    •   首发:2021-04-06 18:28:01
    •   教程
    •   5654

    接到一个需求,基于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

    打赏
    交流区

    暂无内容

    尚未登陆
    发布
      上一篇 (Win10中通过WSL2开发基于Electron的Ubuntu应用程序)
    下一篇 (记一次Intel AX201网卡卡顿问题解决)  

    评论回复提醒