vue项目中 引入mpegtsjs 插件用法及 WebSocket 播放 FLV 流 模拟监控指南

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. 注意事项

  1. 确保 WebSocket 服务器提供的 FLV 流格式正确
  2. 对于直播流,设置 isLive: true 以获得更好的性能
  3. 考虑添加缓冲策略和网络状况监测,以提高用户体验
  4. 浏览器可能对自动播放有限制,必要时添加用户交互触发播放

希望本指南对你使用 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())

使用方法

  1. 确保已安装所有依赖
  2. 将视频文件命名为oceans.mp4并放在同一目录下
  3. 运行服务器:
bash 复制代码
python mp4_flv.py
  1. 使用WebSocket客户端连接到 ws://localhost:8765 接收视频流

自定义修改

  • 更改视频源文件: 修改generate_ffmpeg_command函数中的-i参数
  • 更改输出格式: 修改-f参数和对应的编码器设置
  • 更改服务器端口: 修改main函数中的端口号

可能的扩展

  1. 添加多个视频源支持
  2. 实现视频流录制功能
  3. 添加用户认证机制
  4. 实现Web界面进行控制

注意事项

  • 确保FFmpeg已正确安装并添加到系统PATH
  • 视频转码需要一定的CPU资源,请根据实际情况调整转码参数
  • 对于大型视频文件,可能需要调整缓冲区大小参数
相关推荐
Hilaku41 分钟前
别再手写i18n了!深入浏览器原生Intl对象(数字、日期、复数处理)
前端·javascript·代码规范
每天吃饭的羊1 小时前
强制缓存与协商缓存
前端
缘来小哥1 小时前
Nodejs的多版本管理,不仅仅只是nvm的使用
前端·node.js
陈随易1 小时前
Vite和pnpm都在用的tinyglobby文件匹配库
前端·后端·程序员
LeeAt1 小时前
还在为移动端项目组件发愁?快来试试React Vant吧!
前端·web components
鹏程十八少1 小时前
4. Android 用户狂赞的UI特效!揭秘折叠卡片+流光动画的终极实现方案
前端
Cache技术分享2 小时前
141. Java 泛型 - Java 泛型方法的类型擦除
前端·后端
YGY_Webgis糕手之路2 小时前
OpenLayers 综合案例-基础图层控制
前端·gis
PineappleCoder2 小时前
玩转CSS3新特性:让你的网页会“呼吸”!
前端·css·设计
言兴2 小时前
构建高效 React 应用:从组件设计到状态管理的全面指南
前端·javascript