写在前面:
之前使用过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 () {// 页面销毁前 关闭flvjsthis.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 的urlisNeedControl?: 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并配置系统环境
简介:
参考链接:参考链接,点击跳转