使用树莓派与 Gstreamer 做视频流直播

写在前面的无聊废话

地上捡了个树莓派 闲来无聊打算做个监控直播设备玩玩,想到之前 @当风过时 用香橙(???)派,直播过蚂蚁,就跑去取经,了解到了一个叫 mjpg-streamer 的东东,试试是发现它是一帧一帧的图片(真的⑥

但我想玩串流 : (

Google了一下...

准备

硬件

  1. 树莓派 (我用的是 raspberry pi 3 model b )
  2. 摄像头
  3. 电脑

软件

  1. Vim 编辑器

    sudo apt-get install vim
  2. 编译 Nginx 时需要用到的软件包

    sudo apt-get install -y curl build-essential libpcre3 libpcre3-dev libpcre++-dev zlib1g-dev libcurl4-openssl-dev libssl-dev

产生视频流

因为 apt 指令安装的 Nginx 不包含我们所需要的 nginx-http-flv-module 模块,所以我们要下载源码自行编译。

简要介绍一下 nginx-http-flv-module

网上多数文章都是使用 nginx-rtmp-module 来实现的流媒体服务器,但 nginx-rtmp-module 已经有一段时间没有更新了。

nginx-http-flv-module 是国人开发的基于 nginx-rtmp-module 的流媒体服务器,并提供了 HTTP-FLV 。

功能

  • nginx-rtmp-module 提供的所有功能。
  • nginx-http-flv-module 的其他功能与 nginx-rtmp-module 的对比:
功能nginx-http-flv-modulenginx-rtmp-module备注
HTTP-FLV (播放)x支持HTTPS-FLV和chunked回复
GOP缓存x仅适用于H.264视频和AAC音频
虚拟主机x
省略listen配置x
JSON风格的statx

支持的系统

  • Linux(推荐)/FreeBSD/MacOS/Windows(受限)。

支持的播放器

更多内容请访问 nginx-http-flv-module|Github

安装 Nginx 和 nginx-http-flv-module

下载并编译

# 创建一个放源码的文件夹并进入
mkdir ~/src
cd ~/src
# 下载 nginx 源码并解压
wget https://github.com/arut/nginx-rtmp-module/archive/master.zip
tar -zxvf nginx-1.11.8.tar.gz
# 下载 nginx-http-flv-module 并解压
wget https://github.com/winshining/nginx-http-flv-module/archive/v1.2.4.zip
unzip v1.2.4.zip

cd nginx-1.11.8
# 编译安装
./configure --add-module=../nginx-http-flv-module-1.2.4
make
sudo make install

安装结束后输入

sudo /usr/local/nginx/sbin/nginx -v

没问题的话会显示 Nginx 的版本号。

配置

先创建一个目录

sudo mkdir /var/www

打开配置文件

sudo vim /usr/local/nginx/conf/nginx.conf

删掉原有的内容,粘贴如下配置:

worker_processes  4; #should be 1 for Windows, for it doesn't support Unix domain socket
#worker_processes  auto; #from versions 1.3.8 and 1.2.5

worker_cpu_affinity  0001 0010 0100 1000; #only available on FreeBSD and Linux
#worker_cpu_affinity  auto; #from version 1.9.10

error_log logs/error.log error;

#if the module is compiled as a dynamic module and features relevant
#to RTMP are needed, the command below MUST be specified and MUST be
#located before events directive, otherwise the module won't be loaded
#or will be loaded unsuccessfully when NGINX is started
#load_module modules/ngx_rtmp_module.so;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    keepalive_timeout  65;

    server {
        listen       80;

        location / {
            root   /var/www;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location /live {
            flv_live on; #open flv live streaming (subscribe)
            chunked_transfer_encoding  on; #open 'Transfer-Encoding: chunked' response

            add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header
            add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header
        }

        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }

            root /tmp;
            add_header 'Cache-Control' 'no-cache';
        }

        location /dash {
            root /tmp;
            add_header 'Cache-Control' 'no-cache';
        }

        location /stat {
            #configuration of push & pull status

            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root /var/www/rtmp; #specify in where stat.xsl located
        }

        #if JSON style stat needed, no need to specify
        #stat.xsl but a new directive rtmp_stat_format

        #location /stat {
        #    rtmp_stat all;
        #    rtmp_stat_format json;
        #}

        location /control {
            rtmp_control all; #configuration of control module of rtmp
        }
    }
}

rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;

rtmp {
    out_queue   4096;
    out_cork    8;
    max_streams 64;

    server {
        listen 1935;

        application live {
            live on;
            gop_cache on; #open GOP cache for reducing the wating time for the first picture of video
        }

        application hls {
            live on;
            hls on;
            hls_path /tmp/hls;
        }

        application dash {
            live on;
            dash on;
            dash_path /tmp/dash;
        }
    }

}

详细配置项请参看 nginx-http-flv-module|Github

安装 Gstreamer

sudo apt-get install gstreamer1.0-tools

启用摄像头

在设置中启用

sudo raspi-config

1532705757799

打开系统模块文件

sudo vim /etc/modules

在该文件最后追加一行

bcm2835-v4l2

保存后,重启树莓派

重启后输入以下指令测试摄像头是否正常

vcgencmd get_camera

如果返回

supported=1 detected=1

则说明摄像头正常工作

产生串流

启动 Nginx

sudo /usr/local/nginx/sbin/nginx

终端输入

gst-launch-1.0 -v v4l2src ! 'video/x-raw, width=640, height=480, framerate=30/1' ! queue ! video convert ! omxh264enc ! h264parse ! flvmux ! rtmpsink location='rtmp://树莓派的IP/live/live'

如果没报错,串流就产生了:

RTMP: rtmp://你的树莓派IP/live/live
HTTP-FLV: http://你的树莓派IP/live?app=live&stream=live
如果报错了
GstRTMPSink:rtmpsink0: Could not open resource for writing.

说明你的 Nginx 没有启动...

创建网页播放视频

我们使用 Strobe Media Playback 来播放视频

安装 Strobe Media Playback

mkdir -p ~/strobe_src
cd ~/strobe_src
wget http://downloads.sourceforge.net/project/smp.adobe/Strobe%20Media%20Playback%201.6%20Release%20%28source%20and%20binaries%29/StrobeMediaPlayback_1.6.328-full.zip
unzip StrobeMediaPlayback_1.6.328-full.zip
sudo cp -r for\ Flash\ Player\ 10.1 /var/www/strobe

写网页

sudo vim /var/www/index.html

复制粘贴下面的内容即可(记得改 IP )

<!DOCTYPE html>
<html>
<head>
<title>Live Streaming</title>
 
<!-- strobe -->
<script type="text/javascript" src="strobe/lib/swfobject.js"></script>
<script type="text/javascript">
  var parameters = {  
     src: "rtmp://树莓派的IP/live/live",  
     autoPlay: false,  
     controlBarAutoHide: false,  
     playButtonOverlay: true,  
     showVideoInfoOverlayOnStartUp: true,  
     optimizeBuffering : false,  
     initialBufferTime : 0.1,  
     expandedBufferTime : 0.1,  
     minContinuousPlayback : 0.1,  
     poster: "images/poster.png"  
  };  
  swfobject.embedSWF(
    "strobe/StrobeMediaPlayback.swf"
    , "StrobeMediaPlayback"
    , 1024
    , 768
    , "10.1.0"
    , "strobe/expressInstall.swf"
    , parameters
    , {
      allowFullScreen: "true"
    }
    , {
      name: "StrobeMediaPlayback"
    }
  );
</script>
 
</head>
<body>
<div id="StrobeMediaPlayback"></div>
</body>
</html>

参考文献

  1. https://github.com/winshining/nginx-http-flv-module
  2. https://blog.gtwang.org/iot/raspberry-pi-nginx-rtmp-server-live-streaming/
  3. http://shumeipai.nxez.com/2017/11/01/build-rtmp-stream-live-server-with-raspberry-pi.html
Tags:Linux树莓派
上一篇
下一篇

添加新评论