文章目录

  • 0. 概述
  • 1. 搭建服务器(Nginx)
  • 2. 获取源视频及音频
  • 3. 安装编码器(FFmpeg)
  • 4. 视频编码
  • 5. 音频编码
  • 6. 安装视频切片工具(Bento4)
  • 7. 视频切片
  • 8. 编写网页播放器(dash.js)
  • 9. 配置服务器

0. 概述

环境:

  • 视频服务器:Ubuntu 16.04
  • 视频客户端:任意主机上的浏览器(推荐Chrome)

工具:

  • 服务器:Nginx
  • 编码器:FFmpeg
  • 视频切片:Bento4
  • 播放器:dash.js

*注:本文基于Bento4的mp4dash实现,关于基于MP4Box的实现方案,参见:Ubuntu下GPAC(MP4Box)的安装 | 基于MP4Box搭建DASH视频系统

视频:

  • Elephant Dream

分辨率级别:

  • 1920×1080(1080p)
  • 1280×720(720p)
  • 896×504(480p)1
  • 640×360(360p)
  • 256×144(144p)

参考:

  • Nginx 搭建DASH服务器
  • dash视频服务器本地搭建 (初探)

说明:
本文记录了一个最基础的DASH视频服务器与播放器的搭建过程,并在本人掉坑之后补充了一些细节。有兴趣的初学者不需要了解具体知识,只需跟随说明,即可成功复现。
为了可读性,将工具的安装过程单独写在了别的博文里,点开即见,相当于函数封装了。


1. 搭建服务器(Nginx)

见:Ubuntu下Nginx的安装及使用
(建议使用源码安装)


2. 获取源视频及音频

视频名称:Elephants Dream
来源:Xiph.org :: Derf’s Test Media Collection

1. 视频
原始格式:y4m
原始帧率:24fps
原始时长:10m53s
原始比例:16:9
原始分辨率:1920×1080(1080p)
原始大小:46GB
下载链接:elephants_dream_1080p24.y4m.xz
文件为.xz压缩包,大小为7.13GB,解压命令为:

xz -d elephants_dream_1080p24.y4m.xz

2. 音频
原始格式:flac
原始时长:10m58s(*注:比视频长5s左右,后续没有对这个时间差进行处理)
下载页面:Index of /video/derf/flac/ED
下载链接:ED-CM-St-16bit.flac(*注:其他6个文件是5.1环绕立体声的6条音轨,只有这个是完整的音频)


3. 安装编码器(FFmpeg)

见:Ubuntu下FFmpeg的安装(支持libfdk_acc)
(需支持libfdk_aac,因此应使用源码安装)

若有更多编码需求(如VP9、AV1等),建议直接参阅官方文档:CompilationGuide/Ubuntu – FFmpeg


4. 视频编码

目的编码:H.264/AVC

目的分辨率级别:

  • 1920×1080(1080p)
  • 1280×720(720p)
  • 896×504(480p)
  • 640×360(360p)
  • 256×144(144p)

使用最简单的编码方式,每个分辨率视频的对应命令为:

ffmpeg -i elephants_dream_1080p24.y4m -s 1920x1080 -c:v libx264 -keyint_min 48 -g 48 -sc_threshold 0 -an ED1920x1080.mp4
ffmpeg -i elephants_dream_1080p24.y4m -s 1280x720 -c:v libx264 -keyint_min 48 -g 48 -sc_threshold 0 -an ED1280x720.mp4
ffmpeg -i elephants_dream_1080p24.y4m -s 896x504 -c:v libx264 -keyint_min 48 -g 48 -sc_threshold 0 -an ED896x504.mp4
ffmpeg -i elephants_dream_1080p24.y4m -s 640x360 -c:v libx264 -keyint_min 48 -g 48 -sc_threshold 0 -an ED640x360.mp4
ffmpeg -i elephants_dream_1080p24.y4m -s 256x144 -c:v libx264 -keyint_min 48 -g 48 -sc_threshold 0 -an ED256x144.mp4

关于选项:

  • -s:分辨率
  • -c:v libx264:使用x264编码库,将视频编码为H.264/AVC格式
  • -keyint_min 48 -g 48 -sc_threshold 0:固定GOP长度为48帧(即2s),这里涉及到一个后续可能会遇到的错误2
  • -an:y4m格式不包含音频,因此此处不对音频进行编码

*注:

  • 编码可能需要很长时间,需要等待。
  • 此时生成的各视频均不包含音频

编码完成后,各分辨率下的视频I帧对齐,I帧个数均为327个,对应327个GOP,每个GOP时长2s。各分辨率下的视频码率(单位:kbps)分别为(见ffmpeg输出信息):

  • 1920x1080(1080p):3988.49
  • 1280x720(720p):1983.08
  • 896x504(480p):1131.42
  • 640x360(360p):676.67
  • 256x144(144p):147.76

5. 音频编码

需要将音频使用AAC进行编码为m4a格式3,命令为:

ffmpeg -i ED-CM-St-16bit.flac -c:a libfdk_aac ED.m4a

为了后续的步骤,需要将该m4a音频与之前编码的视频进行合并,输出一个有音轨的视频4,具体命令为:

ffmpeg -i ED1920x1080.mp4 -i ED.m4a -vn -c:a copy ED_audio.mp4

*注:此视频只需要音轨,不需要视频画面,因此用-vn忽略视频编码,否则后面会多生成一种视频的Representation


*注:对音频编码时,若换用其他编码库(如alac),可能会在播放时引起错误:

[6395][Stream] audioCodec (audio/mp4;codecs="mp4a") is not supported.

这是因为浏览器不支持其他编码的音频,参考:Profiles and codecs supported by the Reference Client ( dash.js )?

Dash.js itself does not support codecs. It is a MSE client, meaning that it relies upon the browser’s MSE implementation to decode the content. It will pass along ANY codec that is specified within the manifest and ask the sourceBuffer if it can play it. So the answer to your question is really what codecs do Chrome, IE11, FF and Safari/Yosemite support for MSE?


6. 安装视频切片工具(Bento4)

见:Ubuntu下Bento4(mp4info、mp4fragment、mp4dash)的安装及使用

*注:鉴于mp4dash编码后MPD文件中的码率与视频真实码率不一致(见下),建议用MP4Box完成视频切片,详见:基于MP4Box搭建DASH视频系统


7. 视频切片

步骤:
1. fragment:使用mp4fragment对各分辨率视频及音频视频进行fragment(指定fragment时长为2s)

mp4fragment --fragment-duration 2000 ED1920x1080.mp4 f1080p.mp4
mp4fragment --fragment-duration 2000 ED1280x720.mp4 f720p.mp4
mp4fragment --fragment-duration 2000 ED896x504.mp4 f480p.mp4
mp4fragment --fragment-duration 2000 ED640x360.mp4 f360p.mp4
mp4fragment --fragment-duration 2000 ED256x144.mp4 f144p.mp4
mp4fragment --fragment-duration 2000 ED_audio.mp4 f_audio.mp4

2. 切片:使用mp4dash对已fragment的视频进行切片

mp4dash f1080p.mp4 f720p.mp4 f480p.mp4 f360p.mp4 f144p.mp4 f_audio.mp4

成功后,生成文件的目录结构为:

output/
├── audio/
│   └── und/
│       └── mp4a/
│           ├── init.mp4
│           ├── seg-1.m4s
│           ├── ...
│           └── seg-330.m4s
├── stream.mpd
└── video/└── avc1/├── 1/├── 2/├── 3/├── 4/└── 5/├── init.mp4├── seg-1.m4s├── ...└── seg-327.m4s

可以看到,mp4dash将5种分辨率的视频分别分为了327个视频段,并为其生成了mpd文件。此外,由于音频比视频长5s左右,因此音频有330个段,比视频多了3个

生成的stream.mpd5的内容为:

<?xml version="1.0" ?>
<MPD mediaPresentationDuration="PT10M53.792S" minBufferTime="PT2.00S" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" xmlns="urn:mpeg:dash:schema:mpd:2011"><!-- Created with Bento4 mp4-dash.py, VERSION=1.8.0-629 --><Period><!-- Video --><AdaptationSet maxHeight="1080" maxWidth="1920" mimeType="video/mp4" segmentAlignment="true" startWithSAP="1"><SegmentTemplate duration="2000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1" timescale="1000"/><Representation bandwidth="16079970" codecs="avc1.640028" frameRate="24" height="1080" id="video/avc1/1" scanType="progressive" width="1920"/><Representation bandwidth="7753362" codecs="avc1.64001F" frameRate="24" height="720" id="video/avc1/2" scanType="progressive" width="1280"/><Representation bandwidth="4310870" codecs="avc1.64001F" frameRate="24" height="504" id="video/avc1/3" scanType="progressive" width="896"/><Representation bandwidth="2391544" codecs="avc1.64001E" frameRate="24" height="360" id="video/avc1/4" scanType="progressive" width="640"/><Representation bandwidth="402408" codecs="avc1.64000C" frameRate="24" height="144" id="video/avc1/5" scanType="progressive" width="256"/></AdaptationSet><!-- Audio --><AdaptationSet mimeType="audio/mp4" segmentAlignment="true" startWithSAP="1"><SegmentTemplate duration="2000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1" timescale="1000"/><Representation audioSamplingRate="48000" bandwidth="141821" codecs="mp4a.40.2" id="audio/und/mp4a"><AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/></Representation></AdaptationSet></Period>
</MPD>

8. 编写网页播放器(dash.js)

*注:如果视频服务器有公网IP,则无需自己实现网页播放器,直接在Dash JavaScript Player中填上MPD文件的链接,点击"Load"即可(先完成本文第9步)。

播放器实现基于dash.js,其GitHub仓库为: Dash-Industry-Forum/dash.js: A reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers

首先,需要下载dash.js到本地,下载链接为:dash.all.min.js
*注:若此链接失效,可通过dash.js的GitHub页面(见上)寻找最新版本文件。

之后,编写一个简单的播放器页面(index.html):

<!DOCTYPE html>
<html><head><title>Dash.js Rocks</title><style>video {width: 640px;height: 360px;}</style></head><body><div><video data-dashjs-player autoplay src="./stream.mpd" controls></video></div><script src="./dash.all.min.js"></script></body>
</html>

*注意:这种写法要求index.htmldash.all.min.jsstream.mpd在同一目录下


9. 配置服务器

步骤:
1. 修改Nginx配置
/usr/local/conf/nginx.conf中,添加6

location /
{...add_header Access-Control-Allow-Methods "GET,OPTIONS,POST,HEAD,PUT,DELETE";add_header Accept-Ranges "bytes";add_header Access-Control-Allow-Origin "*";add_header Access-Control-Expose-Headers "Content-Lengrh,Content-Range,Date,Server,Transfer-Encoding,origin,range,x-goog-meta-foo1";
}

之后,验证并重载配置:

nginx -t
nginx -s reload

2. 部署相关文件

  • 将nginx的html/目录(即:/usr/local/nginx/html/)下原本的index.html改名为index_bak.html
  • 将之前生成的output/下所有文件(见上)转移至html/目录下
  • 将之前写好的index.html及下载的dash.all.min.js转移至html/目录下

此时,html/下的文件目录结构为:

/usr/local/nginx/html/50x.htmlaudio/und/mp4a/init.mp4seg-1.m4s...seg-330.m4sdash.all.min.jsindex_bak.htmlindex.htmlstream.mpdvideo/avc1/1/2/3/4/5/init.mp4seg-1.m4s...seg-327.m4s

最后,打开本地浏览器,输入:

http://localhost/

或在其他机器(客户端)上,输入:

http://服务器IP/



可以看出,视频和音频是以一个个格式为m4s的分段进行传输的,其中较小的为音频,较大的为视频。

到此,一个完整的DASH视频系统就正式完成了。Enjoy it!~


  1. 这个分辨率是参考爱奇艺的 ↩︎

  2. 该问题详见:FFmpeg的GOP(I帧)对齐问题 ↩︎

  3. 参考:audio - How do I convert FLAC files to AAC (preferrably VBR 320k+)? ↩︎

  4. 参考:使用FFmpeg合并音视频 ↩︎

  5. 此处生成的MPD文件中的bandwidth值与之前ffmpeg编码得到的视频码率不一致,原因及分析见:mp4dash生成的MPD文件中的Bandwidth取值及其对客户端码率选择的影响 ↩︎

  6. 与HTTP访问控制相关,详见:HTTP访问控制(CORS) ↩︎

DASH视频系统(服务器播放器)搭建相关推荐

  1. linux系统媒体播放器(media player)大全

    媒体播放器 是一种软件程序,可以使用它来播放多种类型的媒体文件,如音频和视频等. 常见的媒体播放器有 Windows Media Player.QuickTime Player.iTunes.Real ...

  2. 计算机管理器为什么没有本地用户和组,windows7系统服务器管理器没有“本地用户和组”选项解决方法...

    本地用户和组功能可以分配本地用户帐户或组帐户的权限和权利.win7系统点击"计算机"图标右键"管理"来打开"计算机管理"中的"本地 ...

  3. css3音乐播放器,CSS3-自定义视频与音乐播放器!

    今天说一下自定义视频和音乐播放器!直接先看看完成后的效果图把! 视频: video.jpg 音乐: 音乐.jpg 哈哈,是不是觉得太难看了,根本没心情往下继续看了?那就对了.我也觉得难看,但是重点来了 ...

  4. win8计算机管理没本地用户和组,win7系统服务器管理器没有本地用户和组选项怎么办?...

    win7系统服务器管理器没有"本地用户和组"选项怎么办? 具体方法如下: 1.出现这种情况一般是组策略做限制了,打开运行gpedit.msc打开组策略编辑器; 2.依次点击,用户设 ...

  5. html给视频加音乐播放器,给视频加背景音乐 ppt如何添加视频加背景音乐-简单实现...

    我们在使用PowerPoint(简称PPT)时,根据需求有时候需要加入视频和ppt如何添加视频加背景音乐的方法有很多,这里就说说简单实现的一种方法,还有比较实用的狸窝PPT转换器PPT转换视频的教程贴 ...

  6. Html5视频加密/html5播放器视频加密应用实例

    说说html5的视频加密,HTML5因无需插件可跨平台使用.开发免费.对搜索引擎友好等,深受广大开发者的喜爱,成为主流播放器的发展趋势. 市面上常见的H5加密,采用标准的Apple HLS Encry ...

  7. Win系统服务器管理器打开方式

    Win系统服务器管理器打开方式 1.运行打开服务的命令 services.msc 2.在"计算机管理"中打开服务管理器 按Win+X组合键 或 右键点击Win10开始按钮---&g ...

  8. 【音视频】ijkplayer播放器参数说明文档

    [音视频]ijkplayer播放器参数说明文档 pragma mark - IJKMediaPlayback #pragma mark 通知IJKMPMediaPlaybackIsPreparedTo ...

  9. 手机影音第十一天,显示视频缓冲,显示卡顿时的网速,播放系统视频时调用播放器的选择...

    代码已经托管到码云,有兴趣的小伙伴可以下载看看 https://git.oschina.net/joy_yuan/MobilePlayer 一.设置视频缓冲进度 显示视频播放进度的效果图如下:灰色的是 ...

最新文章

  1. 自学Python从哪学方面入手?
  2. servlet web.xml配置详解
  3. 邓侃:深度强化学习“深”在哪里?
  4. BZOJ3527:[ZJOI2014]力(FFT)
  5. php 配置 gd2,配置PHP对gd库的支持
  6. MYSQ--SHOW PROFILE Syntax and useing
  7. CentOS7.2中使用Kubernetes(k8s)1.4.6源码搭建k8s容器集群环境
  8. 封装DataList分页
  9. “A class named TcxRect already exists”错误
  10. java布尔值_Java中的布尔值与布尔值
  11. ASP.NET 2.0使用Web Part创建应用程序之一(共二)
  12. WPS专业版自带字体
  13. MQTT.fx工具测试mqtt
  14. MATLAB从入门到精通 第1章 MATLAB入门
  15. vue 源码学习总纲
  16. 移动app用户体验与性能优化
  17. p5727深基5.例3冰雹猜想c语言,深基
  18. R语言使用plot函数可视化数据散点图,使用title函数为可视化图像设置自定义标题名称、自定义adj参数将标题向右侧移动
  19. python-绘制散点图
  20. chrome插件draw.io代替visio成为流程图架构图制作新的利器

热门文章

  1. 京东商城 最具争议的B2C
  2. Eclipse安装Mat工具分析教程
  3. 安信可ESP8266模块实现对接天猫精灵IOT平台控制单路插座的教程
  4. 2019北京国际智能-智慧教育产品展
  5. 论文笔记:Planning and Decision-Making for Autonomous Vehicles
  6. 版本 000 / 2020 作业计划/数量计划中没有 作业类型 XXX的控制记录
  7. Moodle平台问题集锦
  8. 微信小程序 -- 联系客服(小程序客服)
  9. Maven Pom文件标签详解
  10. 郝健: Linux内存管理学习笔记-第1节课【转】