NPlayer 是一个高度可定制、支持移动端、功能强大的弹幕视频播放器。你可以自定义所有图标、主题色和每个控制项的位置,并且提供了内置组件方便二次开发。你可以自定义任意多个断点,不仅仅是兼容移动端,只要愿意,你可以非常轻松的兼容手机竖屏、手机横屏、平板等设备。弹幕系统是通过插件形式提供,使用时按需引入即可,弹幕系统支持非常多的设置,并且不限制后端实现,可以非常轻松就可以接入。NPlayer 还支持 IE 11,SSR,任何流媒体,直播等等。
移动 / 平板 / 桌面 / 自定义断点
NPlayer 支持移动、平板和桌面。还可以自定义任意多个不同的断点,例如下面提到的 Mini 模式或扩展手机横屏模式,都可以通过自定义断点来轻松实现。
NPlayer 交互和布局是分离的。一般我们在手机上看视频,单击视频会显示控制条,双击是播放暂停视频,左右滑动可以快进或快退视频。而在电脑上单击视频是播放暂停,双击是全屏,键盘上的左右快捷键可以快进快退视频。
NPlayer 支持上面提到的两套交互,可以通过 isTouch
参数来设置播放器是使用哪一套交互,默认情况下会在播放器初始化时自动检测是否是触屏,如果是将使用触屏交互逻辑否则使用键鼠交互。
自定义主题
NPlayer 的主题色和所有的图标都可以自定义,非常轻松就可以切换成另一套主题。就像下面这样。
完整代码请查看 自定义 Bilibili 主题。
弹幕
NPlayer 弹幕功能是通过插件形式提供的,在需要的时候按需引入即可。
更多请查看 弹幕插件。
Mini 窗口
当我们用电脑在视频网站上看视频的时候,如果我们向下滚动页面,当播放器消失时,一般会在页面右下角出现一个 Mini 播放器。如下所示。
使用上面提到的自定义断点,我们可以非常轻松的实现 Mini 播放器功能。
代码语言:javascript复制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 容器中,就会应用 bpControls
中 500
的布局,从而隐藏掉一些非必要的控制项。
流媒体
NPlayer 没有内置实现各种流媒体协议。要使用 NPlayer 播放流媒体需要引入相关类库。比如,播放 HLS 可以引入 hls.js、 shaka hls等相关库,播放 DASH 可以引入 dashjs。
代码语言:javascript复制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 的内置组件,非常快速的实现自己的控制项。比如给播放器加个清晰度切换功能。
完整代码请查看 清晰度切换。
截图
除了上面的控制条项,右键菜单也是可以自定义。下面就用右键菜单来视频截图功能。
代码语言:javascript复制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)
镜像
我们再来用设置项的方式来实现视频镜像功能。
代码语言:javascript复制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)
代码语言:javascript复制.nplayer_video-mirroring { transform: scaleX(-1);
}
Vue2 / Vue3 / React
为了方面在 Vue 和 React 上使用,NPlayer 也提供了相关的组件。
代码语言:javascript复制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 的例子,更多请查看相关文档。
- React 组件文档
- Vue2 / Vue3 插件文档
总结
NPlayer 是一个支持移动端、高度可定制的弹幕视频播放器。无任何第三方运行时依赖,Gzip 大小 23.3 KB。如果有问题、新的功能或发现 BUG 欢迎创建 issue。
- 官网:https://nplayer.js.org
- 源码:https://github.com/woopen/nplayer
- 在线编辑 & 预览:https://codesandbox.io/s/nplayer-demo-ujtms?file=/src/index.js