赞
踩
写这一篇目的是记录自己使用buildroot 构建根文件系统 实现摄像头推流到VLC 及 web端
1. buildroot构建根文件系统
2. ffmpeg 及nginx 的配置
3. Linux内核构建
4. 如何将摄像头的视频在web上面显示 (由于自己没找到教程,期间踩了很多坑,最后成功在web上面显示)
1. 正点原子驱动开发指南
2. 百问网韦东山-【物联网实战项目】手把手教你如何从0搭建智慧家居中的视频监控系统
1. imx6ull开发板,我用的正点原子的
2. usb摄像头
参考:正点原子-buildroot构建根文件系统
解压完成buildroot之后
由于buildroot和uboot、linux kernel一样支持图形化配置
输入 make menuconfig
此配置项用于配置交叉编译工具链,也就是交叉编译器,这里设置为我们自己所使用的交
叉编译器即可。 buildroot 其实是可以自动下载交叉编译器的,但是都是从国外服务器下载的,
鉴于国内的网络环境,强烈推荐大家设置成自己所使用的交叉编译器
此选项用于设置一些系统配置,比如开发板名字、欢迎语、用户名、密码等。需要配置的
项目和其对应的内容如下
此选项配置我们最终制作的根文件系统为什么格式的
buildroot 不仅仅能构建根文件系统,也可以编译 linux 内核和 uboot。当配置 buildroot,使
能 linux 内核和 uboot 以后 buildroot 就会自动下载最新的 linux 内核和 uboot 源码并编译。但是
我们一般都不会使用 buildroot 下载的 linux 内核和 uboot,因为 buildroot 下载的 linux 和 uboot
官方源码,里面会缺少很多驱动文件,而且最新的 linux 内核和 uboot 会对编译器版本号有要
求,可能导致编译失败。因此我们需要配置 buildroot,关闭 linux 内核和 uboot 的编译,只使用
buildroot 来构建根文件系统
此选项用于配置要选择的第三方库或软件
Target packages > Audio and video applications > ffmpeg
Target packages > Networking applications > nginx
由于nginx本身是没有rtmp功能的,是依靠第三方模块支持的,所以需要将模块一同编译进nginx。
需要用到nginx-rtmp-modules
需要用到http-flv
,推荐使用nginx-http-flv-module
,他比nginx-rtmp-modules
更强大,支持web推流
先勾选nginx所有的选项
将下载下来的nginx-rtmp-modules
放到 buildroot/dl/nginx
目录下,一般要自己创建。
然后在menuconfig下配置nginx的addtional modules
添加nginx-rtmp-modules
的地址
需要使用http-flv
的话,将库换成下面这个:
注意:我用的是nginx-http-flv-module
1.2.7
版本 可以支持http推流 操作和上面是一样的
因为正点原子的内核源码默认没有开启,UVC设备类驱动,需要自己配置并编译
打开正点原子的内核代码 或者 自己移植的nxp的内核代码
输入 make menuconfig
勾选如下选项
Device Drivers -->
USB support -->
Support for Host-side USB -->
USB announce new devices
Multimedia support -->
Cameras/video grabbers support
Media Controller API
V4L2 sub-device usersapce API
Media USB Adapters -->
USB Video Class (UVC) -->
UVC input events device support
V4L platform devices -->
soC camera support
platform camera support
完成之后make一下
新的镜像文件在 arch/arm/boot /下
copy到开发板进行测试
系统以及文件系统移植完毕之后
在etc/nginx/
下的nginx.conf
文件里面添加如下
将 worker_processes 改为 auto 添加: rtmp { server { listen 1935; # 监听 1935 端口 chunk_size 4096; application live{ allow publish 127.0.0.1; allow play all; live on; # 打开直播 record off; # 关闭 record meta copy; } } } 在http目录下添加 location /test { flv_live on; chunked_transfer_encoding on; add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; } 修改http目录下的html文件目录 location / { root /var/www/html/; 目录要从根目录写起 index index.html; }
配置完之后需要重启nginx : /etc/init.d/S50nginx restart
index.html
我是放在/var/www/html/
目录下 默认目录是/usr/html/
这个根据你自己的想法
参考博客: https://blog.csdn.net/igocsdn/article/details/118753920
<!DOCTYPE html> <html> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <title>flv.js demo</title> <style> .mainContainer { display: block; width: 1024px; margin-left: auto; margin-right: auto; } .urlInput { display: block; width: 100%; margin-left: auto; margin-right: auto; margin-top: 8px; margin-bottom: 8px; } .centeredVideo { display: block; width: 100%; height: 576px; margin-left: auto; margin-right: auto; margin-bottom: auto; } .controls { display: block; width: 100%; text-align: left; margin-left: auto; margin-right: auto; } </style> </head> <body> <div class="mainContainer"> <video id="videoElement" class="centeredVideo" controls autoplay width="1024" height="576" muted>Your browser is too old which doesn't support HTML5 video.</video> </div> <br> <div class="controls"> <!--<button οnclick="flv_load()">加载</button>--> <button onclick="flv_start()">开始</button> <button onclick="flv_pause()">暂停</button> <button onclick="flv_destroy()">停止</button> <input style="width:100px" type="text" name="seekpoint" /> <button onclick="flv_seekto()">跳转</button> </div> <script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.5.0/flv.min.js"></script> <script> var player = document.getElementById('videoElement'); if (flvjs.isSupported()) { var flvPlayer = flvjs.createPlayer({ type: 'flv', url: 'http://192.168.31.98/test?app=live&stream=os', "isLive": true, hasAudio: false, hasVideo: true, //withCredentials: false, //cors: true }, { enableWorker: true, // 开启多线程 enableStashBuffer: false, lazyLoad: false, lazyLoadMaxDuration: 0, lazyLoadRecoverDuration: 0, deferLoadAfterSourceOpen: false, fixAudioTimestampGap: true, autoCleanupSourceBuffer: true, }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); //加载 flv_start(); } function flv_start() { player.play(); } function flv_pause() { player.pause(); } function flv_destroy() { player.pause(); player.unload(); player.detachMediaElement(); player.destroy(); player = null; } function flv_seekto() { player.currentTime = parseFloat(document.getElementsByName('seekpoint')[0].value); } </script> </body> </html>
nginx-rtmp-module
这个库是不支持http的,推流VLC没有问题 ,但是不能推流http-flv,
为了推流web 换了nginx-http-flv-module
库,但是报以下错误
遇到 Input/output error
:期间也困扰了一下,最后发现是版本问题 ,换了低版本就行了
实测nginx-http-flv-module 1.2.7
可以用
然后我想推流到web端,还需要用到x264这个库,默认ffmpeg是没有使能的,需要我们自己添加
添加x264库
先安装好x264库,可以参考 x264的交叉编译和移植
我是安装在/home/os/tools/libx264/
下面
然后进入buildroot 配置界面 在make menuconfig
下 ffmpeg
里面最后一个选项输入如下
--enable-libx264 --extra-cflags=-I/home/os/tools/libx264/include --extra-ldflags=-L/home/os/tools/libx264/lib
注意:先要删除之前生成的 ffmpeg 目录(也就是 output/build
目录下的ffmpeg
),才会重新生成
经过测试还需要将安装好的x264目录下的lib
目录拷贝到开发板/usr/lib
目录下
2.3.2 踩过的坑
root /var/www/html/;
目录要从根目录写起 目录没写对
推流摄像头
推流
ffmpeg -vsync 1 -use_wallclock_as_timestamps 1 -i /dev/video1 -vf 'format=pix_fmts=yuv420p,scale=320:200' -c:v libx264 -preset ultrafast -tune zerolatency -f flv rtmp://127.0.0.1/live/os
-vsync 1: 设置垂直同步为 1,确保输出帧与输入帧的同步。(能解决推流一段时间报时间戳的问题)解决了之前遗留问题。
-vf 'format=pix_fmts=yuv420p': 使用视频滤镜来设置输出视频的像素格式为 YUV420P。这是一种普遍支持的像素格式,适用于大多数流媒体服务器。
-c:v libx264: 指定视频编码器为 libx264,这是一个高效的 H.264 编码器。
-use_wallclock_as_timestamps 1:使用系统时钟作为时间戳,确保输出流的时间戳与实际时间同步。
scale=320:200:将视频的分辨率缩放为 320x200 像素,imx6ull性能有限,为了保证输出画面同步(实时性)因此需要降低画面质量。
-preset ultrafast: 设置编码速度为 ultrafast,这意味着编码速度非常快,但可能会牺牲一些编码效率。
-tune zerolatency: 使用 zerolatency 优化参数,以减少编码延迟,使得实时推流更加实时响应。
-f flv: 指定输出格式为 FLV(Flash 视频)。这是一种常用的流媒体格式,适用于许多流媒体服务器。
也可以用下面命令推流 但是好像web端是显示不了的 原因应该是没有指定编码器
ffmpeg -f v4l2 -framerate 10 -i /dev/video1 -q 10 -f flv rtmp://127.0.0.1/live/os
需要声音的话,可以开启index.html
里面的声音(hasAudio
)选项,开启声音选项,但是推流摄像头会受到影响,因此推流摄像头需要将声音选项去掉
ffmpeg -re -i lx.mp4 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1/live/os
-re: 指定以实时速度(real-time)读取输入文件。这将使 FFmpeg 按照视频的原始帧速率进行处理,而不是尽可能快地处理。
-vcodec copy: 使用 -vcodec 参数指定视频编码器为 "copy",表示直接复制原始视频流而不进行重新编码。这样可以保持原始视频流的编码格式、质量和参数不变。
-acodec copy: 使用 -acodec 参数指定音频编码器为 "copy",表示直接复制原始音频流而不进行重新编码。这样可以保持原始音频流的编码格式、质量和参数不变。
软件:花生壳,其他的类似软件也行,我看了一下基本上都有免费套餐。
内网穿透----自定义映射:配置内网主机和内网端口
添加好之后,打开VLC,输入下面链接
https://你的外网域名/test?app=live&stream=os
至此,我们可以实现在外网访问,手机端VLC也是一样。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。