加载中…
个人资料
南冠彤
南冠彤
  • 博客等级:
  • 博客积分:0
  • 博客访问:411,815
  • 关注人气:59
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

[转载]转:ffserver和ffmpeg配合完成的实时流媒体服务

(2013-08-05 09:51:03)
标签:

转载

分类: 音视频

ffmpeg和ffserver配合使用可以实现实时的流媒体服务,这里实时的数据来自摄像头,如果考虑到应用程序和网络状况,这里客户端看到的画面还是会落后与摄像头本地获取的画面,最糟糕时甚至看不到画面(扯远了),这里我们关注的是ffmpeg和ffserver之间是如何配合工作的,了解了他们之间的关系,对个别问题也能有的放矢。

ffserver先于ffmpeg启动,它在启动的时候需要加参数-f指定其配置文件,配置文件里包含有向客户端传送的流的配置(如编码方式,帧率,采样率……),也有对feed1.ffm的配置,还有其他的一些配置。feed1.ffm是什么?这里可以理解为一个缓冲文件,下面会提到它是如何被用到,ffserver启动后,feed1.ffm就会被创建,这时如果你打开feed1.ffm看看,会发现feed1.ffm开始的部分已经写入了内容,你可以找到关键字ffm以及向客户端传送流的配置信息,在feed1.ffm做缓冲用的时候,这些信息是不会被覆盖掉的,就把它们理解为feed1.ffm文件的头吧。

ffserver启动后,ffmpeg启动,它启动时加的一个关键参数就是“http://ip:8090/feed1.ffm”,其中ip是运行ffserver主机的ip,如果ffmpeg和ffserver都在同一系统中运行的话,用localhost也行。ffmpeg启动后会与ffserver建立一个连接(短暂的连接),通过这第一次的连接,ffmpeg从ffserver那里获取了向客户端输出流的配置,并把这些配置作为自己编码输出的配置,然后ffmpeg断开了这次连接,再次与ffserver建立连接(长久的连接),利用这个连接ffmpeg会把编码后的数据发送给ffserver。如果你观察ffserver端的输出就会发现这段时间会出现两次HTTP的200,这就是两次连接的过程。

ffmpeg从摄像头获取数据后,按照输出流的编码方式编码,然后发送给ffserver,ffserver收到ffmpeg的数据后,如果网络上没有播放的请求,就把数据写入feed1.ffm中缓存,写入时把数据加上些头信息然后分块,每块4096B(每块也有结构),当feed1.ffm的大小到了ffserver.conf中规定的大小后,就会从文件开始(跳过头)写入,覆盖旧的数据。直到网络上有播放的请求,ffserver从feed1.ffm中读取数据,发送给客户端。

上面粗略的描述在实时流媒体服务时ffmpeg和ffserver的关系,这些看法都是在阅读较早FFmpeg代码(very old)时得出的,现在不知这个架构是否改变,兄弟我把砖扔出,希望大家用玉来砸。

4

路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (12 个评论)

  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    李海宁 2009-03-01 19:36
    非常感谢大虾精辟的分析。小弟最近正在看FFserver的源代码,看的有点头大,有问题想请教一下。
    我采用的是H.264的编码器,我阅读output_example后发现编码后的数据格式应该是绑定到AVpacket格式上,我想问一下,ffserver是对什么数据格式进行rtp打包的,是直接对编码后的缓存数据打包,还是对AVpacket数据进行rtp打包?
    希望大哥能予以指点。[转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    王李乐 2009-03-02 13:38
    我理解你这里说的缓存数据是feed1.ffm中的数据,那么发出去的时候应该是从这里取数据的,可以这样理解,一帧解码后的数据被在缓冲的时候,被拆分成一块一块(4096)的存放在feed1.ffm中,在要发送的时候,就把这一块一块的数据拼装起来,还原为一帧解码后的数据,交由AVpacket->data指向,再看要以什么样的格式发给客户端,比如你这里说的RTP,再把数据按照RTP格式打包,发送给客户端。
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    李海宁 2009-03-02 16:25
    王李乐: 我理解你这里说的缓存数据是feed1.ffm中的数据,那么发出去的时候应该是从这里取数据的,可以这样理解,一帧解码后的数据被在缓冲的时候,被拆分成一块一块(40
    看到你的回复太高兴了,非常感谢[转载]转:ffserver和ffmpeg配合完成的实时流媒体服务我还是有点不明白,还得再麻烦一下
    FFmpeg中的编码函数应该是
    out_size = avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,const AVFrame *pict);
    这时编码后的数据放在buf里,我想问一下这时buf里的数据是不是应该是由一个一个的NALUnit组成的?
    如果是,我查看内存映像时发现只有最头的数据是0x000001,以后的就都是普通数据了,也就是说,我编码后的数据好像就只有一个NALUnit,但是我的输入数据pict是一帧图像(摄像头采集到的一帧图像)应该由许多NALUnit组成啊,我想问一下这是什么原因?是编码的参数没设置对吗?
    因为我想对每一个NALUnit打包,如果是现在这种情况:每一个包是一帧数据,传输时也许会有很大的问题,麻烦您了![转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    王李乐 2009-03-02 17:02
    李海宁: 看到你的回复太高兴了,非常感谢[转载]转:ffserver和ffmpeg配合完成的实时流媒体服务我还是有点不明白,还得再麻烦一下
    FFmpeg中的编码函数应该是
    out_size = avcodec_encode_video(AVCodecContext *avctx
    抱歉,这个我也不太清楚,你可以请教下admin,或是到论坛或群里问问。
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    李海宁 2009-03-02 18:15
    王李乐: 抱歉,这个我也不太清楚,你可以请教下admin,或是到论坛或群里问问。
    恩,好的,还是非常感谢您[转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    李海宁 2009-03-05 21:11
    我想请问一下,FFmpeg有没有做接收端?
    服务器端用FFserver+FFmpeg,那么接收端应该用什么接收呢?
    除了VLC,我想问一下FFmpeg自己的接收端有类似FFserver的例程吗?
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    李海宁 2009-03-05 21:18
    呵呵,好像FFplay就是可以做客户端吗?
    FFplay可以接收网络来的rtp包吗?然后自己解码调用SDL显示,是这样吗?
    谢谢王李乐[转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    王李乐 2009-03-06 08:27
    李海宁: 呵呵,好像FFplay就是可以做客户端吗?
    FFplay可以接收网络来的rtp包吗?然后自己解码调用SDL显示,是这样吗?
    谢谢王李乐[转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    ffplay要播放从ffserver来的RTSP/RTP流的话,可能要改代码了,不知道现在最新的ffplay能否直接播,就是类似ffplay rtsp://ip:5454/file这种形式,你可以试试。
    我原来试过ffmpeg编码后的数据直接通过RTP发给客户端,不经过ffserver,就是在服务端:
    ffmpeg -参数 ... rtp://client_ip:client_port?localport=server_port
    这样的形式,客户端用ffplay接收的时候类似于:
    ffplay rtp://server_ip:server_port?localport=client_port
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    李海宁 2009-03-06 11:49
    恩,好的,明白了,谢谢大牛[转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    张磊 2009-04-23 22:14
    你好!
    我使用ffserver命令启动服务器
    然后用ffmpeg -i bj.3gp -f flv http:localhost:8090/feed1.ffm
    在RealPlayer和VLC上都可以正确显示页面
    但却无法正常播放请问您知道怎么解决吗?
    ffserver用的是源码自带的ffserver .conf 谢谢!~
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    王李乐 2009-04-27 10:12
    张磊: 你好!
    我使用ffserver命令启动服务器
    然后用ffmpeg -i bj.3gp -f flv http:localhost:8090/feed1.ffm
    在RealPlayer和VLC上都可以正确显示页面
    但却无法正常播放
    什么叫正常显示页面,无法正常播放?
    客户端请求的URL是什么?
    是否是3gp已经转换完但客户端的请求还未到?
  • [转载]转:ffserver和ffmpeg配合完成的实时流媒体服务
    张磊 2009-04-29 09:51
    在realplay中  输入http://192.168.0.190:8090/stat.html 可以显示
    FFServer Status
    Available Streams
    Path Served
    Conns
    bytes Format Bit rate
    kbits/s Video
    kbits/s
    Codec Audio
    kbits/s
    Codec Feed  
    test1.mpg   63  mpeg  96  64  mpeg1video  32  mp2  feed1.ffm  
    test.asf  3960  3094k asf_stream  320  256  msmpeg4  64  libmp3lame  feed1.ffm  
    stat.html   2142        
    index.html          

    Feed feed1.ffm
    Stream type kbits/s codec Parameters  
    0 audio 32 mp2 1 channel(s), 44100 Hz  
    1 video 64 mpeg1video 160x128, q=3-31, fps=3  
    2 audio 64 libmp3lame 1 channel(s), 22050 Hz  
    3 video 256 msmpeg4 352x240, q=3-31, fps=15  

    Connection Status
    Number of connections: 1 / 1000
    Bandwidth in use: 0k / 1000k
    # File IP Proto State Target bits/sec Actual bits/sec Bytes transferred  
    1 stat.html 192.168.0.95 HTTP/1.1 HTTP_WAIT_REQUEST 0    

    --------------------------------------------------------------------------------
    Generated at Wed Apr 29 09:41:07 2009
    然而页面中的test1.mpg和test.asf都无法播放
    甚至在播放栏点选的时候 迅雷自动启动 默认要下载test.asf和test1.mpg

    而在VLC中输入192.168.0.190:8090/test.asf  或者192.168.0.190:8090/test1.mpg则一直显示连接状态 超时 则弹出 您的输入无法被打开。。。
    3gp转换和客户端的打开顺序应该是如何的呢?我这里不管是先转换还是先打开客户端似乎都不能正确播放

0

  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有