vue flvjs 播放视频

写在前面:

之前使用过vodiejs插件播放过mp4视频格式的视频;

此次需要使用flvjs插件播放rtsp视频格式的视频;

因为视频的数据格式不同,所以对应的插件不同。

 思维导图:

参考链接:rtmp、rtsp、flv、m3u8、 

一、rtsp+flvjs前端实现

1.npm 安装依赖

npm i flv.js

2.使用(vue)

<template>
  <div class="video_home">
    <video class="videoBox" muted autoplay controls ref="player"></video>
  </div>
</template>
 
<script>
import flvjs from 'flv.js' // 引入flvjs
export default {
  data () {
    return {
      player: null
    }
  },
  mounted () {
    // 如果浏览器支持flvjs,则执行相应的程序
    if (flvjs.isSupported()) {
      // 准备监控设备流地址
      const url = 'rtsp://admin:1234567@192.168.1.100:554/Streaming/Channels/101?transportmode=unicast'
      // 创建一个flvjs实例
      // 下面的ws://localhost:8888换成你搭建的websocket服务地址,后面加上设备流地址
      this.player = flvjs.createPlayer({
        type: 'flv',
        isLive: true,
        url: 'ws://localhost:8888/' + url
      })
      
      this.player.on('error', (e) => {
        console.log(e)
      })
      
     // 将实例挂载到video元素上面
      this.player.attachMediaElement(this.$refs.player)
      
      try {
        // 开始运行加载 只要流地址正常 就可以在h5页面中播放出画面了
        this.player.load()
        this.player.play()
      } catch (error) {
        console.log(error)
      }  
    }
  },
  beforeDestroy () {
    // 页面销毁前 关闭flvjs
    this.player.destroy()
  }
}
</script>
 
<style lang="scss" scoped>
  .video_home{
    .videoBox{
      width: 300px;
      height: 300px;
    }
  }
</style>

 3.使用(react)

import React, { useEffect, useRef } from 'react';
import './FlvVideoPlayer.scss';
import flvjs from 'flv.js';
import { Button } from '@alifd/next';

interface FlvVideoPlayerProps {
  url?: string; // rtsp 的url
  isNeedControl?: boolean;
  fullScreenRef?: any; // 方便组件外部调用全屏方法的ref
}

const FlvVideoPlayer = React.forwardRef<any, FlvVideoPlayerProps>(({ isNeedControl, url, fullScreenRef }, ref) => {
  const videoDomRef = useRef<any>();
  const playerRef = useRef<any>(); // 储存player的实例

  React.useImperativeHandle(ref, () => ({
    requestFullscreen,
  }));

  useEffect(() => {
    if (videoDomRef.current) {
      if (fullScreenRef) {
        fullScreenRef.current[url] = requestFullscreen;
      }
      // const url = `${videoUrl}/rtsp/video1/?url=${url}`;
      playerRef.current = flvjs.createPlayer({
        type: 'flv',
        isLive: true,
        url,
      });
      playerRef.current.attachMediaElement(videoDomRef.current);
      try {
        playerRef.current.load();
        playerRef.current.play();
      } catch (error) {
        console.log(error);
      }
    }

    return () => {
      destroy();
    };
  }, [url]);

  /**
   * 全屏方法
   */
  const requestFullscreen = () => {
    if (videoDomRef.current) {
      (videoDomRef.current.requestFullscreen && videoDomRef.current.requestFullscreen()) ||
        (videoDomRef.current.webkitRequestFullScreen && videoDomRef.current.webkitRequestFullScreen()) ||
        (videoDomRef.current.mozRequestFullScreen && videoDomRef.current.mozRequestFullScreen()) ||
        (videoDomRef.current.msRequestFullscreen && videoDomRef.current.msRequestFullscreen());
    }
  };

  /**
   * 销毁flv的实例
   */
  const destroy = () => {
    if (playerRef.current) {
      playerRef.current.pause();
      playerRef.current.unload();
      playerRef.current.detachMediaElement();
      playerRef.current.destroy();
      playerRef.current = null;
    }
  };

  return (
    <>
      <Button type="primary" onClick={requestFullscreen}>
        全屏按钮
      </Button>
      <video controls={isNeedControl} ref={videoDomRef} className="FlvVideoPlayer" loop />
    </>
  );
});

export default FlvVideoPlayer;

二、ffmpeg+nodejs+websocket

简介:

后端代码:

const ffmpegPath = require('@ffmpeg-installer/ffmpeg'); // 自动为当前node服务所在的系统安装ffmpeg
const ffmpeg = require('fluent-ffmpeg');
const express = require('express');
const webSocketStream = require('websocket-stream/stream');
const expressWebSocket = require('express-ws');

ffmpeg.setFfmpegPath(ffmpegPath.path);

/**
 * 创建一个后端服务
 */
function createServer() {
    const app = express();
    app.use(express.static(__dirname));
    expressWebSocket(app, null, {
        perMessageDeflate: true
    });
    app.ws('/rtsp/', rtspToFlvHandle);

    app.get('/', (req, response) => {
        response.send('当你看到这个页面的时候说明rtsp流媒体服务正常启动中......');
    });

    app.listen(8100, () => {
        console.log('转换rtsp流媒体服务启动了,服务端口号为8100');
    });
}

/**
 * rtsp 转换 flv 的处理函数
 * @param ws
 * @param req
 */
function rtspToFlvHandle(ws, req) {
    const stream = webSocketStream(ws, {
        binary: true,
        browserBufferTimeout: 1000000
    }, {
        browserBufferTimeout: 1000000
    });
    // const url = req.query.url;
    const url = new Buffer(req.query.url, 'base64').toString(); // 前端对rtsp url进行了base64编码,此处进行解码
    console.log('rtsp url:', url);
    try {
        ffmpeg(url)
            .addInputOption(
                '-rtsp_transport', 'tcp',
                '-buffer_size', '102400'
            )
            .on('start', (commandLine) => {
                // commandLine 是完整的ffmpeg命令
                console.log(commandLine, '转码 开始');
            })
            .on('codecData', function (data) {
                console.log(data, '转码中......');
            })
            .on('progress', function (progress) {
                // console.log(progress,'转码进度')
            })
            .on('error', function (err, a, b) {
                console.log(url, '转码 错误: ', err.message);
                console.log('输入错误', a);
                console.log('输出错误', b);
            })
            .on('end', function () {
                console.log(url, '转码 结束!');
            })
            .addOutputOption(
                '-threads', '4',  // 一些降低延迟的配置参数
                '-tune', 'zerolatency',
                '-preset', 'ultrafast'
            )
            .outputFormat('flv') // 转换为flv格式
            .videoCodec('libx264') // ffmpeg无法直接将h265转换为flv的,故需要先将h265转换为h264,然后再转换为flv
            .withSize('50%') // 转换之后的视频分辨率原来的50%, 如果转换出来的视频仍然延迟高,可按照文档上面的描述,自行降低分辨率
            .noAudio() // 去除声音
            .pipe(stream);
    } catch (error) {
        console.log('抛出异常', error);
    }
}

createServer();

作者:huisiyu
链接:https://juejin.cn/post/7124188097617051685
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

参看链接:参考链接,点击跳转 

三、下载node依赖+电脑下载ffmpeg并配置系统环境

简介:

参考链接:参考链接,点击跳转 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/573520.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

手把手教会你做属于自己的网站《保姆级教程》

手把手教会你做属于自己的网站《保姆级教程》 前言开始教程特别说明下期内容预报 前言 什么是个人网站&#xff1f; 个人网站是指因特网上一块固定的面向全世界发布消息的地方&#xff0c;通常由域名&#xff08;也就是网站地址&#xff09;、程序和网站空间构成&#xff0c;并…

麒麟 Kylin V10 一键安装 Oracle 11GR2 单机 ASM(231017)

前言 Oracle 一键安装脚本&#xff0c;演示麒麟 Kylin V10 一键安装 Oracle 11GR2 单机 ASM&#xff08;231017&#xff09;过程&#xff08;全程无需人工干预&#xff09;&#xff1a;&#xff08;脚本包括 ORALCE PSU/OJVM 等补丁自动安装&#xff09; ⭐️ 脚本下载地址&a…

(八)小案例银行家应用程序-排序-数组排序

排序一直有很多的算法&#xff0c;今天我们仅仅来说JavaScript内置的排序方法 ● 字符串 const owners [Jonas, Zach, Adam, Martha]; console.log(owners.sort()); console.log(owners);但是注意&#xff0c;这个方法会改变原有的数组&#xff1b; ● 我们在试试数字 cons…

用java实现PDF的下载

1.下载PDF模版 2.导入依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>7.2.5</version><type>pom</type></dependency> 3.完整代码 package com.by.controller…

JAVASE8中基本数据类型

本篇文章基于有过一部分的C语言基础的&#xff0c;还望大家理解 在进入到学习之前我们必须要清楚的是在JAVASE中数据类型与C语言中的数据类型基本上是相同的,接下来我们先来对8中数据类型进行简要介绍&#xff0c;他们分别是&#xff1a; 如果大家之前了解过C语言那么对于基本数…

常见的工业路由器访问问题

A&#xff1a;工业路由器已经设置了pptp怎么访问路由下面的电脑 1. 确认PPTP VPN设置&#xff1a;首先&#xff0c;确保PPTP VPN服务器在工业路由器上已正确设置&#xff0c;并且处于活动状态。这包括确保VPN服务器的IP地址、端口、用户名和密码等设置正确无误。 2. 连接到VP…

Apple公司面试题之Apple-Orange

1. 引言 你幻想过在Apple公司工作吗&#xff1f; 如果心动过&#xff0c;那这个逻辑推理面试题就是给你准备的&#xff01;这是一道有趣的面试题&#xff0c;如下所示&#xff1a; 看到这里的同学&#xff0c;我建议你暂停文章&#xff0c;拿起笔和纸&#xff0c;试一试。准…

KBL410-ASEMI新能源专用整流桥KBL410

编辑&#xff1a;ll KBL410-ASEMI新能源专用整流桥KBL410 型号&#xff1a;KBL410 品牌&#xff1a;ASEMI 封装&#xff1a;KBL-4 最大重复峰值反向电压&#xff1a;1000V 最大正向平均整流电流(Vdss)&#xff1a;4A 功率(Pd)&#xff1a;小功率 芯片个数&#xff1a;4…

Linux实现文件共享

#nfs-utils、rpcbind 软件包来提供 NFS 共享服务 #客户端创建共享文件夹&#xff1a; nmcli c reload nmcli c up ens160 systemctl stop firewalld systemctl disable firewalld rpm -q nfs-utils rpcbind #查看是否安装 systemctl enable rpcbind systemctl enable nfs…

Skill Check: Fundamentals of Large Language Models

Skill Check: Fundamentals of Large Language Models 完结&#xff01;

CUDA的开发框架

CUDA的开发框架主要提供了一系列工具和库&#xff0c;使得开发者可以充分利用NVIDIA GPU进行高效的并行计算。以下是CUDA开发框架的一些关键组成部分。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.CUDA核心库&#xff1a;这些是构…

带你走进不一样的策略模式

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 带你走进不一样的策略模式 前言策略模式简介概念解释 策略模式的结构策略模式优点项目实践之bean策略构思业务策略实现策略接口实现策略上下文业务实现 前言 在编程的世界里&#xff0c;每一次按键都…

【办公类-26-02】20240423 UIBOT学分自动评价(自动登录、评价和退出,全自动)

背景需求&#xff1a; 我想用UIBOT自动模拟鼠标&#xff0c;登录每位老师的账户&#xff0c;进入评价区域&#xff0c;自动选择7次“满意”&#xff0c;输入1次“无”&#xff0c;然后提交。 C Dim objExcelWorkBook,arrayRet,iRet,temp,iPID,hWeb,dictRet,XobjExcelWorkBook …

《QT实用小工具·四十一》无边框窗口

1、概述 源码放在文章末尾 该项目实现了无边框窗口效果&#xff0c;项目demo如下所示&#xff1a; 项目代码如下所示&#xff1a; #include "framelesswindow.h" #include <QGuiApplication> #include <QScreen>#ifdef Q_OS_WIN #include <window…

24深圳杯数学建模挑战赛A题6页初步思路+参考论文+保姆级答疑!!!

问题1:单个残骸的精确位置定位 建立数学模型&#xff0c;分析如果要精准确定空中单个残骸发生音爆时的位置坐标&#xff08;经度、纬度、高程&#xff09;和时间&#xff0c;至少需要布置几台监测设备&#xff1f;假设某火箭一级残骸分离后&#xff0c;在落点附近布置了7台监测…

文件上传服务器、文件展示等异步问题

问题&#xff1a; 文件上传模块&#xff1a;当文件已经上传完成&#xff0c;文件进度已经走完了&#xff0c;但是服务器响应还没有返回结果&#xff0c;出现了&#xff0c;获取不到上传后的文件路径&#xff0c;需要等待服务器返回结果后&#xff0c;才能获取文件路径并点击跳…

Linux 基本指令(上)

目录 whoami 命令 pwd 命令 ls 命令 Linux的目录结构 cd 命令 文件操作 什么是文件 touch 命令 mkdir 命令 rmdir / rm 命令 rm 删除文件&#xff1a; rm 删除目录&#xff1a; whoami 命令 whoami &#xff1a;可以看出当前登录的用户名 pwd 命令 pwd 用于显示用户当…

前端发送请求,显示超时取消

前端发送请求&#xff0c;显示超时取消 问题说明&#xff1a;后台接口请求60s尚未完成&#xff0c;前端控制台显示取消&#xff08;canceled&#xff09; 原因 1、前端设置60s超时则取消 2、后台接口响应时间过长&#xff0c;过长的原因统计的数据量多&#xff08;实际也才17…

嵌入式linux学习之arm开发板移植ssh

1.下载源码 &#xff08;1&#xff09;zlib 下载网址&#xff1a;http://www.zlib.net/fossils/ 教程中版本选择的是: zlib-1.2.11.tar.gz &#xff08;2&#xff09;openssl下载网址&#xff1a;https://www.openssl.org/source/mirror.html 教程中版本选择的是: openssl-1.1…

【Qt】.ui文件转.h文件

1、打开qt命令行 2、转换 uic -o ui.h mainwindow.ui
最新文章