NodeJs 实现简单视频播放
# NodeJs 实现简单视频播放
# 实际展示效果
# 准备
本次使用 nodeJs express
框架实现简单视频播放,需安装使用 nodeJs
新建一个文件夹 命名为 node-video,创建完后进入文件夹
初始化项目
执行初始化命令,按照默认生成 package.json 文件
npm init -y安装
express
安装 express
npm i express按照上图创建相关目录 及 目录文件
static 文件夹中放置视频播放 html 页面
static/index.html 视频播放 html 页面
video 文件夹中放置 视频文件
index.js 为 nodeJs 入口文件
# 主要页面代码
# nodeJs 服务代码
index.js
var express = require('express')
var app = express()
var fs = require('fs')
var path = require('path')
// 设置静态资源文件目录
app.use(express.static(path.resolve(__dirname, './static')))
// 返回体
let obj = {
code: '0',
success: true,
msg: 'ok',
data: null,
}
// 获取播放列表
app.get('/videList', (req, res, next) => {
// 获取 video 目录下的视频文件
fs.readdir('./video', 'utf8', (err, file) => {
if (err) {
obj.code = '-1'
obj.success = false
obj.msg = err
obj.data = null
} else {
obj.code = '0'
obj.success = true
obj.msg = 'ok'
obj.data = file
}
res.send(obj)
})
})
// 根据名称,返回视频文件数据
app.get('/video', function(req, res, next) {
const { name } = req.query
let path = './video/' + name
let stat
let flag = false
try {
stat = fs.statSync(path)
} catch (error) {
flag = true
}
if (flag) {
res.send({
code: '-1',
msg: 'no video',
})
return false
}
let fileSize = stat.size
let range = req.headers.range
let type = name.split('.')[1]
let videoType = 'video/' + type
if (range) {
//有range头才使用206状态码
let parts = range.replace(/bytes=/, '').split('-')
let start = parseInt(parts[0], 10)
let end = parts[1] ? parseInt(parts[1], 10) : start + 999999
// end 在最后取值为 fileSize - 1
end = end > fileSize - 1 ? fileSize - 1 : end
let chunksize = end - start + 1
let file = fs.createReadStream(path, { start, end })
let head = {
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
'Accept-Ranges': 'bytes',
'Content-Length': chunksize,
'Content-Type': videoType,
}
res.writeHead(206, head)
file.pipe(res)
} else {
let head = {
'Content-Length': fileSize,
'Content-Type': videoType,
}
res.writeHead(200, head)
fs.createReadStream(path).pipe(res)
}
})
// 启动express服务器
var server = app.listen(8081, function() {
var host = server.address().address
var port = server.address().port
console.log('应用实例,访问地址为 http://%s:%s', host, port)
})
# 视频播放页
static/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>video</title>
<!-- Video.js -->
<link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet" />
<script src="https://unpkg.com/video.js/dist/video.min.js"></script>
<script src="https://unpkg.com/flv.js/dist/flv.min.js"></script>
<script src="https://unpkg.com/videojs-flvjs/dist/videojs-flvjs.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 简单样式美化 -->
<style>
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
position: relative;
background-color: rgba(0, 0, 0, 0.5);
}
.content {
width: 100%;
min-width: 1000px;
height: 100%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
/* 背景图 可替换为任意一张 1920*1080 或使用背景色 */
background: url('./timg.jpg') no-repeat center center / cover;
/* background-color: rgba(0, 0, 0, 0.9); */
}
.contentBox {
display: flex;
justify-content: center;
align-items: center;
padding: 15px;
border: 1px solid #ccc;
border-radius: 15px;
background-color: rgba(255, 255, 255, 0.7);
}
#videoBox {
width: 600px;
height: 450px;
border-radius: 15px;
overflow: hidden;
}
#videoList {
width: 250px;
height: 450px;
list-style: none;
margin-left: 15px;
padding-left: 15px;
overflow-y: auto;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 15px;
}
#videoList .Oli {
height: 30px;
line-height: 30px;
margin-bottom: 6px;
cursor: pointer;
}
#videoList .Oli:hover,
#videoList .Oli.cur {
color: red;
}
</style>
</head>
<body>
<div class="content">
<div class="contentBox">
<div id="videoBox">
<video id="videojs-flvjs-player" class="video-js vjs-default-skin vjs-big-play-centered"></video>
</div>
<ul id="videoList"></ul>
</div>
</div>
<script>
var videoName = '2.flv'
var videoType = 'video/flv'
function myVideo(Oid) {
// 调用video插件 播放视频
return videojs(
Oid,
{
techOrder: ['html5', 'flvjs'],
flvjs: {
mediaDataSource: {
isLive: false,
cors: true,
withCredentials: false,
},
},
playbackRates: [1, 1.5, 2, 3], // 配置播放速率
aspectRatio: '4:3',
fluid: true,
controls: true,
preload: 'none',
},
function() {
console.log('player ready')
player.src({
src: 'http://localhost:8081/video?name=' + videoName,
type: videoType,
})
player.ready(function() {
console.log('player ready')
player.load()
player.play()
})
player.on('error', (err) => {
console.log('video load error', err)
// player.errorDisplay.close()
player.pause()
})
}
)
}
var player = myVideo('videojs-flvjs-player')
function done(name) {
// 视频播放事件
const type = name.split('.')[1]
// 获取视频格式 此次只配置 flv 和 MP4 格式,其他格式可自行配置
if (type === 'flv') {
videoType = 'video/flv'
} else {
videoType = 'video/mp4'
}
videoName = name
player = myVideo('videojs-flvjs-player')
}
function handleClick(name, index) {
// 播放列表点击事件
const Oul = document.getElementById('videoList')
const Ali = Oul.getElementsByTagName('li')
for (let i = 0; i < Ali.length; i++) {
if (index == i) {
// 设置播放列表当前播放项类名
Ali[i].classList = 'Oli cur'
} else {
Ali[i].classList = 'Oli'
}
}
done(name)
}
function createVideoList() {
// 获取播放列表
const Oul = document.getElementById('videoList')
axios.get('http://localhost:8081/videList').then((res) => {
if (res.data.data.length) {
for (let i = 0; i < res.data.data.length; i++) {
const Oli = document.createElement('li')
Oli.classList = 'Oli'
// 绑定播放列表项点击事件
Oli.onclick = function() {
handleClick(res.data.data[i], i)
}
Oli.innerHTML = res.data.data[i]
Oul.append(Oli)
}
}
})
}
// 初始化时生成播放列表
createVideoList()
</script>
</body>
</html>
# package.json
{
"name": "node-video",
"version": "1.0.0",
"description": "nodeJs实现简单视频播放功能,express + videoJs",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "xiaoc",
"license": "ISC",
"dependencies": {
"express": "^4.17.1"
}
}
# 说明
根据以上步骤配置好了后
进入项目目录
在video
目录中放置几个.mp4
或.flv
格式的视频文件
执行 node index.js
,启动nodeJs
服务器
打开http://localhost:8081
即可看到效果页