视频文件自动转rtsp流
最近碰到一个项目需要用到 rtsp 视频流做测试, 由于真实环境的 摄像头 并不能满足需求,故尝试了一下用本地视频文件转换成rtsp视频流做测试,记录一下~
采用方案: Docker + EasyDarwin + FFmpeg
准备工作:
1. 创建一个文件夹 easydarwin
2. cd easydarwin
3. wget https://github.com/EasyDarwin/EasyDarwin/releases/download/v8.1.0/EasyDarwin-linux-8.1.0-1901141151.tar.gz (下载EasyDarwin 软件包)
4. 创建: Dockerfile
5. 将easydarwin 的配置文件 也放到此目录下: easydarwin.xml
6. 创建一个自动转换 /root/video 目录下的视频文件成rtsp 流的 shell 脚本: start.sh
编写Dockerfile:
FROM centos:latest USER root COPY ./EasyDarwin-linux-8.1.0-1901141151.tar.gz /EasyDarwin-linux-8.1.0-1901141151.tar.gz COPY ./start.sh /start.sh RUN mkdir -p /etc/streaming/ COPY ./easydarwin.xml /etc/streaming/easydarwin.xml RUN yum -y install autoconf automake bzip2 bzip2-devel cmake freetype-devel gcc gcc-c++ git libtool make mercurial pkgconfig zlib-devel tar wget && yum -y clean all RUN gzip -d /EasyDarwin-linux-8.1.0-1901141151.tar.gz \ && tar -xf /EasyDarwin-linux-8.1.0-1901141151.tar \ && mv EasyDarwin-linux-8.1.0-1901141151 EasyDarwin \ && cd / RUN mkdir /ffmpeg-4.1.5 # install nasm RUN cd /ffmpeg-4.1.5 \ && curl -O -L https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.bz2 \ && tar xjvf nasm-2.14.02.tar.bz2 \ && cd nasm-2.14.02 \ && ./autogen.sh \ && ./configure --prefix="/ffmpeg-4.1.5/ffmpeg_build" --bindir="/ffmpeg-4.1.5/bin" \ && make \ && make install ENV PATH="/ffmpeg-4.1.5/bin:$PATH" # install yasm RUN cd /ffmpeg-4.1.5 \ && curl -O -L https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz \ && tar xzvf yasm-1.3.0.tar.gz \ && cd yasm-1.3.0 \ && ./configure --prefix="/ffmpeg-4.1.5/ffmpeg_build" --bindir="/ffmpeg-4.1.5/bin" \ && make \ && make install # install lib264 RUN cd /ffmpeg-4.1.5 \ && git clone --depth 1 https://code.videolan.org/videolan/x264.git \ && cd x264 \ && PKG_CONFIG_PATH="/ffmpeg-4.1.5/ffmpeg_build/lib/pkgconfig" ./configure --prefix="/ffmpeg-4.1.5/ffmpeg_build" --bindir="/ffmpeg-4.1.5/bin" --enable-static \ && make \ && make install # install lib265 RUN cd /ffmpeg-4.1.5 \ && git clone https://bitbucket.org/multicoreware/x265_git.git \ && mv x265_git x265 \ && cd x265/build/linux \ && cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="/ffmpeg-4.1.5/ffmpeg_build" -DENABLE_SHARED:bool=off ../../source \ && make \ && make install #install ffmpeg RUN cd /ffmpeg-4.1.5 \ && curl -O -L https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 \ && tar xjvf ffmpeg-snapshot.tar.bz2 \ && cd ffmpeg \ && PKG_CONFIG_PATH="/ffmpeg-4.1.5/ffmpeg_build/lib/pkgconfig" ./configure --prefix="/ffmpeg-4.1.5/ffmpeg_build" --pkg-config-flags="--static" --extra-cflags="-I/ffmpeg-4.1.5/ffmpeg_build/include" --extra-ldflags="-L/ffmpeg-4.1.5/ffmpeg_build/lib" --extra-libs=-lpthread --extra-libs=-lm --bindir="/ffmpeg-4.1.5/bin" --enable-gpl --enable-libfreetype --enable-libx264 --enable-libx265 --enable-nonfree \ && make \ && make install ENTRYPOINT /start.sh
编写start.sh
#!/bin/sh cnt=`ps -ef | grep "[e]asydarwin" | wc -l` if [ $cnt -lt 1 ];then nohup /EasyDarwin/easydarwin & fi if [[ ! -d /video ]];then mkdir -p /video fi while true;do for video in `ls /video`; do if [[ "$(ps -ef | grep "$video" | grep -v "grep" | wc -l | tr -d ' ' )" = "1" ]]; then echo "Safe $video" else short_name=`echo $video | cut -d '.' -f 1` if [[ $video == *"SRC"* ]];then nohup /ffmpeg-bin/ffmpeg/ffmpeg -re -stream_loop -1 -i /video/$video -vcodec copy -preset ultrafast -tune zerolatency -rtsp_transport tcp -f rtsp rtsp://localhost/$short_name & elif [[ $video == *"265"* ]];then nohup /ffmpeg-bin/ffmpeg/ffmpeg -re -stream_loop -1 -i /video/$video -vcodec libx265 -preset ultrafast -tune zerolatency -rtsp_transport tcp -f rtsp rtsp://localhost/$short_name & else nohup /ffmpeg-bin/ffmpeg/ffmpeg -re -stream_loop -1 -i /video/$video -vcodec libx264 -preset ultrafast -tune zerolatency -rtsp_transport tcp -f rtsp rtsp://localhost/$short_name & fi echo "Started $video" fi done ps -ef | grep "[f]fmpeg"| grep -v 'auto ffmpeg' | awk -F ' ' '{print $2 " " $NF}' > exist.txt cat exist.txt | while read line;do pid=`echo $line | cut -d ' ' -f 1` video_name=`echo $line | cut -d ' ' -f 2 | rev | cut -d '/' -f 1 | rev` cnt=`ls /video | grep "^$video_name\." | wc -l ` if [ $cnt -lt 1 ];then kill -9 $pid echo "kill process $pid, $video_name" fi done sleep 1m done
用途说明:
Dockerfile将我们需要的环境准备好,包括安装编译安装EasyDarwin以及需要的依赖包, FFmpeg等, 最后运行 start.sh. 注意 Docker中 ENTRYPOINT 和 CMD 命令的用法区别。
start.sh 用来启动EasyEarwin,并每隔1分钟查看 /root/video 目录下的视频文件,如果有新文件,就会自动使用ffmpeg 转为rtsp流, 地址为 rtsp://localhost/short_name, 其中localhost使用时改成服务器的IP地址,short_name 为 当前食品文件的文件名(去掉扩展名, 如: video.mp4 的 short_name 为 video)
最后打包镜像,然后运行container, 可以在 easydarwin 目录的同级别创建 启动脚本: easydarwin.sh
#!/bin/bash easy=`ls ./easydarwin/*.gz | wc -l` if [[ $easy -lt 1 ]];then wget https://github.com/EasyDarwin/EasyDarwin/releases/download/v8.1.0/EasyDarwin-linux-8.1.0-1901141151.tar.gz mv EasyDarwin-linux-8.1.0-1901141151.tar.gz ./easydarwin fi local_img=`docker images | grep "[e]asydarwin" | wc -l` if [ $local_img -lt 1 ];then cd easydarwin docker build -t easydarwin_qa . --no-cache cd .. fi #挂载host 的 /root/video 到 container 的对应路径 docker run -dit --net host --restart=always --name easy_qa -v /root/video:/video easydarwin_qa
所以只需在装了docker的服务器上启动此shell就可以: bash easydarwin.sh
/root/video下面的视频文件 如果名字包含265则会转为libx265 编码,否则为264编码
上述方法是 编译源代码生成ffmpeg, 下面是另一种方法
------------使用现有的ffmpeg镜像生成:
Dockerfile:
FROM jrottenberg/ffmpeg:4.1-centos USER root ENV ff_args "" COPY ./EasyDarwin-linux-8.1.0-1901141151.tar.gz /EasyDarwin-linux-8.1.0-1901141151.tar.gz COPY ./start.sh /start.sh RUN mkdir -p /etc/streaming/ COPY ./easydarwin.xml /etc/streaming/easydarwin.xml RUN yum -y install tar && yum -y clean all RUN gzip -d /EasyDarwin-linux-8.1.0-1901141151.tar.gz \ && tar -xf /EasyDarwin-linux-8.1.0-1901141151.tar \ && mv EasyDarwin-linux-8.1.0-1901141151 EasyDarwin \ && cd / ENTRYPOINT ["/bin/bash","-c","/start.sh \"${ff_args}\" "]
start.sh
#!/bin/sh ff_args=$1 cnt=`ps -ef | grep "[e]asydarwin" | wc -l` if [ $cnt -lt 1 ];then nohup /EasyDarwin/easydarwin & fi if [[ ! -d /video ]];then mkdir -p /video fi while true;do for video in `ls /video`; do if [[ "$(ps -ef | grep "$video" | grep -v "grep" | wc -l | tr -d ' ' )" = "1" ]]; then echo "Safe $video" else short_name=`echo $video | cut -d '.' -f 1` if [[ $video == *"SRC"* ]];then nohup ffmpeg -re -stream_loop -1 -i /video/$video -vcodec copy ${ff_args} -rtsp_transport tcp -f rtsp rtsp://localhost/$short_name & echo "ffmpeg -re -stream_loop -1 -i /video/$video -vcodec copy ${ff_args} -rtsp_transport tcp -f rtsp rtsp://localhost/$short_name" elif [[ $video == *"265"* ]];then nohup ffmpeg -re -stream_loop -1 -i /video/$video -vcodec libx265 ${ff_args} -rtsp_transport tcp -f rtsp rtsp://localhost/$short_name & echo "ffmpeg -re -stream_loop -1 -i /video/$video -vcodec libx265 ${ff_args} -rtsp_transport tcp -f rtsp rtsp://localhost/$short_name" else nohup ffmpeg -re -stream_loop -1 -i /video/$video -vcodec libx264 ${ff_args} -rtsp_transport tcp -f rtsp rtsp://localhost/$short_name & echo "ffmpeg -re -stream_loop -1 -i /video/$video -vcodec libx264 ${ff_args} -rtsp_transport tcp -f rtsp rtsp://localhost/$short_name" fi echo "Started $video" fi done ps -ef | grep "[f]fmpeg"| grep -v 'auto ffmpeg' | awk -F ' ' '{print $2 " " $NF}' > exist.txt cat exist.txt | while read line;do pid=`echo $line | cut -d ' ' -f 1` video_name=`echo $line | cut -d ' ' -f 2 | rev | cut -d '/' -f 1 | rev` cnt=`ls /video | grep "^$video_name\." | wc -l ` if [ $cnt -lt 1 ];then kill -9 $pid echo "kill process $pid, $video_name" fi done sleep 1m done
最后打包镜像,然后运行container, 可以在 easydarwin 目录的同级别创建 启动脚本: easydarwin.sh
#!/bin/bash easy=`ls ./easydarwin/*.gz | wc -l` if [[ $easy -lt 1 ]];then wget https://github.com/EasyDarwin/EasyDarwin/releases/download/v8.1.0/EasyDarwin-linux-8.1.0-1901141151.tar.gz mv EasyDarwin-linux-8.1.0-1901141151.tar.gz ./easydarwin fi local_img=`docker images | grep "[e]asydarwin" | wc -l` if [ $local_img -lt 1 ];then cd easydarwin docker build -t easydarwin_qa . --no-cache cd .. fi # no performance tunning #docker run -dit --net host --restart=always --name easy_qa -v /root/video:/video easydarwin_qa docker run -dit --net host --restart=always --name easy_qa -v /root/video:/video -e ff_args="-preset ultrafast -an" easydarwin_qa