NPlayer 支持移动、平板、桌面,高度可定制的弹幕视频播放器

3,979 阅读4分钟

NPlayer 是一个高度可定制、支持移动端、功能强大的弹幕视频播放器。你可以自定义所有图标、主题色和每个控制项的位置,并且提供了内置组件方便二次开发。你可以自定义任意多个断点,不仅仅是兼容移动端,只要愿意,你可以非常轻松的兼容手机竖屏、手机横屏、平板等设备。弹幕系统是通过插件形式提供,使用时按需引入即可,弹幕系统支持非常多的设置,并且不限制后端实现,可以非常轻松就可以接入。NPlayer 还支持 IE 11,SSR,任何流媒体,直播等等。

移动 / 平板 / 桌面 / 自定义断点

NPlayer 支持移动、平板和桌面。还可以自定义任意多个不同的断点,例如下面提到的 Mini 模式或扩展手机横屏模式,都可以通过自定义断点来轻松实现。

NPlayer 交互和布局是分离的。一般我们在手机上看视频,单击视频会显示控制条,双击是播放暂停视频,左右滑动可以快进或快退视频。而在电脑上单击视频是播放暂停,双击是全屏,键盘上的左右快捷键可以快进快退视频。

NPlayer 支持上面提到的两套交互,可以通过 isTouch 参数来设置播放器是使用哪一套交互,默认情况下会在播放器初始化时自动检测是否是触屏,如果是将使用触屏交互逻辑否则使用键鼠交互。

66a99c29eaa836a1c099c0d14bdc343a166a8891.gif

自定义主题

NPlayer 的主题色和所有的图标都可以自定义,非常轻松就可以切换成另一套主题。就像下面这样。

nplayer custom theme

完整代码请查看 自定义 Bilibili 主题

弹幕

NPlayer 弹幕功能是通过插件形式提供的,在需要的时候按需引入即可。

未标题-22.jpg

更多请查看 弹幕插件

Mini 窗口

当我们用电脑在视频网站上看视频的时候,如果我们向下滚动页面,当播放器消失时,一般会在页面右下角出现一个 Mini 播放器。如下所示。

使用上面提到的自定义断点,我们可以非常轻松的实现 Mini 播放器功能。

import Player from 'nplayer'

const videoContainer = document.querySelector('.video_container')
const miniContainer = document.querySelector('.mini_container')

const player = new Player({
  src: 'https://v-cdn.zjol.com.cn/280443.mp4',
  bpControls: {
    500: [
      ['play', 'progress', 'time'],
    ]
  }
})

const interObserver = new IntersectionObserver((entries) => {
  player.mount(entries[0].isIntersecting ? videoContainer : miniContainer)
}, {
  root: null,
  threshold: 0
})

interObserver.observe(videoContainer);

上面通过 IntersectionObserver API 来检测当前播放器是否在视口中可见,如果不可见就将播放器挂载到 Mini DOM 容器元素中。

上面省略了视频容器和 Mini 容器的 CSS 代码。我们假设 Mini 容器宽度是小于 500 的,所以当播放器挂载到 Mini 容器中,就会应用 bpControls500 的布局,从而隐藏掉一些非必要的控制项。

流媒体

NPlayer 没有内置实现各种流媒体协议。要使用 NPlayer 播放流媒体需要引入相关类库。比如,播放 HLS 可以引入 hls.js、 shaka hls等相关库,播放 DASH 可以引入 dashjs。

import Hls from 'hls'
import Player from 'player'

const hls = new Hls()
const player = new Player()
hls.attachMedia(player.video)

hls.on(Hls.Events.MEDIA_ATTACHED, function () {
  hls.loadSource('https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8')
})

player.mount(document.body)

上方是使用 hls.js 播放流媒体的例子,其他流媒体也可以用类似的方法播放,只需要提供 player.video 给相关播放库就行。

更多请查看流媒体

清晰度切换

NPlayer 是高度可扩展的,除了内置的控制项,你可以使用 NPlayer 的内置组件,非常快速的实现自己的控制项。比如给播放器加个清晰度切换功能。

image.png

完整代码请查看 清晰度切换

截图

除了上面的控制条项,右键菜单也是可以自定义。下面就用右键菜单来视频截图功能。

import Player from 'nplayer'

const Screenshot = {
  html: '截图',
  click(player) {
    const canvas = document.createElement('canvas')
    canvas.width = player.video.videoWidth
    canvas.height = player.video.videoHeight
    canvas.getContext('2d').drawImage(player.video, 0, 0, canvas.width, canvas.height)
    canvas.toBlob((blob) => {
        let dataURL = URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = dataURL
        link.download = 'NPlayer.png'
        link.style.display = 'none'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        URL.revokeObjectURL(dataURL)
    })
  }
}

const player = new Player({
  contextMenus: [Screenshot, 'loop', 'pip', 'version'],
})
player.mount(document.body)

镜像

我们再来用设置项的方式来实现视频镜像功能。

const Mirroring = {
  type: 'switch',
  html: '视频镜像',
  checked: false,
  init(player) {
    player.video.classList.remove('nplayer_video-mirroring')
    // 默认不是镜像
  },
  change(value, player) {
    player.video.classList.toggle('nplayer_video-mirroring', value)
    // 通过添加移除 class 来让视频是否是镜像
  }
}

const player = new Player({
  settings: [Mirroring, 'speed']
})
player.mount(document.body)
.nplayer_video-mirroring {
  transform: scaleX(-1);
}

Vue2 / Vue3 / React

为了方面在 Vue 和 React 上使用,NPlayer 也提供了相关的组件。

import { useEffect, useRef } from "react";
import NPlayer from "@nplayer/react";

export default function App() {
  const player = useRef();

  useEffect(() => {
    console.log(player.current);
  }, []);

  return (
    <div>
      <NPlayer
        ref={player}
        options={{ src: "https://v-cdn.zjol.com.cn/280443.mp4" }}
      />
    </div>
  );
}

上面是 React 的例子,更多请查看相关文档。

总结

NPlayer 是一个支持移动端、高度可定制的弹幕视频播放器。无任何第三方运行时依赖,Gzip 大小 23.3 KB。如果有问题、新的功能或发现 BUG 欢迎创建 issue

相关文章