linux下fms2流媒体服务器搭建

[转]linux下fms2流媒体服务器搭建之一-----ffmpeg安装篇

接触fms2也有一段时间了,前段时间尝试着做了个流媒体服务器玩,功能包括了视频转换(所有格式转为flv)、视频播放和视频录制,虽然不是很完美,也有很多缺陷,但是基本功能也具备了。在这里我毫无保留,把所有源码和学习体会公开,一方面,希望高手能指点一下帮我解决里面的几个问题,另一方面,也希望能对新手有一些帮助,少走弯路,里面的有部分内容并非原创,而是参考别人的资料和文档再结合自己的体会更简单更系统的表达出来。

     要使用fms2作流媒体服务器,必定要两个工具把其他格式的视频文件转换成flv,它们就是ffmpeg和mencoder, ffmpeg主要负责除了rm、rmvb和wmv9等之外的其他各种格式的转换成flv,mencoder则是把rm、rmvb和wmv9等格式转换成 flv。这里先讲ffmpeg的安装:

    必需的软件包包括:ffmpeg、lame、ogg vorbis、nasm、x264、xvid、libdts、faac、faad2、3gp

    1、ffmpeg,下载ffmpeg,解压:tar jxvf ffmpeg-checkout-20070130.tar.bz2

    2、lame,下载lame,安装:./configure --prefix=/usr --enable-shared,make,make install

    3、ogg vorbis,这个一般的redhat自带,不需要下载,可以去看看/usr/lib/libvorbis.a在不在,如果不在可以yum install或apt-get install

    4、nasm,下载nasm,安装:rpm -ivh nasm-0.98.39-1.i386.rpm

    5、x264,下载x264,安装:./configure --prefix=/usr --enable-shared,make,make install

    6、xvid ,下载xvid,安装:./configure --prefix=/usr --enable-shared,make,make install

    7、libdts,下载libdts,安装:./configure --prefix=/usr --enable-shared,make,make install

    8、faac,下载faac,安装:./configure --prefix=/usr --enable-shared,make,make install

    9、faad2,下载faad2,安装:./configure --prefix=/usr --enable-shared,make,make install

    10、3gp,包括两个包:amrwb_float下载、amr_float下载,安装:解压ffmpeg的源码包后,进入ffmpeg-checkout-20070130/libavcodec/,新建两个新目录 amrwb_float和amr_float,然后解压这两个包,把amrwb_float里面的所有文件复制到amrwb_float,把 amr_float的所有文件复制到amr_float

    现在可以开始编译安装ffmpeg了,

    ./configuration --enable-gpl --enable-shared --enable-mp3lame --enable-amr_nb --enable-amr_wb --enable-amr_if2 --enable-libogg --enable-vorbis --enable-xvid --enable-a52 --enable-a52bin --enable-faadbin --enable-dts --enable-pp --enable-faad --enable-faac --enable-x264 --enable-pthreads --disable-ffserver --disable-ffplay  --prefix=/usr  --extra-cflags=-I/local/include --extra-ldflags=-L/local/lib

    make

    make install
 

[转]linux下fms2流媒体服务器搭建之二-----mencoder安装篇

1、下载主程序: MPlayer-1.0rc1.tar.bz2

2、下载essential-20061022.tar.bz2,安装:
tar vjxf essential-20061022.tar.bz2
mv essential-20061022 /usr/lib/codes
chmod 644 /usr/lib/codes/*
chown root.root /usr/lib/codes/*

3、下载windows-essential-20061022.zip,安装:
unzip windows-essential-20061022.zip
mv windows-essential-20061022 /usr/lib/wincodes
chmod 644 /usr/lib/wincodes/*
chown root.root /usr/lib/wincodes/*

4、安装mplayer

tar vjxf MPlayer-1.0rc1.tar.bz2
cd MPlayer-1.0rc1
./configure --prefix=/usr/local/mplayer/ --enable-freetype --with-codecsdir=/usr/lib/codes/ --with-win32libdir=/usr/lib/wincodes/ --disable-gcc-check --language=zh_CN

make

make install

如果你需要使用mplayer在linux下播放视频,还需要加上--enable-gui(图形界面),不过这样就要安装多很多东西了,这里我们只使用它的mencoder,所以--enable-gui可以省略

 

[转]linux下fms2流媒体服务器搭建之三-----FMS安装篇

1、下载fms2安装程序,点击下载

2、安装:

tar zxvf FlashMediaServer2.tar.gz

cd FMS_2_0_1_r27_linux

./installFMS -platformWarnOnly

说明:-platformWarnOnly,忽略安装平台,因为有些系统会安装不了,所以这个一定要加上。执行安装程序后会有些类似于同意条款之类的东西,直接ctrl+c就得,然后需要填写一些配置,一般默认就可以,我填的是这样的:

Installation directory         = /opt/macromedia/fms //安装目录

FMS Server Port                = 1935  //服务端口
FMS Admin Server Port          = 1111 //管理端口

Administrative username        = yingzi //管理员

Administrative password        = (suppressed) //管理员密码

FMS owner                      = root

FMS service user               = root

FMS service user group         = root

FMS run as daemon              = Yes
Start FMS                      = Yes

3、启动和停止

启动:

./fmsmgr server fms start

./fmsmgr adminserver start


停止:

./fmsmgr server fms stop

./fmsmgr adminserver stop

4、序列号:

linux版的序列号都在windows版里面,下载window版,解压,把里面无限制序列号目录下的license.lic文件复制到linux版安装目录的licenses目录下,然后重启一下就可以了。

[转]linux下fms2流媒体服务器搭建之四-----格式转换篇

用fms2做流媒体服务器,就需要把所有用户上传的各种视频转换成flv格式,这种格式的文件容量很小,比较适合远程播放。用ffmpeg和mencoder已经足以把绝大部分视频转换成flv了。

    我这里是用perl调用ffmpeg和mecoder命令,java操作数据库和控制线程调用perl进行转换的。说也说不清,我还是直接拿源码来说吧:

    1、covert.pl

 #!/usr/bin/perl
my $encoder = $ARGV[0];//java传过来的参数,编码命令,如:/usr/local/ffmepg
my $fileIn = $ARGV[1];//java传过来的参数,要转换的源文件路径
my $fileOut = $ARGV[2];//java传过来的参数,转换后的文件路径
my $logPath = $ARGV[3];//java传过来的参数,日志路径
my $localTime = localtime;//当前时间
my $cmd;

my $coder = substr($encoder,rindex($encoder,"/")+1);
if($coder eq "ffmpeg"){
 $cmd = $encoder." -i ".$fileIn." -ab 64 -acodec mp3 -ac 1 -ar 22050 -b 230 -r 29.97  -y ".$fileOut;//如果转换命令是ffmpeg,调用该命令转换
}
else{//否则调用该命令用ffmpeg转换
 $cmd = $encoder." -of lavf -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -ovc lavc -lavcopts vcodec=flv:vbitrate=500 -srate 22050 -oac lavc -lavcopts acodec=mp3:abitrate=56 -ffourcc FLV1 -oac mp3lame ".$fileIn." -o ".$fileOut;
}

`echo $localTime: $cmd >> $logPath`;//把命令内容写到日志
`$cmd`;//执行转换命令

2、CovertVideo.java

ffmpeg转换flv:

public synchronized static boolean ffmpegToFlv(String fileIn, String fileOut) {
   SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
  String cmdFile = Configuration.getInstance()//从配置文件获取perl文件路径
    .getConfigValue("path.perl")
    + "covert.pl";
  String encoder = Configuration.getInstance().getConfigValue(//从配置文件获取命令行路径
    "commend.ffmpeg");
  String logPath = Configuration.getInstance().getConfigValue(//日志路径
    "stdout.path")
    + format.format(new Date()) + ".txt";
  StringBuffer cmd = new StringBuffer("/usr/bin/perl ").append(cmdFile)
    .append(" ").append(encoder).append(" ").append(fileIn).append(
      " ").append(fileOut).append(" ").append(logPath);
  System.out.print(cmd.toString());
  String line = null;
  InputStream stderr = null;
  InputStreamReader isr = null;
  BufferedReader br = null;
  Runtime rt = null;
  boolean success = false;
  try {
   rt = Runtime.getRuntime();
   Process proc = rt.exec(cmd.toString());//执行命令,调用perl进行转换
   stderr = proc.getErrorStream();
   isr = new InputStreamReader(stderr);
   br = new BufferedReader(isr);
   System.out.println("<ffmpegToFlv>");
   while ((line = br.readLine()) != null)
    System.out.println(line);
   System.out.println("</ffmpegToFlv>");
   int exitVal = proc.waitFor();
   System.out.println("Process exitValue: " + exitVal);
   File filePath = new File(fileOut);
   // 如果文件存在,并且长度不为0,则表示转换成功.
   success = filePath.exists() && filePath.length() > 0;
  } catch (Throwable t) {
   t.printStackTrace();
  } finally {
   try {
    stderr.close();
    isr.close();
    br.close();
   } catch (Exception e) {
    e.printStackTrace();
    rt.exit(1);
   }
  }
  return success;
 }

mencoder转换flv跟上面几乎一样,不写注释了:

public synchronized static boolean mencoderToFlv(String fileIn,
   String fileOut) {
  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
  String cmdFile = Configuration.getInstance()
    .getConfigValue("path.perl")
    + "covert.pl";
  String encoder = Configuration.getInstance().getConfigValue(
    "commend.mencoder");
  String logPath = Configuration.getInstance().getConfigValue(
    "stdout.path")
    + format.format(new Date()) + ".txt";
  StringBuffer cmd = new StringBuffer("/usr/bin/perl ").append(cmdFile)
    .append(" ").append(encoder).append(" ").append(fileIn).append(
      " ").append(fileOut).append(" ").append(logPath);
  System.out.print(cmd.toString());
  String line = null;
  InputStream stderr = null;
  InputStreamReader isr = null;
  BufferedReader br = null;
  Runtime rt = null;
  boolean success = false;
  try {
   rt = Runtime.getRuntime();
   Process proc = rt.exec(cmd.toString());
   stderr = proc.getErrorStream();
   isr = new InputStreamReader(stderr);
   br = new BufferedReader(isr);
   System.out.println("<mencoderToFlv>");
   while ((line = br.readLine()) != null)
    System.out.println(line);
   System.out.println("</mencoderToFlv>");
   int exitVal = proc.waitFor();
   System.out.println("Process exitValue: " + exitVal);
   File filePath = new File(fileOut);
   // 如果文件存在,并且长度不为0,则表示转换成功.
   success = filePath.exists() && filePath.length() > 0;
  } catch (Throwable t) {
   t.printStackTrace();
  } finally {
   try {
    stderr.close();
    isr.close();
    br.close();
   } catch (Exception e) {
    e.printStackTrace();
    rt.exit(1);
   }
  }
  return success;
 }

程序已经编译通过的,配置文件config.properties需要放到web服务的WEB-INF/classes目录下,只需按实际情况把配置文件里面的路径修改成你自己的就可以用了。
 

[转]linux下fms2流媒体服务器搭建之五-----flv播放器制作篇

   很多人也许苦于找不到一个稍微简单而又完整的flv播放器,我刚开始也找了很久找不到,后来干脆叫朋友帮忙做了个界面,然后自己添加代码做了个,感觉还可以,这里我不敢独享,把源码公开给各位参考一下。

    要做flv播放器,首先你要明白fms2的工作目录,它的工作目录都在安装目录的applications目录下,你需要新建一个目录作为自己的工作目录,比如我新建了gdrc,然后在gdrc里面新建一个streams目录(这个目录名不能改变),这样,在streams下的所有子目录都是你的应用了。默认是_definst_,我为了好管理自己建了video放置视频flv文件,再建audio放置音频,这样我的目录结构就是: applications/gdrc/streams/video、applications/gdrc/streams/audio、 applications/gdrc/streams/_definst_。在上一篇中提到的格式转换转换的所有flv文件就是放在 applications/streams/video目录下。

    然后,来看看我的flv播放器吧,我是用flash8开发的,只需要几个简单的组件,视频组件、播放按钮、暂停按钮、停止按钮、时间轴再加下面的代码就是一个flv播放器,在第一祯写上下面的代码:

stop();
var play_status = false;//视频播放标记,true-正在播放;false-没有播放
var connect_url = "rtmp://172.16.1.2/gdrc/video";//连接方式rtmp,注意这个连接的后面/gdrc/video跟上面提到的flv目录applications/gdrc/streams/video是对应的。
var flv = stream;//动态播放flv,该参数名对应外面的参数名比如play.swf?stream=a表示播放a.flv,参数不需要.flv后缀名
var nc:NetConnection = new NetConnection();
var ns:NetStream;
nc.connect(connect_url);
var streamLength;//flv文件长度
bt_pause._visible = false;//设置暂停按钮不可见
var startBF = 2;//开始缓冲秒数
var mainBF = 6;//空时缓冲秒数

//初始化
initStreams = function(){
 ns=new NetStream(nc);
 ns.setBufferTime(startBF);
 video.attachVideo(ns);//把ns附给video视频组件
 ns.onStatus = Onstatus;//动态缓冲
};
//动态缓冲,缓冲区满时为3秒,空的时候为10秒
function  Onstatus(infoObject:Object){
 trace(infoObject["code"]);
 if(infoObject["code"] == "NetStream.Buffer.Full"){
  ns.setBufferTime(startBF);
 }
 if(infoObject["code"] == "NetStream.Buffer.Empty"){
  ns.setBufferTime(mainBF);
 }
}

//测试连接
nc.onStatus = function(info) {
 trace(info.code);
 switch (info.code) {
  case "NetConnection.Connect.Success":initStreams();break;
 }
}

//缓冲
function checkBufferTime(ns:NetStream):Void{
    var bufferPct:Number = Math.min(Math.round(ns.bufferLength/ns.bufferTime*100), 100);
 if(isNaN(bufferPct)){
  bufferPct = 0;
 }
    buffer_txt = "缓冲:"+bufferPct+"%";;
};

//获得文件长度,这个长度的获取需要服务器端的支持,要在fms2服务器端编写main.asc,后面会给出
function FileLength() {
 this.onResult = function(retVal) {
   streamLength = retVal;
 };
};

//播放
doPlay = function(){
 if(play_status == false){
  bar.ball._x = 0;
  play_status = true;
  ns.play(flv);
  //播放进度条
  bar.onEnterFrame=function(){
   nc.call("getFileLength", new FileLength(), flv);
   var nowPlayPercent=Math.round(ns.time/streamLength*100);
   if(isNaN(nowPlayPercent)){
    bar.ball._x = 0;
   }
   else{
    bar.ball._x = nowPlayPercent*490/100;
   }
   if(nowPlayPercent==99){
    play_status = false;
    bar.ball._x = 0;
    bt_play._visible = true;
    bt_pause._visible = false;
    //ns.close();
    delete this.onEnterFrame;
   }
  };
  //缓冲提示
  var buffer_interval:Number = setInterval(checkBufferTime, 100, ns);
 }
 else{
  ns.pause();
 }
};


//暂停
doPause = function(){
 ns.pause();
};


//停止
doStop = function(){
 play_status = false;
 bar.ball._x = 0;
 //ns.seek(0);
 //ns.pause(true);
 ns.close();
};

//开始播放
playNow.onRelease=function(){
 bt_play._visible = false;
 bt_pause._visible = true;
 doPlay();
};

//播放按钮
bt_play.onRelease=function(){
 bt_play._visible = false;
 bt_pause._visible = true;
 doPlay();
};

//暂停按钮
bt_pause.onRelease=function(){
 bt_play._visible = true;
 bt_pause._visible = false;
 doPause();
};

//停止按钮
bt_stop.onRelease=function(){
 bt_play._visible = true;
 bt_pause._visible = false;
 doStop();
};

main.asc,放置到fms2安装目录的applications/gdrc目录下

load("components.asc");

application.onAppStart = function() {};
application.onConnect = function(client) {
 application.acceptConnection(client);
 client.getFileLength = function(filename) {
  var tlen = Stream.length(filename);
  return tlen;
 };
 };

你可能感兴趣的:(linux下fms2流媒体服务器搭建)