zoukankan      html  css  js  c++  java
  • ffmpeg+ffserver搭建流媒体服务器

    http://blog.chinaunix.net/uid-9688646-id-3399113.html

    ffmpeg和ffserver配合使用可以实现实时的流媒体服务。
     
    一、理解
    里边主要有如下四个东西,搞清楚他们之间的关系就差不多明白了。
    1. ffmpeg
     
    2. ffserver
     
    3. ffserver.conf
     
    4. feed1.ffm
     
     
    1. ffmpeg,负责媒体文件的transcode工作,把你服务器上的源媒体文件转换成要发送出去的流媒体文件。
     
    2. ffserver,负责响应客户端的流媒体请求,把流媒体数据发送给客户端。
     
    3. ffserver.conf,ffserver启动时的配置文件,在这个文件中主要是对网络协议,缓存文件feed1.ffm(见下述)和要发送的流媒体文件的格式参数做具体的设定。
     
    4. feed1.ffm,可以看成是一个流媒体数据的缓存文件,ffmpeg把转码好的数据发送给ffserver,如果没有客户端连接请求,ffserver把数据缓存到该文件中。
     
     
    二、http的建立流程
    1. 配置ffserver.conf文件(初次接触可以参考ffmpeg源码中的doc/ffserver.conf,里边有详细的注释)
    如下写一个示例
    Port 10535
    RTSPPort 5454
    BindAddress 0.0.0.0、
    MaxHTTPConnections 2000
    MaxClients 1000
    MaxBandwidth 1000
    CustomLog -
    NoDaemon
     
    #实时流数据配置(参考源码ffmpeg/test/下的ffserver.conf)
    <Feed feed1.ffm>
    File /tmp/feed1.ffm
    FileMaxSize 1M
    ACL allow 127.0.0.1
    </Feed>
     
    <Stream test.avi>
    Feed feed1.ffm
    Format avi
    #
    BitExact
    DctFastint
    IdctSimple
    VideoFrameRate 10
    VideoSize 352x288
    VideoBitRate 100
    VideoGopSize 30
    NoAudio
     
    PreRoll 10
    StartSendOnKey
    MaxTime 100
     
    </Stream>
     
    #已经存在的文件而非实时流
     
    <Stream test.flv>
    File "/project/apps/ffserver/test.flv"
    Format flv
    </Stream>
     
     
    2、如何实现播放
    (1)实时流用http传输
    如果传输硬盘上的文件,则:
    ffserver -f myfile/ffmpeg0.8.9/ffserver.conf & ffmpeg -i inputfile(输入文件) http://localhost:10535/feed1.ffm
    如何传输摄像头捕获的实时流,则:
    ffserver -f myfile/ffmpeg0.8.9/ffserver.conf & ffmpeg -f video4linux2 -framerate 30 -i /dev/video0 http://127.0.0.1:8090/feed1.ffm
     
    启动ffserver和ffmpeg。ffserver先于ffmpeg启动,它在启动的时候需要加参数-f指定其配置文件。ffserver启动后,feed1.ffm就会被创建,这时如果你打开feed1.ffm看看,会发现feed1.ffm开始的部分已经写入了内 容,你可以找到关键字ffm以及向客户端传送流的配置信息,在feed1.ffm做缓冲用的时候,这些信息是不会被覆盖掉的,就把它们理解为 feed1.ffm文件的头吧。
     
    ffserver启动后,ffmpeg启动,它启动时加的一个关键参数就是“http://ip:10535/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中读取数据,发送给客户端。
     
    (2)本地文件用http传输
    ffserver -f /etc/ffserver.conf
    用命令启动ffserver,然后用ffplay http://ip:port/test.flv,或者在vlc中输入以上网址也可实现播放。
     
    (3)本地文件用rtsp传输
    ffserver -f /etc/ffserver.conf
    用命令启动ffserver,然后用ffplay rtsp://ip:port/rtsp.mpg,或者在vlc中输入以上网址也可实现播放。
    备注:在做测试的时候,用rtsp不能传输flv文件。
     
     
     
     
     
     
    相关错误:
    http://localhost:8090/test.asf: Invalid data found when processing input

    Error occurs when I transcode a file into asf format

    http://ffmpeg.gusari.org/viewtopic.php?f=11&t=590

    You can't stream avi file format, it's not designed to be streamed, rather to be used as a file/storage format. Streaming formats are: flv, mpegts, asf, rtmp/rtp/rtsp... So, try changing Format avi to Format mpegts and see if that works. But, the most convenient way of using ffmpeg/ffserver is to create a config file for ffserver and then run ffmpeg, telling it to feed the ffserver, which will do the actual encoding and streaming.

    ffmpeg与ffserver的协同工作

    http://blog.csdn.net/shendan00/article/details/18839837

    工作流程如下:

    1、 启动ffserver,配置参数

    ffserver先于ffmpeg启动,它在启动的时候需要加参数-f指定其配置文件,配置文件里包含端口信息、缓冲文件配置、传送流配置(如编码方式,帧率,采样率……)。

    2、 启动ffmpeg,输入流

        启动ffmpeg,向缓冲文件输入数据流,数据流可以来自摄像头,也可以来自本来就存在的文件。

    feed1.ffm是一个缓冲文件,fserver启动后,feed1.ffm就会自动被创建,feed1.ffm开始的部分已经写入向客户端传送流的配置信息,在feed1.ffm做缓冲用的时候,这些信息是不会被覆盖掉。

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

    3、连接过程

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

    带有缓冲的数据流图如下
    ffserver用法小结 - yjlyp - 龙
     
     
     
     
     
    我的配置(注意:asf文件播放不了)
     
    Port 8090
    RTSPPort 8091
    BindAddress 0.0.0.0
    MaxHTTPConnections 2000
    MaxClients 1000
    MaxBandwidth 1000
    CustomLog -

    <Feed feed1.ffm>
    #File /tmp/feed1.ffm
    File "/home/yingc/gcyin/test/thirdparty/output/ffmpeg/bin/feed1.ffm"
    FileMaxSize 20000000K
    ACL allow 127.0.0.1
    </Feed>

    #<Stream test.ts>
    #Feed feed1.ffm
    #Format mpegts
    #
    #AudioCodec libmp3lame
    #AudioBitRate 128
    #AudioChannels 2
    #AudioSampleRate 44100
    #AVOptionAudio flags +global_header
    #
    #VideoBitRate 800
    #VideoFrameRate 25
    #VideoSize 640x480
    #VideoCodec libx264
    #AVOptionVideo flags +global_header
    #</Stream>
    #
    #<Stream test.asf>
    #Feed feed1.ffm
    #Format asf
    #
    #AudioCodec aac
    #AudioBitRate 128
    #AudioChannels 2
    #AudioSampleRate 44100
    #AVOptionAudio flags +global_header
    #
    #VideoBitRate 800
    #VideoFrameRate 25
    #VideoSize 640x480
    #VideoCodec libx264
    #AVOptionVideo flags +global_header
    #</Stream>


    <Stream test.ts>
    Feed feed1.ffm
    Format mpegts
    </Stream>
    <Stream test.avi>
    Feed feed1.ffm
    Format avi
    </Stream>
    <Stream test.flv>
    Feed feed1.ffm
    Format flv
    </Stream>
    <Stream test.mp4>
    Format rtp
    File "/home/yingc/gcyin/test/thirdparty/output/ffmpeg/bin/h.mp4"
    </Stream>
    <Stream test.asf>
    Feed feed1.ffm
    Format asf
    </Stream>

    <Stream stat.html>
    Format status

    # Only allow local people to get the status
    ACL allow localhost
    ACL allow 192.168.110.0 192.168.110.255
    </Stream>

    # Redirect index.html to the appropriate site
    <Redirect index.html>
    URL http://www.ffmpeg.org/
    </Redirect>

     
     
    ./ffmpeg -i "http://122.228.84.235/d44bff3d000002EE-1400405760-3078718192/data4/vhotlx.video.qq.com/flv/173/5/p0014s3d4pb.p201.1.mp4?vkey=06C6236D18A183017BF4076DC2CCD118E4A6DCC28BAB7ECA53A48918D7D3732A6379C03F1EC5CB6FE7C901CA66638EFDB3E01647C335E225hostname=122.228.84.235" http://localhost:8090/feed1.ffm
     
     
     
    ./ffmpeg -i h.mp4 http://localhost:8090/feed1.ffm
     
     
     
    ./ffplay  http://localhost:8090/test.flv
     
    ./ffplay  rtsp://localhost:8091/test.flv
     
  • 相关阅读:
    【BZOJ4009】[HNOI2015]接水果 DFS序+整体二分+扫描线+树状数组
    【BZOJ4010】[HNOI2015]菜肴制作 拓扑排序
    【BZOJ4028】[HEOI2015]公约数数列 分块
    有道云笔记配合MPic+七牛云 自制MarkDown文档图床(适用Typora)
    Python面试题之Python反射机制
    Python爬虫学习笔记之爬虫基础库
    Django学习笔记之Django Form表单详解
    Django学习笔记之Django的url反向解析
    SQL学习笔记之SQL中INNER、LEFT、RIGHT JOIN的区别和用法详解
    SQL学习笔记之MySQL中真假“utf8” 问题
  • 原文地址:https://www.cnblogs.com/jingzhishen/p/3735314.html
Copyright © 2011-2022 走看看