vue项目中 引入mpegtsjs 插件用法及 WebSocket 播放 FLV 流 模拟监控指南
(接受了一个新项目需要对接监控,但是海康的demo页面功能基本用不到,所以自己写一个小实例通过其他方式播放监控画面,防止忘记)
前端部分
1. 插件介绍
mpegts.js 是一个用于在浏览器中播放 MPEG-TS 流的 JavaScript 库,它支持通过 HTTP、WebSocket 等协议播放 FLV 格式的视频流,特别适用于直播场景。
2. 安装方法
在 Vue 项目中,可以通过 npm 安装 mpegts.js:
bash
npm install mpegts.js --save
3. 基本使用步骤
3.1 引入库
在需要使用的组件中引入 mpegts.js:
javascript
import mpegtsjs from 'mpegts.js'
3.2 创建视频元素
在模板中添加 video 元素:
html
<video id="video" autoplay muted width="1050" height="1050"></video>
3.3 初始化播放器
在组件挂载后初始化播放器:
javascript
import { onMounted, nextTick } from 'vue'
onMounted(() => {
initPlayer()
})
const initPlayer = () => {
nextTick(() => {
const videoElement = document.getElementById('video')
const player = mpegtsjs.createPlayer({
url: "ws://localhost:8765", // WebSocket 链接
type: 'flv', // 流类型
isLive: true // 是否为直播流
})
player.attachMediaElement(videoElement)
player.load()
player.play()
})
}
4. 通过 WebSocket 播放 FLV 流
4.1 配置参数
javascript
const player = mpegtsjs.createPlayer({
url: "ws://localhost:8765", // WebSocket 服务器地址
type: 'flv', // 流类型为 FLV
isLive: true, // 直播流模式
// 可选配置
hasAudio: true, // 是否有音频
hasVideo: true, // 是否有视频
stashInitialSize: 128 // 初始缓存大小
})
4.2 完整示例
vue
<template>
<div>
<video id="video" autoplay muted width="1050" height="1050"></video>
</div>
</template>
<script setup>
import { onMounted, nextTick } from 'vue'
import mpegtsjs from 'mpegts.js'
onMounted(() => {
initPlayer()
})
const initPlayer = () => {
nextTick(() => {
const videoElement = document.getElementById('video')
const player = mpegtsjs.createPlayer({
url: "ws://localhost:8765",
type: 'flv',
isLive: true
})
player.attachMediaElement(videoElement)
player.load()
player.play()
// 错误处理和重连机制
player.on('error', (err) => {
console.error('播放器错误:', err)
// 3 秒后尝试重新加载
setTimeout(() => {
player.load()
player.play()
}, 3000)
})
})
}
</script>
5. 错误处理和重连机制
为了提高直播流的稳定性,可以添加错误监听和自动重连机制:
javascript
player.on('error', (err) => {
console.error('播放器错误:', err)
// 尝试重新加载
setTimeout(() => {
player.load()
player.play()
}, 3000) // 3 秒后重试
})
6. 事件监听
mpegts.js 支持多种事件,可以根据需要监听:
javascript
// 播放开始
player.on('play', () => {
console.log('播放开始')
})
// 暂停
player.on('pause', () => {
console.log('暂停播放')
})
// 结束
player.on('ended', () => {
console.log('播放结束')
})
// 加载状态变化
player.on('loadedmetadata', () => {
console.log('元数据加载完成')
})
7. 注意事项
- 确保 WebSocket 服务器提供的 FLV 流格式正确
- 对于直播流,设置
isLive: true
以获得更好的性能 - 考虑添加缓冲策略和网络状况监测,以提高用户体验
- 浏览器可能对自动播放有限制,必要时添加用户交互触发播放
希望本指南对你使用 mpegts.js 播放 FLV 流有所帮助!
后端部分
视频流服务器教程
项目概述
这个项目实现了一个基于Python和FFmpeg的视频流服务器,它能够将MP4视频文件实时转码为FLV格式,并通过WebSocket协议发送给客户端用于模拟监控。
所需依赖
- Python 3.7+
- FFmpeg (需要安装并添加到系统PATH)
- Python库:
websockets
安装依赖
bash
pip install websockets
代码解析
1. 导入库和配置日志
python
import logging
from websockets import serve
import asyncio
# 配置日志系统
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[logging.StreamHandler()]
)
2. 视频流处理核心逻辑
python
async def video_stream(websocket):
"""视频流处理核心逻辑"""
try:
# 生成FFmpeg命令
ffmpeg_cmd = await generate_ffmpeg_command()
# 启动FFmpeg进程
process = await asyncio.create_subprocess_exec(
*ffmpeg_cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
logging.info("FFmpeg进程启动(PID: %d)", process.pid)
# 流量控制参数
MAX_BUFFER_SIZE = 10 * 1024 * 1024 # 10MB
buffer_size = 0
try:
while True:
# 读取数据块
chunk = await read_data_chunk(process)
# 流量控制
buffer_size += len(chunk)
if buffer_size > MAX_BUFFER_SIZE:
logging.warning("缓冲区溢出,等待客户端处理...")
await asyncio.sleep(0.1)
continue
# 发送数据
await websocket.send(chunk)
logging.debug("已发送 %d 字节数据", len(chunk))
finally:
# 资源清理
await cleanup_resources(process)
except Exception as e:
logging.error("视频流处理异常: %s", str(e))
await websocket.close(code=1011, reason=str(e))
3. 生成FFmpeg命令
python
async def generate_ffmpeg_command():
"""生成FFmpeg转码命令"""
return [
'ffmpeg',
'-i', 'oceans.mp4',
'-f', 'flv',
'-c:v', 'libx264',
'-preset', 'fast',
'-crf', '23',
'-c:a', 'aac',
'-b:a', '128k',
'pipe:1'
]
4. 读取数据块和清理资源
python
async def read_data_chunk(process):
"""从FFmpeg进程读取数据块"""
chunk = await process.stdout.read(4096)
if not chunk:
logging.info("视频流传输完成")
raise asyncio.CancelledError
return chunk
async def cleanup_resources(process):
"""清理系统资源"""
if process.returncode is None:
logging.info("终止FFmpeg进程")
process.terminate()
try:
await asyncio.wait_for(process.wait(), timeout=5)
except asyncio.TimeoutError:
process.kill()
logging.debug("资源清理完成")
5. 主函数
python
async def main():
async with serve(video_stream, "localhost", 8765):
logging.info("流媒体服务器已在 ws://localhost:8765 启动")
await asyncio.Future() # 保持服务器运行
if __name__ == "__main__":
asyncio.run(main())
使用方法
- 确保已安装所有依赖
- 将视频文件命名为
oceans.mp4
并放在同一目录下 - 运行服务器:
bash
python mp4_flv.py
- 使用WebSocket客户端连接到
ws://localhost:8765
接收视频流
自定义修改
- 更改视频源文件: 修改
generate_ffmpeg_command
函数中的-i
参数 - 更改输出格式: 修改
-f
参数和对应的编码器设置 - 更改服务器端口: 修改
main
函数中的端口号
可能的扩展
- 添加多个视频源支持
- 实现视频流录制功能
- 添加用户认证机制
- 实现Web界面进行控制
注意事项
- 确保FFmpeg已正确安装并添加到系统PATH
- 视频转码需要一定的CPU资源,请根据实际情况调整转码参数
- 对于大型视频文件,可能需要调整缓冲区大小参数