FFmpeg进行笔记本摄像头+麦克风实现流媒体直播服务,展示在浏览器上。

news/2024/12/22 17:34:43/

0、本文中所用软件下载包

1、前置工作

        1.1 下载 ffmpeg,Download FFmpeg,

                1.1.1配置ffmpeg如下图

                1.1.2测试ffmpeg 安装成功:ffmpeg -version

        1.1.3 使用FFmpeg获取本地摄像头设备

ffmpeg -list_devices true -f dshow -i dummy

                     video和audio地址在1.1.4会用到

        1.1.4使用FFmpeg推送RTSP视频流

ffmpeg -f dshow -i video="Integrated Webcam":audio="麦克风 (Realtek(R) Audio)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -rtsp_transport tcp -f rtsp rtsp://127.0.0.1/test

        1.2下载easydarwin:Releases · EasyDarwin/EasyDarwin,运行EasyDarwin.exe,

 下载解压到本地后运行 EasyDarwin.exe 程序,点击运行后会弹出一个 cmd 命令,注:不要关闭弹出的命令框;在浏览器中输入 http://127.0.0.1:10008 查看是否有显示有个 web 页面,如果显示则证明打开成功。

2、node服务搭建

package.json  依赖项

{"name": "ssss","version": "1.0.0","description": "","type": "module","main": "index.js","scripts": {"start": "nodemon --exec babel-node index.js","test": "echo \"Error: no test specified\" && exit 1"},"author": "","license": "ISC","devDependencies": {"@babel/cli": "^7.20.7","@babel/core": "^7.20.12","@babel/node": "^7.20.7","@babel/preset-env": "^7.20.2","@ffmpeg-installer/ffmpeg": "^1.1.0","fluent-ffmpeg": "^2.1.2","nodemon": "^2.0.20","websocket-stream": "^5.5.2","ws": "^8.12.0"}
}

index.js  websocket服务器+ffmpeg转码

import { WebSocketServer } from 'ws'
import webSocketStream from 'websocket-stream/stream.js'
import ffmpeg from 'fluent-ffmpeg'
import ffmpegInstaller from '@ffmpeg-installer/ffmpeg'
// 建立WebSocket服务
const wss = new WebSocketServer({ port: 8888, perMessageDeflate: false })
ffmpeg.setFfmpegPath(ffmpegInstaller.path);
// 监听连接
wss.on('connection', handleConnection)// 连接时触发事件
function handleConnection(ws, req) {// 获取前端请求的流地址(前端websocket连接时后面带上流地址)const url = req.url.slice(1)console.log(url)// 传入连接的ws客户端 实例化一个流const stream = webSocketStream(ws, { binary: true })// 通过ffmpeg命令 对实时流进行格式转换 输出flv格式const ffmpegCommand = ffmpeg(url).addInputOption("-rtsp_transport", "tcp", "-buffer_size", "102400", '-analyzeduration', '10000', '-max_delay', '1000').on('start', function () { console.log('Stream started.') }).on('codecData', function () { console.log('Stream codecData.') }).on('error', function (err) {console.log('An error occured: ', err.message)stream.end()}).on('end', function () {console.log('Stream end!')stream.end()}).outputFormat('flv').videoCodec('copy')//.noAudio()stream.on('close', function () {ffmpegCommand.kill('SIGKILL')})try {// 执行命令 传输到实例流中返回给客户端ffmpegCommand.pipe(stream)} catch (error) {console.log(error)}
}

3.前端vue框架,使用flv.js获取视频数据并渲染

package.json  依赖项

{"name": "a","version": "0.1.0","private": true,"scripts": {"serve": "vue-cli-service serve","build": "vue-cli-service build","lint": "vue-cli-service lint"},"dependencies": {"core-js": "^3.8.3","flv.js": "^1.6.2","vue": "^3.2.13"},"devDependencies": {"@babel/core": "^7.12.16","@babel/eslint-parser": "^7.12.16","@vue/cli-plugin-babel": "~5.0.0","@vue/cli-plugin-eslint": "~5.0.0","@vue/cli-service": "~5.0.0","eslint": "^7.32.0","eslint-plugin-vue": "^8.0.3"},"eslintConfig": {"root": true,"env": {"node": true},"extends": ["plugin:vue/vue3-essential","eslint:recommended"],"parserOptions": {"parser": "@babel/eslint-parser"},"rules": {}},"browserslist": ["> 1%","last 2 versions","not dead","not ie 11"]
}

vue.config.js 配置端口

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer: { port: 8787 }
})

 app.vue 通过flv.js将视频流展示到页面

<template><div class="wrap"><div @click="sound">点击播放</div><video class="video" volume="0.5" controls ref="player"></video></div>
</template><script>
import flvjs from 'flv.js' // 引入flvjs
export default {data() {return {player: null}},mounted() {},beforeUnmount() {// 页面销毁前 关闭flvjsthis.player.destroy()},methods: {sound() {// 如果浏览器支持flvjs,则执行相应的程序if (flvjs.isSupported()) {this.player = null;// 准备监控设备流地址const url = 'rtsp://192.168.31.160/test'//ffmpeg -f dshow -i video="Integrated Webcam":audio="麦克风 (Realtek(R) Audio)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -rtsp_transport tcp -f rtsp rtsp://127.0.0.1/test// 创建一个flvjs实例// 下面的ws://localhost:8888换成你搭建的websocket服务地址,后面加上设备流地址this.player = flvjs.createPlayer({type: 'flv',isLive: true,hasVideo: true,url: 'ws://192.168.31.160:8888/' + url})this.player.on('error', () => {//报错重置player,不重置卡着不动。this.player.unload()this.player.destroy()this.player = null;this.sound()})// 将实例挂载到video元素上面this.player.attachMediaElement(this.$refs.player)try {// 开始运行加载 只要流地址正常 就可以在h5页面中播放出画面了this.player.load()this.player.play()} catch (error) {console.log(error)}}}}
}
</script><style  scoped>
.wrap .video {width: 300px;height: 300px;
}
</style>

4.页面效果,此图是摄像头拍摄的实时画面,带麦克风声音

本文章参考以下网址:

Windows笔记本本地摄像头提供Rtsp视频流服务

FFmpeg进行笔记本摄像头+麦克风实现流媒体直播服务
html5中播放rtsp流实现监控、直播等方案


http://www.ppmy.cn/news/11700.html

相关文章

STM32 按键模块化

文章目录前言一、按键的原理图二、按键的GPIO配置总结前言 本篇文章将继续带大家学习模块化编程&#xff0c;今天主要给大家讲解按键的模块化。 一、按键的原理图 我们可以看到按键分别接到了板子的PE3和PE4引脚。 按键的具体原理这里我就不多讲了&#xff0c;大家可以看我之…

开源飞控初探(二):无人机技术栈

自动驾驶无人机的自动驾驶AutoPilot可从三个场景来理解&#xff1a;指定目的地后让它自己飞过去&#xff0c;且可以指定途经点&#xff0c;整个流程即执行航线规划。这些点是三维的&#xff0c;即经纬度海拔高度。在水平面方向飞行时保持高度让它悬停第一个场景相对好理解&…

LeetCode 1807. 替换字符串中的括号内容

【LetMeFly】1807.替换字符串中的括号内容 力扣题目链接&#xff1a;https://leetcode.cn/problems/evaluate-the-bracket-pairs-of-a-string/ 给你一个字符串 s &#xff0c;它包含一些括号对&#xff0c;每个括号中包含一个 非空 的键。 比方说&#xff0c;字符串 "(…

成功解决VMware安装操作系统出现分辨率的问题

文章目录问题重现问题原因问题解决方法一&#xff1a;拓展&#xff1a;1. 电脑分辨率&#xff1a;2. xrandr命令3. 查询后如果没有合适的分辨率解决方案参考资料问题重现 如下图&#xff1a; 在VMware16上安装ubuntu操作系统的时候&#xff0c;出现分辨率问题&#xff0c; 导致…

NTN(三) Timing

微信同步更新欢迎关注同名modem协议笔记。这篇看下k_offset和k_mac&#xff0c;如38.300所述&#xff0c;k_offset是配置的调度偏移量&#xff0c;需要大于或等于service link RTT和Common TA之和&#xff1b;k_mac 是配置的偏移量&#xff0c;需要大于或等于 RP 和 gNB 之间的…

【数据结构】—— Java实现队列和循环队列

队列与循环队列一、队列1.概念2.队列的使用3.队列的模拟实现二、循环队列1.基本概念2.代码实现一、队列 1.概念 队列&#xff1a;是允许在一端进行插入操作&#xff0c;而在另一端进行删除操作的线性表。 队列是一种先进先出的&#xff08;First In First Out&#xff09;的…

TCP/IP常见的一些调优措施

文章目录前言TCP/IP连接建立状态解释调优tcp_synack_retries &#xff1a;INTEGERtcp_keepalive_time &#xff1a;INTEGERtcp_keepalive_probes&#xff1a;INTEGERtcp_keepalive_intvl&#xff1a;INTEGERtcp_retries1 &#xff1a;INTEGERtcp_retries2 &#xff1a;INTEGERt…

【YOLOv7/YOLOv5系列改进NO.52】融入YOLOv8中的C2f模块

文章目录 前言一、解决问题二、基本原理三、​YOLOv5添加方法四、​YOLOv7添加方法五、总结前言 作为当前先进的深度学习目标检测算法YOLOv7,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列文章,将重点…