Tutorial: How to "live stream" a media file

如何"直播"一个媒体文件

I have tried a while to setup a free (open source etc.) live streaming solution 


which is able to stream “anything” to a flash frontend. The basic idea is to 


stream TV from v4l2 (and similar), but I also wanted to stream files (movies). 


I found that most tutorials only show how to setup the streaming or only show 


how to get a flash player up and running. The whole roundtrip is not really described 


and has its own difficulties. This tutorial describes the whole “roundtrip” 


from a media file on your disk to displaying it in a browser. I know that 


there are easier ways to send a media file to some player in a browser and I also know 


that playing a file is not really live streaming. (This is why I have put it in double quotes.) 


However, it shows the principle and it might be easier to set this up as a first step.


本文讲解如何搭建一个媒体文件(如电影)在flash前端直播的解决方案,


并详述了整个过程:


  从硬盘上的媒体文件到在浏览器中播放;

Maybe important to note that this is targeted to a Linux server, I don’t know how and 


if it works with other operating systems.


本文是基干Linux服务器实现的;

一、概览 Overview


The whole roundtrip looks as follows:


整个流程如下:


  file → ffmpeg → crtmpserver → jwplayer/haxe ( → apache)

ffpmeg : 


  is used to convert the input to h264/aac in an MPEG-TS container 


  and sends it to crtmpserver using UDP


  ffmpeg将输入转换成以MPEG-TS封装的H264/aac格式,并通过UDP协议发送到crtmpserver;

crtmpserver :


  acts as the RTMP server (you might have guessed this)


  crtmpserver作为RTMP server;

jwplayer :


  can then play the stream. With using haXe, it is possible to create your own players


  jwplayer可以用来播放流。


  也可以使用haXe, 来创建自己的播放器;


  


apache :


  is the webserver


  Apache是Webserver;

二、ffmpeg


The following command line converts <filename-of-movie> to h264/aac, puts it into an TS container 


and sends it using UDP. (I have split this on several lines for readability.)


下面的命令行将<filename-of-movie>转码成h264/aac,并封装进TS协议,并通过UDP发送;

> ffmpeg -i "<filename-of-movie>" -re 


         -vcodec libx264 -vpre default -vpre baseline 


         -b 500000 -s 320x180 -strict experimental -g 25 -me_method zero 


         -acodec aac -ab 96000 -ar 48000 -ac 2 -vbsf h264_mp4toannexb 


         -f mpegts udp://127.0.0.1:10000?pkt_size=1316


This command line simulates a live stream. It does not wait for anything to receive the stream, 


it just pumps the data through port 10000 at the speed the movie should play. 


(You should see some ffmpeg output about frames, fps etc.) This is achieved by the ”-re” 


which makes ffmpeg to read the data with (maximum) the framerate which the movie has. 


In addition, the UDP protocol does not wait for the answer of any receiver like TCP would do. 


(As far as I understand.)


这个命令行模仿了一个直播流;它不用等待流的接收端;


它通过端口10000以电影播放的速度吐出数据,这是通过参数“-re”实现的;


它指示了ffmpeg以电影的最大帧率读取数据;


另外,UDP不像TCP,它不用等待接收端的应答;

In my tests, <filename-of-movie> always is in an AVI container, with DivX/XviD and MP3. 


It should, however, work as well with any other movie formats ffmpeg understands properly.


在我的测试中,<filename-of-movie>是以DivX/XviD 和 MP3编码,并以AVI格式封装;


ffmpeg也支持很多其它的文件格式;

The ffmpeg command line above was taken from the wowza documentation. 


I have only experimented a bit to enhance the performance. 


So I have changed the ”-g 60” to ”-g 25” as it seems more appropriate to me 


and added the ”-me_method zero” as it was considered in the ffmpeg documentation as being faster. 


The ffmpeg documentation also mentions using ”-intra”, but this did not work. 


The stream never played in the flash player. (I don't have an explanation for that.)


上面的ffmpeg命令行是我从wowza 的文档中看到的,我做了我所知道的性能提升;


如将 “-g 60 ”改成 “-g 25”等;


更多的可以去看ffmpeg文档

三、crtmpserver


I have checked out and compiled the sources from svn as described on the crtmpserver website. 


After that, the server can be run. I have tried the same with other free rtmp servers 


and it did not work. E.g. I did never succeed with compiling red5. With crtmpserver, 


it just worked. It is also not that complicated to understand the coding. 


(Even if there could be some more comments…)


下载并编译crtmpserver后,就可以启动运行了;

I.e. just get and compile crtmpserver as described in the crtmpserver documentation.

To enable it to receive an UDP TS stream, the following needs to be added to the file 


crtmpserver/builders/cmake/crtmpserver/crtmpserver.lua


为了能接收UDP TS 流,需要对crtmpserver/builders/cmake/crtmpserver/crtmpserver.lua添加


如下配置项:


    {


            ip="0.0.0.0",


            port=10000,


            protocol="inboundUdpTs"


    }, 


This should be added to the acceptors part of the flvplayback application. 


This tells crtmpserver that there should be a stream in a TS container sent via UDP on port 10000. 


(See also rtmpserver.lua for the whole file.)


这个配置项需要添加在“flvplayback”应用的接收器部分;


它告诉crtmpserver需要接收通过UDP向端口10000发送TS 流;

After changing this and running the ffmpeg command line above, run the server with the config file 


as argument, like


修改完成后,启动crtmpserver:

> cd crtmpserver/builders/cmake


> ./crtmpserver/crtmpserver crtmpserver/crtmpserver.lua


(I don't know yet why it only works from the cmake directory. 


Running from the crtmpserver directory itself did not work for me.)

UPDATE: This happens because cmake is used for building the development version of the server. 


It has all the binaries/libraries paths hardcoded in by the GCC linker. 


This is why you can't move around any binaries/libraries. If the production version is required 


(independent paths, maximum optimization, etc), make or packing scripts should be used instead.


The documentation about installing/compiling the server will be changed to reflect that.


更正:


为什么要在cmake目录下启动程序,是因为使用的是server的开发版;


它对应的所有 binaries/libraries的路径都是对GCC固定的;


因此,不能移动任何 binaries/bibraries;


产品版本则没有这样的限制;

I keep having the issue that crtmpserver does not start up when I try it the first time 


after booting the machine. This is because there is another rtmp server (red5) installed 


as well. This needs to be stopped first, at least as long as it runs on the same port. 


I.e. all other rtmp servers should be stopped. On my sytsem, this is done like this:


如果服务器上启动了其它的RTMP服务,crtmpserver将不能正常工作,要先关掉其它的RTMP服务;

> /etc/rc2.d/S20red5-server stop

Apparently, this needs to be done as root.

Apart from some (maybe a lot) warnings, the crtmpserver output should contain something like


  ...basetsappprotocolhandler.cpp:49 Stream available (1): ts_2_257_256


Remember the “ts_2_257_256”, or whatever it exactly looks like. This is the name of the 


stream which is later needed in the flash player. The name might depend on the ffmpeg 


version and on the crtmpserver config and version. 


Generally, it has the format “ts_<id>_<audio-pid>_<video-pid>”.


启动后,crtmpserver会有一些信息提示和警告;并且包含有如下的信息:


  ...basetsappprotocolhandler.cpp:49 Stream available (1): ts_2_257_256


需要记下“ts_2_257_256”,


因为这个流的名字要用在后面的flash播放器;


这个名字依据ffmpeg和crtmpserver版本的不同,可能也会有差异;


通常,它的格式是:


  ts_<id>_<audio-pid>_<video-pid>

crtmpserver now sends the stream as crtmpserver://<your-ip>/flvplayback/ts_2_257_256. 


This URI can be used to point a flash player to the stream. I have successfully done 


this with a very simple player written in Haxe and with JWPlayer as well.


这时,crtmpserver就可以以URI“crtmpserver://<your-ip>/flvplayback/ts_2_257_256”发送流了;


这个URI用在flash播放器的流指定;


播放器可以通过Haxe和JWPlayer来实现;

But first, we need a webserver. Playing the streams from an embedded player using local 


files seems to have some security issues, so flash does not allow it easily.


但在实现播放之前,需要有一个webserver; 


因为使用本地文件实现的内嵌播放器来播放流有一些安全问题,


所以flash不提倡这么做;

四、apache


There's not much to say here. Install apache and find where the content needs to go. 


On my system, this is /var/www, which I believe is the default.


这个没能什么好说的,直接安装一个apache,并使用它的默认目录/var/www

五、JWPlayer


The JWPlayer is a full-blown Flash video player. You can get it from here: 


JWPlayer是一个完整的Flash视频播放器,可以在这下载:


  http://www.longtailvideo.com/players/jw-flv-player/

Copy the file player.swf in a directory which can be reached by the web server 


(e.g. a subdirectory of /var/www) and embed it into an html file as described 


on the longtailvideo website. Alternatively, just use my test_jwplayer.html and 


put it in the same directory as player.swf. When using it, you need to change this part:


  streamer:'rtmp://zeus/flvplayback',file:'ts_2_257_256'


“zeus” is the name of my server, you need to change it to the name of your server. 


If unsure or it does not work, just use 127.0.0.1. Apparently, it will only work locally then…


You might also need to change the stream name (ts_2_257_256) to the one from crtmpserver's output.


将文件player.swf复制到webserver的指定目录(如/var/www), 并将它嵌入到一个HTML页面中;


也可以简单地使用test_jwplayer.html并将它和player.swf放在同一个目录下,


然后修改流地址:


  streamer:'rtmp://zeus/flvplayback',file:'ts_2_257_256'


其中:


"zeus"是服务器域名,要改成你自己的域名或IP;

test_jwplayer.html


<html>                                                                                 


<head>                                                                                 


<script src="/jwplayer/jwplayer.js"></script>                                          


</head>                                                                                


<body>                                                                                 


<div id='my-video'></div> <script type='text/javascript'>                              


  jwplayer('my-video').setup({                                                         


  file:'rtmp://192.168.1.80/live/ts_2_257_256',                                          


  width: '624',                                                                        


  height: '352'     });                                                                


</script>                                                                              


</body>                                                                                


</html>

Now make sure that ffmpeg and crtmpserver are running. Open a browser and type an url like


    http://zeus/thorsten/jwplayer/test_jwplayer.html


Apparently, you need to change “zeus” to your machine's name or try 127.0.0.1. 


The rest is the path to the test_jwplayer.html file, which will also be different on your box.


After a few seconds of buffering, you should be able to watch the movie. 


It might not have the correct aspect ratio and it also might be a bit choppy, 


but it works in principle. 


(If it does not, restart ffmpeg and crtmpserver and reload the page.)


将ffmpeg和crtmpserver都启动后,打开浏览器并输入地址:


  http://zeus/thorsten/jwplayer/test_jwplayer.html


缓冲后,就可以观看电影了;


可能分辨率会有些不对或卡顿,但原则上已经能工作了;

六、haXe


It seems that it can do even more, but for me, haXe (http://haxe.org/) is a free 


(open source) alternative to “develop flash”. I.e. you can write actionscript-like 


programs and compile them to .swf format. (I sometimes need to do things myself to 


really understand them.) I like this especially because I could write my own little 


flash stream player which I could experiment with. In theory, this could also be done 


with JWPlayer as this is open source as well. However, JWPlayer source is a bit complicated 


and I am not sure if you can compile it without the commercial flash development kit.


实际上,haXe能做很多事,但对于我来说,haXe(http://haxe.org/) 是一个免费开源的选择来开发flash;


例如,可能编写类actionscript程序并编译生成.swf格式;


更有用的是,可能通过它来写一个很小的flash流播放器;

If you want to try the haXe player, install haxe (at least on debian, there is a package). 


Then create a file like Test.hx. Open it in an editor and change the appearances of “zeus” 


to your own server's name and change “ts_2_257_256” to the correct stream name. 


(I know that hardcoding these names is not a programming style which deserves 


to be called “style”, but again, it shows the principle.)


如果想试试haXe播放器,


需要先安装haxe,


然后创建一个文件,如Test.hx; 


打开一个编辑器并修改域名"zeus"和"ts_2_257_256"成正确值 ;

The file can then be compiled using the following command line from the directory 


where Test.hx sits in.


使用下面的命令进行编译;

> haxe -swf9 test.swf -main Test

This results in the file test.swf. This can then be embedded as any other flash player into a website, 


see e.g. test_haxe.html.


结果文件test.swf就可以嵌入到的页面中了;

Put test.swf and test_haxe.html in a directory accessible by the web server. 


Open a browser and point it to the test_haxe.html page. Again, the movie should come up 


after a few seconds. (…if crtmpserver and ffmpeg are still running)


将test.swf和test_haxe.html放在同一个目录并在浏览器打开网址,就可看到流了;

使用ffmpeg+crtmpserver搭建文件的伪直播的更多相关文章

  1. nginx开发(四)调用ffmpeg,搭建rtmp直播流。

    1: 修改conf文件,配置rtmp直播 打开usr/local/nginx/conf/nginx.conf,添加红色内容: rtmp {#rtmp点播配置    server {        li ...

  2. ffmpeg+nginx搭建直播服务器

    Nginx与Nginx-rtmp-module搭建RTMP视频直播和点播服务器 https://zhuanlan.zhihu.com/p/28009037 FFmpeg总结(十三)用ffmpeg基于n ...

  3. 利用crtmpserver搭建rtmp服务器

    Google + 实践:最终直播成功. 记录一下. 这样.兴许就能够对代码进行改造,利用开源码实现:Android平台下.搭建rtmpserver.浏览器端利用flash播放视频. 代码架构为:ffm ...

  4. Windows10环境下 Nginx+ffmpeg自搭服务器制作RTMP直播流

    Windows10环境下 Nginx+ffmpeg自搭服务器制作RTMP直播流学习笔记 所需条件: nginx-rtmp-module(带rtmp模块) ,链接:https://link.jiansh ...

  5. Windows10+VMware Workstation Pro+Ubuntu 16.04+Hadoop-2.6.5+IDEA环境搭建(单机&伪分布式&集群)

    (注:下面出现的"czifan"为用户名,需替换成自己的用户名) 本篇博客是在实践该篇博客的过程中的一些补充和修改~ 0 - 安装VMware Workstation Pro 首先 ...

  6. Centos7 搭建Nginx+rtmp+hls直播推流服务器

    1 准备工具 使用yum安装git [root~]# yum -y install git 下载nginx-rtmp-module,官方github地址 // 通过git clone 的方式下载到服务 ...

  7. Java使用FFmpeg处理视频文件指南

    Java使用FFmpeg处理视频文件指南 本文主要讲述如何使用Java + FFmpeg实现对视频文件的信息提取.码率压缩.分辨率转换等功能: 之前在网上浏览了一大圈Java使用FFmpeg处理音视频 ...

  8. ffmpeg处理rtmp/文件/rtsp的推流和拉流

    ffmpeg处理rtmp/文件/rtsp的推流和拉流   本demo演示了利用ffmpeg从服务器拉流或本地文件读取流,更改流url或文件类型名称发送回服务器或存到本地的作用. 由于本程序只写了3个小 ...

  9. Java使用FFmpeg处理视频文件的方法教程

    这篇文章主要给大家介绍了关于Java使用FFmpeg处理视频文件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧 前言 本文主要 ...

随机推荐

  1. canvas下载图片

    canvas下载图片 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  2. mongoDB数据库的修复

    mongoDB数据库的修复 标签: 数据库mongodbdatabasefile文档 2011-08-05 11:33 2323人阅读 评论(0) 收藏 举报  分类: 数据库技术/Cache技术/存 ...

  3. svn代码回滚和合并的利器svn merge

    1.svn merge可以将两个对象的diff体现到本地工作目录上. (1)两个对象 这个两个对象可以是同一个svn url的两个revison,也可以是不用的url,比如分支和主干. (2)diff ...

  4. 伸展树(SplayTree)的实现

    优点:伸展树(splay tree)是一种能自我调整的二叉搜索树(BST).虽然某一次的访问操作所花费的时间比较长,但是平摊(amortized) 之后的访问操作(例如旋转)时间能达到O(logn)的 ...

  5. 出现The folder is already a source folder

    右键build path -> configure build path -> source ,选择 src/main/java.src/test/java删除,然后再新建.

  6. @JsonIgnore

    @JsonIgnore 避免取JSON对象时无限递归的问题,过滤掉一些不需要的属性,说明createdDate这个属性不需要转成json,放到getter方法前生效

  7. 【原】Coursera—Andrew Ng机器学习—Week 10 习题—大规模机器学习

    [1]大规模数据 [2]随机梯度下降 [3]小批量梯度下降 [4]随机梯度下降的收敛 Answer:BD A 错误.学习率太小,算法容易很慢 B 正确.学习率小,效果更好 C 错误.应该是确定阈值吧 ...

  8. shell编程——变量子串的常用操作

    ${#字符串} 返回字符串的长度 [root@localhost ~]# a=length [root@localhost ~]# echo ${#a} 6 ${字符串:位置x} 从位置x开始往后截取 ...

  9. Apache Hive (三)Hive元数据信息对应MySQL数据库表

    转自:https://www.cnblogs.com/qingyunzong/p/8710356.html 概述 Hive 的元数据信息通常存储在关系型数据库中,常用MySQL数据库作为元数据库管理. ...

  10. 压缩包法安装mysql

    之前一直安装mysql,我一直是用压缩包安装的.如果之前安装过Mysql,必须要删除注册文件,才能把Mysql彻底删除了. 先在官网下载mysql的版本.下载package版本,即.zip版本的.下载 ...