Nginx 学习笔记nginx-vod-module 模块

Posted Tinywan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx 学习笔记nginx-vod-module 模块相关的知识,希望对你有一定的参考价值。

https://github.com/kaltura/nginx-vod-module

一、编译

./configure \\
--user=www \\
--group=www \\
--prefix=/usr/local/openresty \\
--with-debug \\
--with-luajit \\
--with-file-aio \\
--with-threads \\
--with-cc-opt="-O3" \\
--with-http_v2_module \\
--with-http_realip_module \\--with-http_gzip_static_module \\
--with-http_ssl_module \\
--with-openssl=/usr/local/ssl \\
--with-openssl-opt="enable-tlsext" \\
--without-http_redis2_module \\
--with-http_iconv_module \\
--with-http_stub_status_module \\
--with-http_xslt_module \\--add-dynamic-module=/home/www/build/nginx-vod-module 

推荐设置:

  1. --with-file-aio - 启用异步I / O支持,强烈建议,仅与本地和映射模式相关
  2. --with-threads(nginx 1.7.11+) - 使用线程池(也需要vod_open_file_thread_pool在nginx.conf中)启用异步文件,仅与本地和映射模式相关
  3. --with-cc-opt="-O3"- 启用额外的编译器优化(与nginx默认值相比,mp4解析时间和帧处理时间减少了大约8%-O

调试设置:

  1. --with-debug- 启用调试消息(也需要传入nginx.conf debug中的error_log指令)。
  2. --with-cc-opt="-O0" - 禁用编译器优化(用gdb进行调试)

移植文件

cp -f /home/www/build/openresty-1.13.6.1/build/nginx-1.13.6/objs/ngx_http_vod_module.so /usr/local/openresty/nginx/modules/ngx_http_vod_module.so

cp -f /home/www/build/openresty-1.13.6.1/build/nginx-1.13.6/objs/nginx  /usr/local/openresty/nginx/sbin/nginx

重启服务

sudo service nginx restart 
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.

》》今天发现了一个好办法,通过以上启动服务器是不报错的,直接启动不起来,不管什么错误都是提示以上错误信息,今天终于找到办法了,那就是运行Nignx二进制文件,会有错误日志输出哦

sudo ../../sbin/nginx
nginx: [emerg] unknown directive "vod_mode" in /usr/local/openresty/nginx/conf/vhost/nginx.vod.module.conf:3

遇到的错误:

nginx: [emerg] unknown directive "vod_moov_cache" in /usr/local/openresty/nginx/conf/vhost/nginx.vod.module.conf:7

解决:https://github.com/kaltura/nginx-vod-module/issues/739

网址结构

一、基本的网址结构

URI 的基本结构是: http://<domain>/<location>/<fileuri>/<filename>

  • domain - nginx-vod-module服务器的域
  • location - 在nginx conf中指定的位置
  • fileuri - 一个到mp4文件的URI:
    • 本地模式 - 完整的文件路径是根据根/别名nginx.conf指令确定的
    • 映射模式 - 完整的文件路径是根据从上游/本地文件接收到的JSON来确定的
    • 远程模式 - mp4文件是从上游块中读取的
    • 注意:在映射模式和远程模式下,上游请求的URL是http://<upstream>/<location>/<fileuri>?<extraargs>(extraargs由vod_upstream_extra_args参数决定)
  • 文件名 - 详细如下
    • domain:vod.tinywan.com
    • location:location /vod { }
    • fileuri:/home/www/ffmpeg/  

本地模式测试

    server {
        listen 8384;

        # vod caches
        vod_metadata_cache metadata_cache 256m;
        vod_response_cache response_cache 128m;

        # vod settings
        vod_mode local;
        vod_segment_duration 2000; # 2s
        vod_align_segments_to_key_frames on;

        #file handle caching / aio
        open_file_cache max=1000 inactive=5m;
        open_file_cache_valid 2m;
        open_file_cache_min_uses 1;
        open_file_cache_errors on;
        aio on;

        location /hls/ {
            alias /home/www/ffmpeg/;
            vod hls;
            add_header Access-Control-Allow-Headers \'*\';
            add_header Access-Control-Expose-Headers \'Server,range,Content-Length,Content-Range\';
            add_header Access-Control-Allow-Methods \'GET, HEAD, OPTIONS\';
            add_header Access-Control-Allow-Origin \'*\';
            expires 100d;
        }
    }

MP4文件路径

www@TinywanAliYun:~/ffmpeg$ pwd
/home/www/ffmpeg
www@TinywanAliYun:~/ffmpeg$ ls -lh nginx_vod_test.mp4 
-rwxrwxrwx 1 www www 340M Dec 18  2013 nginx_vod_test.mp4

注:MP4文件的权限是775

播放URL:http://127.0.0.1:8384/hls/nginx_vod_test.mp4/index.m3u8

二、多个网址结构

多个网址用于在单个网址上对多个网址进行编码。例如,可以使用多个URL来指定应包含在DASH MPD中的几个不同MP4文件的URL。

多个URL的结构是: http://<domain>/<location>/<prefix>,<middle1>,<middle2>,<middle3>,<postfix>.urlset/<filename>

上面的示例网址代表3个网址:

  • http://<domain>/<location>/<prefix><middle1><postfix>/<filename>
  • http://<domain>/<location>/<prefix><middle2><postfix>/<filename>
  • http://<domain>/<location>/<prefix><middle3><postfix>/<filename>

后缀.urlset(可以使用vod_multi_uri_suffix更改)表示该URL应被视为多个URL。例如,URL http://example.com/hls/videos/big_buck_bunny_,6,9,15,00k.mp4.urlset/master.m3u8将返回一个包含以下内容的清单:

三、网址路径参数

URL路径支持以下参数:

  • clipFrom - 自视频开始以来的偏移量(以毫秒为单位),其中生成的流应该开始。例如,.../clipFrom/10000/...将生成一个流10秒开始的视频流。
  • clipTo - 自视频开始以来的偏移量(以毫秒为单位),其中生成的流将结束。例如,.../clipTo/60000/...将生成一个截断到60秒的流。
  • 轨道 - 可用于选择特定的音频/视频轨道。参数的结构是:v<id1>-v<id2>-a<id1>-a<id2>... 例如,.../tracks/v1-a1/...将选择第一个视频轨道和第一个音轨。默认是包含所有曲目。
  • 移位 - 可用于将时间转换应用于一个或多个流。参数的结构是:v<vshift>-a<ashift>-s<sshift> 例如,.../shift/v100/...将100ms的正向移位应用到视频时间戳

四、文件名结构

文件名的结构是: <basename>[<seqparams>][<fileparams>][<trackparams>][<langparams>].<extension>

  • basename +扩展名 - 选项集是打包者特定的(下面的列表适用于默认设置):seqparams - 可用于通过id(在映射JSON中提供)来选择特定序列,例如master-sseq1.m3u8。fileparams - 可用于在使用多个URL时按索引选择特定序列。例如,manifest-f1.mpd将仅从第一个URL返回一个MPD。trackparams - 可用于选择特定的音频/视频轨道。例如,manifest-a1.f4m将返回仅包含每个序列的第一个音频流的F4M。默认是包含每个文件的第一个音频和第一个视频轨道。在文件名中选择的曲目与使用/ tracks / path参数选择的曲目进行AND运算。v0 / a0分别选择所有视频/音频轨道。a / v参数可以与f / s结合,例如f1-v1-f2-a1 = file1的video1 + file2的audio1,f1-f2-v1 = file1的video1 + file2的video1。langparams - 可用于根据语言(ISO639-3代码)过滤音轨/字幕。例如,master-leng.m3u8将只返回英文音轨。
    • dash - manifest.mpd
    • hds - manifest.f4m
    • hls主播放列表 - master.m3u8
    • hls媒体播放列表 - index.m3u8
    • mss - 清单
    • thumb - thumb-<offset>[<resizeparams>].jpg(偏移量是以毫秒为单位的缩略图视频偏移量)
    • volume_map - volume_map.csv
  • resizeparams - 可用于调整返回的缩略图图像。例如,thumb-1000-w150-h100.jpg在视频中捕获缩略图1秒,并将其大小调整为150x100。如果省略其中一个尺寸,则设置其值以使得生成的图像保持视频帧的纵横比。

五、映射响应格式

当配置为在映射模式下运行时,nginx-vod-module向配置的上游服务器发出HTTP请求,以便接收它应该生成的媒体流的布局。响应必须采用JSON格式

本部分包含几个简单的示例,后面是对支持的对象和字段的引用。但首先,有几个定义:

  1. Source Clip - 从单个媒体文件中提取的一组音频和/或视频帧(音轨)
  2. Generator - 可以生成音频/视频帧的组件。目前,唯一支持的发生器是无声发生器。
  3. Filter - 可以应用于音频/视频帧的操作。支持以下过滤器:
    • 速率(速度)变化 - 适用于音频和视频
    • 音量变化
    • 混合 - 可用于将多个音轨合并在一起,或将源A的音频与源B的视频合并
  1. Clip - 在一组源剪辑上应用零个或多个过滤器的结果
  2. Dynamic Clip - 内容未知的剪辑,例如有针对性的广告内容
  3. Sequence - 一组应该一个接一个播放的剪辑。
  4. Set - 几个序列一起作为自适应集合播放,每个序列必须具有相同数量的剪辑。

六、简单的映射

下面的JSON将请求URI映射到单个MP4文件:

{
    "sequences": [
        {
            "clips": [
                {
                    "type": "source",
                    "path": "/path/to/video.mp4"
                }
            ]
        }
    ]
}

当使用多个URL时,这是唯一允许的JSON模式。换句话说,使用多个URL来组合更复杂的JSON是不可能的。

映射模式测试(使用json文件播放一个mp4文件)

JSON文件

www@TinywanAliYun:~/data/vod-json$ pwd
/home/www/data/vod-json
www@TinywanAliYun:~/data/vod-json$ cat tinywan.json 
{
    "sequences": [
        {
            "clips": [
                {
                    "type": "source", 
                    "path": "/home/www/ffmpeg-data/59f81ac0f1ec2.mp4"
                }
            ]
        }
    ]
}

虚拟主机

    server {
        listen 8384;

        # vod caches
        vod_metadata_cache metadata_cache 256m;
        vod_response_cache response_cache 128m;

        # vod settings
        vod_mode mapped;
        vod_segment_duration 2000; # 2s
        vod_align_segments_to_key_frames on;

        #file handle caching / aio
        open_file_cache max=1000 inactive=5m;
        open_file_cache_valid 2m;
        open_file_cache_min_uses 1;
        open_file_cache_errors on;
        aio on;

         # json file play hls
         location /json_hls/ {
            add_header Access-Control-Allow-Headers \'*\';
            add_header Access-Control-Expose-Headers \'Server,range,Content-Length,Content-Range\';
            add_header Access-Control-Allow-Methods \'GET, HEAD, OPTIONS\';
            add_header Access-Control-Allow-Origin \'*\';

            vod hls;
            alias /home/www/data/vod-json/;
         }
    }

注:这里一定是映射模式

VLC播放测试:http://nginx-vod.tinywan.com:8384/json_hls/tinywan.json/index.m3u8

测试结果:

 说明:当然了tinywan.json 文件我们是可以动态的修改,如:使用php去动态修改json文件中的MP4文件路径,可以更换播放源,一旦换掉,以前的将会断掉,重新播放新的源文件

 可能出现的错误,请检查配置文件,是否为映射模式

2017/11/27 21:20:56 [error] 8630#8630: *44 ngx_http_vod_identify_format: failed to identify the file format /home/www/data/vod-json/video.json while reading media header,

七、自适应集

作为使用多个URL的替代方案,可以通过JSON定义自适应集:

{
    "sequences": [
        {
            "clips": [
                {
                    "type": "source",
                    "path": "/path/to/bitrate1.mp4"
                }
            ]
        },
        {
            "clips": [
                {
                    "type": "source",
                    "path": "/path/to/bitrate2.mp4"
                }
            ]
        }
    ]
}

上面的暂时不能够播放,待解决?????

提示错误:

2017/11/27 21:59:12 [error] 8750#8750: *637 ngx_http_vod_validate_streams: one stream at most per media type is allowed video=2 audio=2 while getting mapping, 

八、播放列表

下面的JSON会播放35秒的视频1和22秒的视频2:

 tinywan_multiple_durations.json 文件

{
    "durations": [ 35000, 22000 ],
    "sequences": [
        {
            "clips": [
                {
                    "type": "source",
                    "path": "/home/www/ffmpeg-data/59fb2eba73a57.mp4"
                },
                {
                    "type": "source",
                    "path": "/home/www/ffmpeg-data/59f81ac0f1ec2.mp4"
                }
            ]
        }
    ]
}

 VLC播放测试:http://nginx-vod.tinywan.com:8384/json_hls/tinywan_multiple_durations.json/index.m3u8

 

前35s播放:59fb2eba73a57.mp4

后22s播放:59f81ac0f1ec2.mp4

过滤器

下面的JSON将视频1播放到x1.5,并将结果的音频与视频2的音频混合,然后将其降低到50%音量:

{
    "sequences": [
        {
            "clips": [
                {
                    "type": "mixFilter",
                    "sources": [
                        {
                            "type": "rateFilter",
                            "rate": 1.5,
                            "source": {
                                "type": "source",
                                "path": "/path/to/video1.mp4"
                            }
                        },
                        {
                            "type": "gainFilter",
                            "gain": 0.5,
                            "source": {
                                "type": "source",
                                "path": "/path/to/video2.mp4",
                                "tracks": "a1"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

连续直播

下面的JSON是一个连续的直播流(=所有视频具有完全相同的编码参数的直播流)的示例。在实践中,这个JSON必须由一些脚本生成,因为它依赖于时间。(有关示例实现,请参阅test / playlist.php)

{
    "playlistType": "live",
    "discontinuity": false,
    "segmentBaseTime": 1451904060000,
    "firstClipTime": 1451917506000,
    "durations": [83000, 83000],
    "sequences": [
        {
            "clips": [
                {
                    "type": "source",
                    "path": "/path/to/video1.mp4"
                },
                {
                    "type": "source",
                    "path": "/path/to/video2.mp4"
                }
            ]
        }
    ]
}

非连续的直播

下面的JSON是非连续直播流(=视频具有不同编码参数的直播流)的示例。在实践中,这个JSON必须由某个脚本生成,因为它是时间依赖的(参见test / playlist.php)

{
    "playlistType": "live",
    "discontinuity": true,
    "initialClipIndex": 171,
    "initialSegmentIndex": 153,
    "firstClipTime": 1451918170000,
    "durations": [83000, 83000],
    "sequences": [
        {
            "clips": [
                {
                    "type": "source",
                    "path": "/path/to/video1.mp4"
                },
                {
                    "type": "source",
                    "path": "/path/to/video2.mp4"
                }
            ]
        }
    ]
}

(1)编译没有启用异步I / O支持(裸奔ngx-vod-module),播放一个MP4文件

结论:打开的很慢,很卡,原因就是我服务带宽太小了(1M啊),视频卡顿原因,带宽太小了,今天升级带宽为5M,不会再出先卡顿现象

 (2)OSS下载一个文件进行播放,缓存不够吗?

 

性能建议

6、通过更改以下参数可以减少此模块生成的流的复用开销:

  • HDS - 设置vod_hds_generate_moof_atom为关闭
  • HLS - 设置vod_hls_mpegts_align_frames为关闭和vod_hls_mpegts_interleave_frames打开

测试结果:

#vod_hds_generate_moof_atom off;
#vod_hls_mpegts_align_frames off;
#vod_hls_mpegts_interleave_frames on;

视频每隔2帧就会一卡一卡的,不推荐。

HLS

HLS主播放列表文件的名称(默认为m3u8扩展名)。

vod_hls_index_file_name_prefix

语法:vod_hls_index_file_name_prefix name

默认:index

背景:httpserverlocation

描述:HLS媒体播放列表文件的名称(隐含M3u8扩展名)。

案例:vod_hls_index_file_name_prefix main;

默认url地址为:../video/1510808170003.mp4/index.m3u8

新播放url地址为:../video/1510808170003.mp4/main.m3u8

 

vod_hls_segment_file_name_prefix

语法:vod_hls_segment_file_name_prefix name

默认:seg

背景:httpserverlocation

描述:段文件名的前缀,实际的文件名是:seg-<index>-v<video-track-index>-a<audio-track-index>.ts

案例: vod_hls_segment_file_name_prefix tinywan;

配置指令 - 性能

vod_metadata_cache

  • 语法:vod_metadata_cache zone_name zone_size [expiration]
  • 默认:off
  • 背景:httpserverlocation

配置视频元数据缓存的大小和共享内存对象名称。对于MP4文件,这个缓存保存moov原子。

vod_mapping_cache

  • 语法:vod_mapping_cache zone_name zone_size [expiration]
  • 默认:off
  • 背景:httpserverlocation

为vod配置映射缓存的大小和共享内存对象名称(仅限映射模式)。

vod_live_mapping_cache

  • 语法:vod_live_mapping_cache zone_name zone_size [expiration]
  • 默认:off
  • 背景:httpserverlocation

配置实时映射缓存的大小和共享内存对象名称(仅限映射模式)。

vod_response_cache

  • 语法:vod_response_cache zone_name zone_size [expiration]
  • 默认:off
  • 背景:httpserverlocation

配置响应缓存的大小和共享内存对象名称。响应缓存包含清单和其他非视频内容(如DASH初始段,HLS加密密钥等)。视频片段不被缓存

vod_live_response_cache

  • 语法:vod_live_response_cache zone_name zone_size [expiration]
  • 默认:off
  • 背景:httpserverlocation

配置响应缓存的大小和共享内存对象名称,以便更改实时响应。该缓存包含以下类型的响应:DASH MPD,HLS索引M3U8,HDS引导,MSS清单。

vod_initial_read_size

  • 语法:vod_initial_read_size size
  • 默认:4K
  • 背景:httpserverlocation

设置MP4文件的初始读取操作的大小。

vod_max_metadata_size

  • 语法:vod_max_metadata_size size
  • 默认:128MB
  • 背景:httpserverlocation

设置支持的最大视频元数据大小(对于MP4 - moov原子大小)

vod_max_frames_size

  • 语法:vod_max_frames_size size
  • 默认:16MB
  • 背景:httpserverlocation

设置单个段的帧的总大小限制

vod_cache_buffer_size

  • 语法:vod_cache_buffer_size size
  • 默认:256K
  • 背景:httpserverlocation

设置读取MP4帧时使用的缓存缓冲区的大小。

vod_open_file_thread_pool

  • 语法:vod_open_file_thread_pool pool_name
  • 默认:off
  • 背景:httpserverlocation

启用通过线程池打开的异步文件。线程池必须使用thread_pool指令定义,如果未指定池名称,则使用默认池。当使用--add-threads进行编译时,该指令仅在nginx 1.7.11或更新版本上受支持。注意:这个指令目前禁止nginx-vod-module使用nginx的open_file_cache

vod_output_buffer_pool

  • 语法:vod_output_buffer_pool size count
  • 默认:off
  • 背景:httpserverlocation

预先分配缓冲区以生成响应数据,从而节省每个请求的分配/释放缓冲区的需求。

vod_performance_counters

  • 语法:vod_performance_counters zone_name
  • 默认:off
  • 背景:httpserverlocation

配置性能计数器的共享内存对象名称

配置指令 - DRM /加密

vod_secret_key

  • 语法:vod_secret_key string
  • 默认:empty
  • 背景:httpserverlocation

设置用于生成TS加密密钥和DASH / MSS加密IV的种子。参数值可以包含变量,通常具有“secret- $ vod_filepath”结构。查看下面这个模块添加的nginx变量列表。

vod_encryption_iv_seed

  • 语法:vod_encryption_iv_seed string
  • 默认:empty
  • 背景:httpserverlocation

设置用于生成加密IV的种子,目前仅适用于使用AES-128加密的HLS / fMP4。参数值可以包含变量。

vod_drm_enabled

  • 语法:vod_drm_enabled on/off
  • 默认:off
  • 背景:httpserverlocation

启用后,模块将根据从drm上游获得的响应来加密媒体段。目前仅支持破折号和mss(播放就绪)。

vod_drm_single_key

  • 语法:vod_drm_single_key on/off
  • 默认:off
  • 背景:httpserverlocation

启用时,模块只请求第一个序列的drm信息并将其应用于所有序列。禁用时,需要为每个序列单独请求DRM信息。此外,在DASH中,启用此设置将使模块将ContentProtection标签置于AdaptationSet下,否则置于Representation下。

vod_drm_clear_lead_segment_count

  • 语法:vod_drm_clear_lead_segment_count count
  • 默认:1
  • 背景:httpserverlocation

设置流开始处的清除(未加密)分段的数量。明确的领先优势使玩家无需等待许可证回应即可开始游戏。

vod_drm_max_info_length

  • 语法:vod_drm_max_info_length length
  • 默认:4K
  • 背景:httpserverlocation

设置从上游返回的drm信息的最大长度。

vod_drm_upstream_location

  • 语法:vod_drm_upstream_location location
  • 默认:none
  • 背景:httpserverlocation

设置应该用于获取文件的DRM信息的nginx位置。

vod_drm_info_cache

  • 语法:vod_drm_info_cache zone_name zone_size [expiration]
  • 默认:off
  • 背景:httpserverlocation

配置drm信息缓存的大小和共享内存对象名称。

vod_drm_request_uri

  • 语法:vod_drm_request_uri uri
  • 默认:$vod_suburi
  • 背景:httpserverlocation

设置drm信息请求的URI,参数值可以包含变量。在多url的情况下,$vod_suburi将是当前的子uri(每个子URL发出一个单独的drm信息请求)

vod_min_single_nalu_per_frame_segment