視頻文件自動轉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

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM