리눅스 (RHEL5) 기반 VOD 동영상 Streaming 서비스 환경 구축 하기

리눅스 (RHEL5) 기반  VOD 동영상 Streaming 서비스 환경 구축 하기

작성자 : 서진우(
alang@syszone.co.kr)
작성일 : 2010년 8월 10일



 



본 문서는 그동안 테스트해온 다양한 기술을 이용하여 리눅스 운영체제 환경에서
동영상을 스트리밍 가능한 파일 형태로 인코딩하고, 인코딩된 파일을 이용하여 실제
웹 서비스 환경에서 VOD 서비스를 구현하는 방법을 설명한 문서이다.


오랜 출장 속에 우리 이쁜 예진이를 보고 싶은 마음에 시작한 연구 결과를
같은 처지에 있는 여러 친구 동료들을 위해 공개합니다.






1. 설치 환경 준비 하기


우선 RHEL5 환경에서 encoding 서비스를 위해 필요한 패키지를 설치할 수 있도록 YUM
환경을 구성한다.


yum package install – RHEL5 에서 Centos5 Yum 저장소 이용하기


# yum -y install yum-priorities
# rpm -Uvh
http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm


# vi /etc/yum.repos.d/centos.repo
—————————————————-



[base-be]
name=CentOS-5 – Base
#repo=os
baseurl=http://mirror.centos.org/centos/5.2/os/x86_64/
enabled=1
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/5.2/os/x86_64/RPM-GPG-KEY-CentOS-5


[updates-be]
name=CentOS-5 – Updates
baseurl=http://mirror.centos.org/centos/5.2/updates/x86_64/
enable=1
gpgcheck=1


[centosplus-be]
name=CentOS-5 – Plus
baseurl=http://mirror.centos.org/centos/5.2/centosplus/x86_64/
enabled=1
gpgcheck=1


[addons-be]
name=CentOS-5 – Addons
baseurl=http://mirror.centos.org/centos/5.2/addons/x86_64/
enable=1
gpgcheck=1


[extras-be]
name=CentOS-5 – Extras
baseurl=http://mirror.centos.org/centos/5.2/extras/x86_64/
enable=1
gpgcheck=1


[fasttrack-be]
name=CentOS-5 – Fasttrack
baseurl=http://mirror.centos.org/centos/5.2/fasttrack/x86_64/
enabled=1
gpgcheck=1


————————————————————-


# yum -y install yum-priorities
# yum -y install yum
# yum -y install yum-utils




2. FFMPEG로 인코딩 환경 구축하기 



– 기본 프로그램 설치


# yum install ruby
# yum install ncurses-devel*
# yum install lame
# yum install libogg
# yum install libvorbis
# yum install flvtool2
# yum install ffmpeg


– 코덱 설치


# wget http://www3.mplayerhq.hu/MPlayer/releases/codecs/essential-20061022.tar.bz2
# bunzip2 essential-20061022.tar.bz2
# tar xvf essential-20061022.tar
# mkdir /usr/local/lib/codecs/
# mv essential-20061022/* /usr/local/lib/codecs/
# chmod -R 755 /usr/local/lib/codecs/


# vi /etc/ld.so.conf
# ldconfig


3. ffmpeg 기본 사용법


AVI -> FLV


# ffmpeg -i onestar.avi -ar 22050 -ab 32 -f flv -s 640×480 onestar.flv | flvtool2 -U stdin onestar.flv


-i             : input file name
-ar          : audio sampling rate in HZ
-ab          : audio bit rate in kbit/s
-f             : output format
-s             : output dimension


FLV -> JPG


# ffmpeg -i test.flv -an -r 1 -y -s 640×480 test%d.jpg


-i             : input file name
-an         : disable audio
-r            : fps
-y           : overwrite file
-s            : output dimension


Particular frame to JPG


# ffmpeg -i test.flv -an -ss 00:00:10 -t 00:00:01 -r 1 -y -s 640×480 test%d.jpg


-ss          : recored start time
-t            : record end time last for


– ffmpeg 실무 사용법


ffmpeg를 이용하여 avi 파일을 flv로 변환 한다.


# ffmpeg -i onestar.avi -b 512k -ar 22050 -ab 128k -r 24 -s 400×300 onestar.flv
 
or


# ffmpeg -i “onestar.avi” -vcodec flv -f flv -r 29.97 -s 400×300 -aspect 4:3 -b 320k -g 160 -cmp 2 -subcmp 2 -mbd 2 -flags +aic+cbp+mv0+mv4+trell -ac 1 -ar 22050 -ab 128k “onestar.flv”


– FLV에 메타데이터 넣기 (스트리밍 보기-중간 구간 바로 보기)


# flvtool2 -U onstar.flv


– 동영상 썸네일 만들기


# ffmpeg -y -i onestar.avi -vframes 1 -ss 00:00:02 -an -vcodec png -f rawvideo -s 400×300 onestar.png


# ffmpeg  -itsoffset -4  -i test.avi -vcodec mjpeg -vframes 1 -an -f rawvideo -s 320×240 test.jpg


4. mencoder를 이용한 동영상에 자막 넣기


동영상을 flv 로 변환할때 자막을 같이 넣을 경우 기존의 ffmpeg로는 자막 포함 기능이
제공되지 않는다. 자막을 포함하여 인코딩을 할 수 있는 프로그램으로 mencoder이 있다.
설치는 yum으로 쉽게 가능하다.


# yum install mencoder


설치 후 자막의 언어 설정을 아래와 같이 한다.


$ vi ~/.mplayer/mencoder.conf
————————————————————————-


font=”/usr/share/fonts/korean/TrueType/gulim.ttf”
subfont-text-scale=3
subcp=cp949

————————————————————————-


이제 mencoder로 자막을 포함해서 인코딩을 한다.


$ mencoder -noodml [avi파일]  -o [flv파일]  -sub $1.smi -of lavf -oac mp3lame -lameopts abr:br=128 -ovc lavc -lavcopts vcodec=flv:vbitrate=512:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -srate 44100 -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -vf-add scale=400:300



5. Web Streaming 을 위한 Player 연동하기


– 웹 FLV_Player 연동하기


웹에서 FLV 파일을 스트리밍으로 볼수 있는 Player는 여러가지가 있다.


* UCCUP에서 제공하는 Player – http://www.uccup.kr
* http://flowplayer.org/download.html
* GRZ_JWMediaPlayer


– UCCUP Player 연동하기


아래 구문중 flv 파일명과 png 파일명을 수정 후 HTML 문서에 붙여 넣는다.
flv,png 파일은 [UCCUP설치경로]/SERVICE 디렉토리 밑에 복사해 둔다.


<embed src=”http://syszone.co.kr/uccup/UCCUp.swf?file=http://syszone.co.kr/uccup/file.php?f=onestar.flv&previewImage=http://syszone.co.kr/uccup/file.php?f=onestar.png&bufferTime=3&bgColor=-1
width=”400″ height=”300″ scale=”noscale” bgcolor=”#ffffff” type=”application/x-shockwave-flash” allowFullScreen=”true”
allowScriptAccess=”always” allowNetworking=”all” pluginspage=”
http://www.macromedia.com/go/getflashplayer“>
</embed>

 


– GRZ_JWMediaPlayer 연동하기


아래는 textcube의 플러그인으로 연동된 GRZ_JWMediaPlayer를 이용하는 방법이다.




<object classid=”clsid:d27cdb6e-ae6d-11cf-96b8-444553540000″ codebase=”http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0” width=”425″ height=”340″>
<param name=”movie” value=”/plugins/GRZ_JWMediaPlayer/mediaplayer.swf”/>
<param name=”allowfullscreen” value=”true”/>
<param name=”wmode” value=”transparent”/>
<param name=”flashvars” value=”width=425&height=340&thumbsinplaylist=true&displayheight=320&overstretch=true&logo=&searchbar=false&linkfromdisplay=true&linktarget=_blank&file=/plugins/GRZ_JWMediaPlayer/mkpl.php?list=1|%5bhttp%5dblog.syszone.co.kr%2fattach%2f1%2f1466599573.flv|alang.flv+%289.64+MB%29|||||%5bhttp%5dblog.syszone.co.kr|”/>
<!–[if !IE]> <–>
<object type=”application/x-shockwave-flash” transparent=”yes” data=”/plugins/GRZ_JWMediaPlayer/mediaplayer.swf” flashvars=”thumbsinplaylist=true&displayheight=320&overstretch=true&logo=&searchbar=false&linkfromdisplay=true&linktarget=_blank&file=/plugins/GRZ_JWMediaPlayer/mkpl.php?list=1|%5bhttp%5dblog.syszone.co.kr%2fattach%2f1%2f1466599573.flv|alang.flv+%289.64+MB%29|||||%5bhttp%5dblog.syszone.co.kr|” width=”425″ height=”340″>
<p>
<a href=”/plugins/GRZ_JWMediaPlayer/mediaplayer.swf”>[Flash]</a></p>
</object>
<!–> <![endif]–>


</object>


– FlowPlayer 연동하기


기본 연동법
————————————————————————————



<object type=”application/x-shockwave-flash” data=”[your site]/FlowPlayer.swf”
width=”320″ height=”263″ id=”FlowPlayer”>


  <param name=”allowScriptAccess” value=”sameDomain”/>
  <param name=”movie” value=”[your site]/FlowPlayer.swf”/>
  <param name=”quality” value=”high”/>
  <param name=”scale” value=”noScale”/>
  <param name=”wmode” value=”transparent”/>
  <param name=”flashvars” value=”baseURL=[base URL]&amp;videoFile=movie.flv
  &amp;autoPlay=false&amp;loop=false&amp;autoBuffering=false
  &amp;splashImageFile=movie.png”/>
</object>


————————————————————————————–
or
————————————————————————————–



<script type=”text/javascript” src=”flowplayer-3.0.2.min.js”></script>
<script>
flowplayer(“player”, “./flowplayer-3.0.2.swf”);


</script>


<a href=”http://syszone.co.kr/yaejin/data/11.flv” style=”display:block;width:400px;height:300px” id=”player”>


</a>


————————————————————————————–
or
————————————————————————————–



<script type=”text/javascript” src=”flowplayer-3.0.2.min.js”></script>
<script>
flowplayer(“player”, “./flowplayer-3.0.2.swf”, {
    clip: {
        url: ‘http://syszone.co.kr/yaejin/data/11.flv’,
        autoPlay: false,



        onStart: function(clip) {
            pageTracker._trackPageview(“configuration demo: ” + clip.url);
        }
    }



});


</script>


<a href=”http://syszone.co.kr/yaejin/data/11.flv” style=”display:block;width:400px;height:300px” id=”player”>
<img src=”
http://syszone.co.kr/yaejin/data/11.png” border=0 alt=”Play this video” />
</a>
—————————————————————————————
or (youtube 방식의 동영상 라이브러리 구현)
—————————————————————————————
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
        “
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>



<c:if test=”true”>
<!– include desired tools –>
<script src=”
http://syszone.co.kr/yaejin/jquery.min.js”></script>
<script src=”
http://syszone.co.kr/yaejin/flowplayer-3.0.2.min.js”></script>
</c:if>
<script src=”
http://syszone.co.kr/yaejin/flowplayer.playlist-3.0.1.min.js”></script>


<!– player / playlist styling –>
<style>
/* player style */
/* container has a background image */
a.player {
        margin-top:40px;
        display:block;
        background:url(
http://syszone.co.kr/yaejin/img/splash.png) no-repeat;
        width:425px;
        height:298px;
        padding:0 126px 75px 127px;
        text-align:center;
        color:#fff;
        text-decoration:none;
        cursor:pointer;
}


/* splash image */
a.player img {
        margin-top:115px;
        border:0;
}



#player {
        float:left;
}


/* playlist style */
#playlist {
        width:300px;
        height:380px;
        overflow-y:auto;
        overflow-x:hidden;
        border:1px solid #ccc;
        padding:4px 10px 12px 10px;
        background-color:#efefef;
        margin-top:20px;
        float:left;
}


/* playlist entry */
#playlist a {
        display:block;
        width:260px;
        height:60px;
        padding:7px;
        background-color:#fff;
        border:1px solid #ccc;
        font:11px “bitstream vera sans”, “lucida grande”,verdana;
        text-decoration:none;
        margin-top:7px;
        color:#666;
}


/* different states of a playlist entry */
#playlist a:hover {
        background-color:#ffc;
}


#playlist a.progress {
        background-color:#efefef;
}


#playlist a.playing {
        border:1px solid #666;
        background-color:#ffc;
}


#playlist a.paused {
        border:1px solid #666;
        background-color:#ffc;
}


/* elements inside playlist entry */
#playlist a img {
        border:0;
        float:left;
        margin-right:10px;
}


#playlist a strong {
        color:blue;
        padding-bottom:5px;
}


#playlist a em {
        border:0;   
        float:left;
        margin-right:10px;
        background:url(
http://syszone.co.kr/yaejin/img/clock.gif) no-repeat 0 50%;
        padding-left:20px;
        color:#333;
        font-style:normal;
        margin-top:10px;
}


</style>



<!– javascript setup. pretty simple stuff –>
<script>
$(function() {


        // setup player
        $f(“player”, “flowplayer-3.0.2.swf”, {


                clip: {baseUrl: ‘http://syszone.co.kr/yaejin/data’}


        // playlist plugin
        }).playlist(“#playlist”);


});
</script>



<!– player container –>
<a id=”player” class=”player plain”>
        <img src=”
http://syszone.co.kr/yaejin/img/play.png” />
</a>


<!– the playlist. simple HTML controlled with CSS –>


<div id=”playlist”>


<a href=071202-탄생1.flv>
<img src=http://syszone.co.kr/yaejin/data/071202-탄생1.png />
<strong>071202-탄생1</strong><br /><br>
</a>


<a href=071202-탄생2.flv>
<img src=http://syszone.co.kr/yaejin/data/071202-탄생2.png />
<strong>071202-탄생2</strong><br /><br>
</a>


.
.
</div>
<!– let the rest of the page float normally –>
<br clear=”all” />


————————————————————————————



6. Encoding 관련 스크립트 제작


ffmpeg를 이용하여 avi 파일을 flv로 변환하는 스크립트


# vi /usr/bin/ffmpeg_encoder.sh [filename] [geometry]
———————————————————————————–



#!/bin/sh


if [ $# -lt 2 ]
then
echo -n “using : ffmpeg_encoder.sh <filename> <geometry> ( movie 400×300 )
“;


exit;
fi


ffmpeg -i $1.avi -b 512k -ar 22050 -r 24 -ab 128k -s $2 $1.flv
ffmpeg -y -i $1.avi -vframes 1 -ss 00:00:02 -an -vcodec png -f rawvideo -s $2 $1.jpg
flvtool2 -U $1.flv
echo -n “——————————————————–
$1.avi completed $1.flv to encoding..!!
——————————————————–
“;


———————————————————————————-


mencoder를 이용하여 avi파일과 smi 자막파일을 flv 파일로 변환하는 스크립트


# vi /usr/bin/mencoder_encoder.sh
———————————————————————————-



#!/bin/sh
if [ $# -lt 3 ]
then
echo -n “using : mencoder_encoder.sh <filename> <x_geometry> <y_geometry> <avi,mkv,flv> ( movie 400 300 avi )
“;
exit;


fi


mencoder -noodml ${1}.${4} -o $1.flv -sub $1.smi -of lavf -oac mp3lame -lameopts abr:br=128 -ovc lavc -lavcopts vcodec=flv:vbitrate=512:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -srate 44100 i_certify_that_my_video_stream_does_not_use_b_frames -vf-add scale=${2}:${3}
ffmpeg -y -i ${1}.${4} -vframes 1 -ss 00:00:02 -an -vcodec png -f rawvideo -s ${2}x${3} $1.jpg
flvtool2 -U $1.flv
echo -n “——————————————————–
$1.avi completed $1.flv to encoding..!!
——————————————————–
“;


———————————————————————————


디렉토리내 flv 파일을 UCCUP Player에서 인식할 수 있는 HTML 코드로 변환하는 스크립트


# vi /usr/bin/convert_flvhtml.sh
——————————————————————————–



#!/bin/sh


rm -f source.html
ls -1 *.flv | sed -e ‘s/\.flv//g’ > filelist


A=`cat filelist`


for B in `echo $A`
do


echo -n “
<embed src=\”
http://syszone.co.kr/uccup/UCCUp.swf?file=http://syszone.co.kr/uccup/file.php?f=${B}.flv&previewImage=http://syszone.co.kr/uccup/file.php?f=${B}.jpg&bufferTime=3&bgColor=-1\
width=400 height=300 scale=noscale bgcolor=#ffffff type=application/x-shockwave-flash allowFullScreen=true
allowScriptAccess=always allowNetworking=all pluginspage=http://www.macromedia.com/go/getflashplayer>
</embed>
<p>
” >> source.html


done


———————————————————————————


AnyCall 핸드폰에서 볼수 있는 형태의 mp4 동영상으로 encoding 시켜 주는 스크립트


# vi /usr/bin/ffmpeg_encoder_mp4.sh
———————————————————————————



#!/bin/sh


if [ $# -lt 1 ]
then
echo -n “using : ffmpeg_encoder.sh <filename> <quality=low,high>>
“;


exit;
fi


if [ $2 == “high” ]
then


ffmpeg -i “${1}.avi” -vcodec mpeg4 -acodec libfaac -b 672k -ab 96k -ar 24000 -s 480×272 -aspect 16:9 -g 300  -mbd 2 -cmp 3 -precmp 3 -subcmp 3 -trellis 2 -flags +4mv -pass 1 -f psp -threads 2 “${1}.mp4”


else


ffmpeg -i “${1}.avi” -vcodec mpeg4 -acodec libfaac -b 250k -ab 96k -ar 24000 -s 480×272 -aspect 16:9 -g 300  -mbd 2 -cmp 3 -precmp 3 -subcmp 3 -trellis 2 -flags +4mv -pass 1 -f psp -threads $2 “${1}.mp4”



fi


echo -n “——————————————————–
$1.avi completed $1.mp4 to encoding..!!
——————————————————–
“;


———————————————————————————–



7. FFmpeg 와 Flv Player를 이용한 Web Streaming 서비스 환경 구축 하기


지금까지 설명한 기술 내용으로 일반 동영상 파일을 웹 환경에서 스트리밍이 가능한 flv 파일로
변환하고, 이용 가능한 Flv player를 통해 기본적인 스트리밍 환경을 구성할 수 있다.


아래는 실제 환경에 적용 가능한 수준의 스트리밍 환경을 구성해 보자


우선 스트리밍 서비스 대상 동영상을 웹 서비스가 가능한 특정 경로 밑의  SERVICE 란 디렉토리에
복사한다.


# cp *.avi [PATH]/SERVICE
# cd [PATH]/SERVICE


여기서 [PATH] 는 웹서버의 Document Root 아래에 해당하는 상대 경로이다.


해당 디렉토리 밑에 있는 avi 파일을 ffmpeg_encoder.sh 스크립트를 이용하여 flv 파일 형태로
모두 변환한다. (자동화 스크립트는 각자 개발 ..)


# ls -1 | grep flv$ > list.txt


uccup player 관련 파일을 [PATH] 에 복사해 둔다. -> 별도 요청


uccup 의 config 파일의 설정을 수정한다.


# vi config.php


// 실제 서비스 폴더
$SERVICE_DIR = $_SERVER[DOCUMENT_ROOT] . ‘[PATH]/SERVICE/’;

.
.



이제 간단한 스트리밍 동영상 목록 페이지와 Player 뷰어 페이지를 개발해야 한다.
아래는 직접 개발한 간단한 소스이다. 참고 바람..


– 스트리밍 동영상 목록 페이지


# vi index.php



<?
include “./config.inc”;


$root = “./SERVICE”;
$fp = fopen(“${root}/list.txt”,”r”);
$fsize = filesize(“${root}/list.txt”);


if (!$fp) {
        echo (“list.txt  .”);
        exit;
        }



while (!feof($fp)) {
        $str = fgets($fp,$fsize);
        $str = trim($str);
        $str = ereg_replace(“.flv”,””,trim($str));
        $arr[] = $str;
        }



$M_num = sizeof($arr) – 1;
$MovieName = “<font size=3><b>\”$M_Name\” 에 해당하는 동영상/[$M_num]편 </b></font>”;



?>


<html>


<head>
<link rel=”stylesheet” href=”main.css” type=”text/css”>


</head>


<body bgcolor=#DDE5D9>
<table width=650 cellspacing=5 cellpadding=0 border=0 bgcolor=#EFEFEF>
<tr>
<td height=50 align=left vaglign=middle bgcolor=white>&nbsp;
<? echo $MovieName; ?>
</td>
</tr>



<tr>
<td bgcolor=white align=center>



<table width=500 cellspacing=7 cellpadding=3 border=0>
<tr bgcolor=#DEDEDE align=center>
<?


if (!$fp) {
        echo (“list.txt 파일이 없습니다.”);
        exit;
        }



while (!feof($fp)) {
        $str = fgets($fp,$fsize);
        $str = trim($str);
        $str = ereg_replace(“.flv”,””,trim($str));
        $arr[] = $str;
        }


for ($i = 0; $i < sizeof($arr) -1 ; $i++) {


$A = ${i} % 5 ;
$B = ${i} + 1 ;
if (  $A  == 0 ) {


        echo (“</tr><tr bgcolor=#DEDEDE align=center><td>
        <table cellpadding=2 cellspacing=2 width=100% border=0>
        <tr><td align=center bgcolor=white><a href=view.php?filename=$arr[$i]&moviename=$B>
        <img src=$root/$arr[$i].jpg width=100 height=70 alt=$arr[$i] border=0></a>
        </td></tr>
        <tr><td align=center bgcolor=white>$M_Name $B</td></tr>
        </table>
        </td>”);


} else {


        echo (“<td>
        <table cellpadding=2 cellspacing=2 width=100% border=0>
        <tr><td align=center bgcolor=white><a href=view.php?filename=$arr[$i]&moviename=$B>
        <img src=$root/$arr[$i].jpg width=100 height=70 alt=$arr[$i] border=0></a>
        </td></tr>
        <tr><td align=center bgcolor=white>$M_Name $B</td></tr>
        </table>
        </td>”);


}


}



?>


</td></tr></table>




– 동영상 Player 뷰어 페이지


# vi view.php



<?
include “./config.inc”;
$root = “./SERVICE”;
$fp = fopen(“${root}/list.txt”,”r”);
$fsize = filesize(“${root}/list.txt”);
$MovieName = “<font size=3><b>\”$M_Name\” [$moviename]편에 해당하는 동영상</b></font>”;
?>


<html>


<head>
<link rel=”stylesheet” href=”main.css” type=”text/css”>
</head>


<body bgcolor=#DDE5D9>
<table width=650 cellspacing=5 cellpadding=0 border=0 bgcolor=#EFEFEF>
<tr>
<td height=50 align=left vaglign=middle bgcolor=white>
        <table width=100% cellpadding=0 cellspacing=0 border=0>
        <tr><td align=left height=50>&nbsp;
<? echo (“$MovieName”); ?>
        </td><td align=right><a href=index.php>전체 목록보기</a>&nbsp;&nbsp;</td></tr>
        </table>
</td>
</tr>


<tr>
<td height=450 bgcolor=white align=center valign=middle>



<embed src=”http://syszone.co.kr/<? echo $top; ?>/UCCUp.swf?file=http://syszone.co.kr/<? echo $top; ?>/file.php?f=<? echo $filename; ?>.flv&previewImage=http://syszone.co.kr/<? echo $top; ?>/file.php?f=<? echo $filename; ?>.jpg&bufferTime=3&bgColor=-1″
width=”600″ height=”420″ scale=”noscale” bgcolor=”#ffffff” type=”application/x-shockwave-flash” allowFullScreen=”true”
allowScriptAccess=”always” allowNetworking=”all” pluginspage=”
http://www.macromedia.com/go/getflashplayer“>
</embed>



</td></tr>
<tr><td>
<table width=100% cellpadding=0 cellspacing=0 border=0><tr>


<?


if (!$fp) {
        echo (“list.txt 파일이 없습니다.”);
        exit;
        }


while (!feof($fp)) {
        $str = fgets($fp,$fsize);
        $str = trim($str);
        $str = ereg_replace(“.flv”,””,trim($str));
        $arr[] = $str;
        }



if ( sizeof($arr) > ( $moviename + 5) ) {



for ($i = $moviename; $i < $moviename + 5 ; $i++) {
$B = $i + 1;


        echo (“<td>
        <table cellpadding=2 cellspacing=2 width=100% border=0>
        <tr><td align=center bgcolor=white><a href=view.php?filename=$arr[$i]&moviename=$B>
        <img src=$root/$arr[$i].jpg width=100 height=70 alt=$arr[$i] border=0></a>
        </td></tr>
        <tr><td align=center bgcolor=white>$M_Name $B</td></tr>
        </table></td>”);
        }


} else {


$A = sizeof($arr) – $moviename – 1;
for ($i = $moviename; $i < $moviename + $A ; $i++) {
$B = $i + 1;


        echo (“<td>
        <table cellpadding=2 cellspacing=2 width=100% border=0>
        <tr><td align=center bgcolor=white><a href=view.php?filename=$arr[$i]&moviename=$B>
        <img src=$root/$arr[$i].jpg width=100 height=70 alt=$arr[$i] border=0></a>
        </td></tr>
        <tr><td align=center bgcolor=white>$M_Name $B</td></tr>
        </table></td>”);
        }
}


?>



</tr>


</table>



– 환경 설정 파일


# vi config.inc



<?


$M_Name = “동영상서비스이름”;
$top = “[PATH]”;


?>


 


이제 http://domain/[PATH] 로 접속해서  확인한다.


그럼.. [PATH]/SERVICE 디렉토리안에 있는 모든 flv 파일이 리스트화 된 화면이 나타날것이다. 



8. RED5 를 이용한 스트리밍 서비스 환경 구축하기 


– Red5 설치하기


ant download :  http://ant.apache.org/bindownload.cgi
red5 download : http://osflash.org/red5
jdk download : http://java.sun.com


각 사이트에서 최신 패키지를 다운받는다.


apache-ant-1.7.1-bin.tar.gz
red5-0.7.0.tar.gz
jdk-6u11-linux-x64-rpm.bin


– JDK 설치하기


# chmod 755 jdk-6u11-linux-x64-rpm.bin
# ./jdk-6u11-linux-x64-rpm.bin
——————————————————————————–
.
.


Do you agree to the above license terms? [yes or no]
              yes
Unpacking…
Checksumming…
Extracting…
UnZipSFX 5.50 of 17 February 2002, by Info-ZIP (
Zip-Bugs@lists.wku.edu).
  inflating: jdk-6u11-linux-amd64.rpm 
  inflating: sun-javadb-common-10.4.1-3.1.i386.rpm 
  inflating: sun-javadb-core-10.4.1-3.1.i386.rpm 
  inflating: sun-javadb-client-10.4.1-3.1.i386.rpm 
  inflating: sun-javadb-demo-10.4.1-3.1.i386.rpm 
  inflating: sun-javadb-docs-10.4.1-3.1.i386.rpm 
  inflating: sun-javadb-javadoc-10.4.1-3.1.i386.rpm 
준비 중…                  ########################################### [100%]


.
.
Press Enter to continue…..
Done.


/usr/java 디렉토리 밑에 설치 완료 .


– Ant 설치하기


# tar xzvf apache-ant-1.7.1-bin.tar.gz
# mv apache-ant-1.7.1 /usr/local/ant


– Red5 설치하기


# mkdir /usr/local/red5
# tar xzvf red5-0.7.0.tar.gz -C /usr/local/red5


– 환경설정하기


# vi /etc/profile.d/ant_java.sh
—————————————————————————–



#!/bin/sh


export JAVA_HOME=/usr/java/default
export JAVA_VERSION=1.6
export ANT_HOME=/usr/local/ant
export PATH=${ANT_HOME}/bin:${JAVA_HOME}/bin:$PATH


—————————————————————————-


# source /etc/profile.d/ant_java.sh
# java -version
java version “1.6.0_11”
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
Java HotSpot(TM) 64-Bit Server VM (build 11.0-b16, mixed mode)


– RED5 컴파일 및 데몬 시작하기


http://osflash.org/red5 에서 final 바이너리 패키지를 받은 경우 별도의 컴파일
없이 바로 실행이 가능하다.


# cd /usr/local/red5
# sh red5.sh


svn를 통해 코드를 받은 경우 아래와 같이 컴파일을 해줘야 한다.


# cd /usr/local
# svn co
http://red5.googlecode.com/svn/java/server/trunk red5src
# cd red5


방법1 :


# cd /usr/local/red5src


# ant server &
# /usr/local/ant/bin/ant
# cp -a /usr/local/red5src/dist /usr/local/red5
# cd /usr/local/red5
# ./red5.sh &


방법2 :


# cd /usr/local/red5src
# make
# make install


# cd /usr/lib/red5
# ./red5.sh &


방법 3 :


# cd /usr/local/red5src
# ant prepare
# ant build


Target “build” does not exist in the project “RED5”. 라는 에러가 발생했을 경우


# ant
or
# ant -f build.xml
# cp -a dist /usr/local/red5
# cd /usr/local/red5
# sh red5.sh &


;; 3번 권장함



최신버전으로 컴파일 시 간혹 아래와 같은 에러가 발생하는 경우가 있다.
————————————————————————
.
[ivy:resolve]           :: spring#spring-support;2.0.8: not found
[ivy:resolve]           :: javax#jsp-api;2.1: not found
[ivy:resolve]           :: red5#xercesImpl;2.9.0: not found
[ivy:resolve]           :: red5#groovy;1.0: not found
[ivy:resolve]           :: commons#commons-lang;2.3: not found
[ivy:resolve]           :: tomcat#jasper;6.0.14: not found
[ivy:resolve]           ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:resolve]
[ivy:resolve] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS


BUILD FAILED
/usr/local/red5-0.7.0/build.xml:205: The following error occurred while executing this line:
/usr/local/red5-0.7.0/build.xml:221: The following error occurred while executing this line:
/usr/local/red5-0.7.0/build.xml:165: impossible to resolve dependencies:
        resolve failed – see output for details
————————————————————————



위 문제는 ivy 라는 패키지 관리 도구에서 red5 컴파일 시 필요한 패키지를 사전에 정의된
패키지 저장소에서 자동으로 다운로드 받게 되는데, 필요한 패키지를 찾을 수 없을때 발생한다.
ivy.xml 와 ivysettings.xml 파일에 다운로드 경로 정보가 있는데, 이것이 변동된 경우 발생하니


ivysettings.xml 에서 http://red5.googlecode.com/svn/trunk/repository/ 부분을
http://red5.googlecode.com/svn/repository 로 수정하거나 최신 해당 파일을 다운로드 받으면
된다.



– Init script 만들기


# vi /etc/rc.d/init.d/red5
————————————————————————–



#!/bin/sh
#
# Startup script for Red5 flash streaming server
#
# chkconfig: 345 81 81
# description: RED5 by java
#
# processname: java (unfortunately)
# pidfile: /var/run/red5.pid
# config: /etc/red5.conf


# Source function library.


. /etc/rc.d/init.d/functions


PID_FILE=/var/run/red5.pid
PID=`ps ax |grep java|grep red5|awk ‘{print $1;}’`
RETVAL=0


start() {
echo -n $”Starting $DESCR: “
# daemon java $OPTIONS > /dev/null 2>&1 &


export ANT_HOME=/usr/local/ant
export JAVA_HOME=/usr/java/default
export PATH=$PATH:$JAVA_HOME/bin:$ANT_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar


exec $JAVA_HOME/bin/java -Djava.security.manager -Djava.security.policy=/usr/local/red5/conf/red5.policy -cp /usr/local/red5/red5.jar:conf:/usr/local/red5/conf org.red5.server.Standalone > /dev/null 2>&1 & RETVAL=$?


[ $RETVAL = 0 ] && touch /var/lock/subsys/red5 && echo $!>$PID_FILE && echo_success
echo
return $RETVAL
}
stop() {
echo -n $”Stopping $DESCR: “
#killproc $PID_FILE
[[ $PID != “” ]] && success && kill $PID || failure
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/red5 $PID_FILE
}


# See how we were called.
case “$1” in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 3
start
;;
*)
echo $”Usage: $DESCR {start|stop|restart}”
exit 1
esac


exit $RETVAL


—————————————————————————-


# chmod 755 /etc/rc.d/init.d/red5
# chkconfig –add /etc/rc.d/init.d/red5


# /etc/rc.d/init.d/red5 start



– red5 spec file
—————————————————————————-
Summary: Red5 Server
Name: red5
Version: 0.7.0
Release: 1
Source0: %{name}-%{version}.tar.gz
License: LGPL
Group: Applications/Networking
BuildRoot: %{_builddir}/%{name}-root
%description
The Red5 open source Flash server allows you to record and stream video to the Flash Player.
%prep
%setup -q
%build
ant dist-installer
%install
cp dist $RPM_BUILD_ROOT
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
/usr/local/bin/red5.init
%doc doc/changelog.txt
——————————————————————————


– Red5를 이용한 flv 동영상 스트리밍 Player 환경 구성하기


flash_media_player.zip 파일을 다운로드 받는다.
http://www.jeroenwijering.com/upload/flash_media_player.zip


# cp mediaplayer.html index.html


# vi index.html
——————————————————————————



<html>
<head>


<script type=”text/javascript” src=”swfobject.js”></script>



</head>
<body>



<p id=”player2″><a href=”http://www.macromedia.com/go/getflashplayer”>Get
the Flash Player</a> to see this player.</p>
<script type=”text/javascript”>
        var s2 = new SWFObject(“mediaplayer.swf”,”playlist”,”640″,”640″,”9″);
        s2.addParam(“allowfullscreen”,”true”);
        s2.addVariable(“file”,”playlist.xml”);
        s2.addVariable(“displayheight”,”480″);
        s2.addVariable(“backcolor”,”0x000000″);
        s2.addVariable(“frontcolor”,”0xCCCCCC”);
        s2.addVariable(“lightcolor”,”0x996600″);
        s2.write(“player2”);
</script>



</body>
</html>


———————————————————————————-


# vi playlist.xml
———————————————————————————-



<playlist version=”1″ xmlns=”http://xspf.org/ns/0/“>
        <trackList>
        <track>
        <title>Resident.Evil.Degeneration.2008</title>
        <creator>alang</creator>
        <location>rtmp://syszone.co.kr/oflaDemo/</location>
        <identifier>residentevil.flv</identifier>
        <meta rel=”type”>rtmp</meta>
        </track>
        </trackList>


.
.


</playlist>


———————————————————————————-



위의 <location>rtmp://syszone.co.kr/oflaDemo/</location> 에 해당 red5 streams 디렉토리
경로를 지정한다.


기본 경로는 [RED5_PATH]/webapps/oflaDemo/streams 디렉토리 밑에 flv 파일을 넣어두면된다.


9. RED5와 OpenLaszlo를 이용한 스트리밍 환경 구축하기


http://www.openlaszlo.org 에서 최신 패키지를 다운받는다.


최신 개발 패키지  : http://download.openlaszlo.org/nightly/trunk



# tar xzvf openlaszlo-4.2.0-unix.tar.gz
# mv lps-4.2.0 /usr/local/lps
# cd /usr/local/lps/Server/tomcat-5.0.24/bin
# ./startup.sh
———————————————————————————-
Using CATALINA_BASE:   /usr/local/lps/Server/tomcat-5.0.24
Using CATALINA_HOME:   /usr/local/lps/Server/tomcat-5.0.24
Using CATALINA_TMPDIR: /usr/local/lps/Server/tomcat-5.0.24/temp
Using JAVA_HOME:       /usr/java/default


———————————————————————————-


http://domain:8080/lps-4.2.0/demos/


# cd /usr/local/lps/Server/lps-4.2.0/demos/videolibrary
# vi videolibrary.lzx
———————————————————————————-



<include href=”av/videoutils.lzx”/> -> 삭제


.
.
    <dataset name=”ds_library”
        src=”http:videolibrary.jsp?method=getLibrary”
        request=”true”
    />


이 부분을 ..


    <dataset name=”ds_library”
        src=”
http://192.168.123.2:8080/lps-4.2.0/demos/videolibrary/videolibrary.jsp?method=getLibrary
        request=”true”
    />


으로 ..



    <rtmpconnection id=”rtc”
        autoconnect=”true”
        debug=”true”
        src=”rtmp:localhost/test/instance1″
    />
 
이 부분을 ..


    <rtmpconnection id=”rtc”
        autoconnect=”true”
        debug=”true”
        src=”rtmp://192.168.123.90/oflaDemo”
    />


으로 변경


———————————————————————————-
# vi videolibrary.jsp
———————————————————————————
 



  public String libraryDirectory =
        “/home/fms/applications/test/streams/instance1/”; –> 이부분을 ..
 “/usr/local/red5/webapps/oflaDemo/streams/” 으로 ..


    public String libraryUrl =
        “rtmp://localhost/test/instance1/”; –> 이부분을
 “rtmp://domain/oflaDemo/”; 으로 ..


———————————————————————————


아래 주소로 접속하면 확인이 가능하다.


http://192.168.123.2:8080/lps-4.2.0/demos/videolibrary/videolibrary.lzx


;; flv 파일명이 한글이면 안된다.
;; flv 파일 리스트와 썸네일이 보이지 않는다.


– thumbnail 관련 임시 조치


# cd /usr/local/lps/Server/lps-4.2.x/demos/videolibrary
# vi videolibrarythumbnail.lzx
——————————————————————————–


.
        <videothumbnail name=”vt”
.
thumbnailtime=”${classroot.thumbnailtime}” resource=”resources/thumbnail.jpg”
 />

——————————————————————————–


resources=”원하는 thumbnail 파일 경로” 적어 준다.


….ㅠ.ㅠ


– lps URL 변경


# cd /usr/local/lps/Server/tomcat-5.0.24/conf/LPS/localhost
# vi lps.xml
——————————————————————————–
<Context docBase=”../../lps-4.2.x” path=”/lps-4.2.x”>


위의 path=”” 에 url에 표시될 alias명을 적는다.


http://domain:8080/<alias_name>


– SOLO 기능 이용하기


solo 는 laszlo에서 개발된 내용을 HTML과 swf 형태로 변경해 주는 관리 기능이다.
실제 laszlo로 미디어 관련 어플리케이션을 개발한 후 최종적으로는 solo를 이용하여
웹 컨텐츠 형태로 변형 시켜 사용한다.


solo 버턴을 클릭하면 해당 컨텐츠가 zip 파일로 압축된다.
압축 파일 위치는 /usr/local/lps/Server/lps-4.2.x/lps/admin 이다.


웹서버의 적당한 디렉토리 및에 해당 파일을 풀고 사용하면 된다.



– 동영상 저장소 분리하기


기본적으로 하나의 저장소에 동영상을 모두 저장해야 하는데, 이 경우 동영상의 수가
너무 많아 지면, 동영상 목록을 불려 올때 일정 시간 이후에 로딩되는 목록의 경우
익식을 못하는 문제가 발생한다.


또한 성격이 다른 동영상을 분리하여 저장할 필요가 있는데, 하나의 저장소를 통해
관리하기엔 한계가 있다.



저장소를 분리하여 관리하는 방법에 대해 알아보자.
본 방법이 정식적인 방법은 아니라고 본다. 그냥 될거 같아 해 보았는데 되더라.



일단 red5 의 동영상 서비스 위치인 /usr/local/red5/webapps/oflaDemo 을 다른이름
으로 복사한다.


# cd /usr/local/red5/webapps
# mkdir oflaDemo2007
# cp -a oflaDemo/WEB-INF/ oflaDemo2007/
# cd oflaDemo2007/WEB-INF


# vi red5-web.properties
—————————————————————
webapp.contextPath=/oflaDemo2007
—————————————————————


# vi web.xml
—————————————————————
        <context-param>
                <param-name>webAppRootKey</param-name>
                <param-value>/oflaDemo2007</param-value>
—————————————————————



# cd ..
# mkdir streams


이제 /usr/local/red5/webapps/oflaDemo2007/streams 밑에 해당 동영상을 복사한다.


그런 다음 lps 의 videolibrary 소스 저장소를 분리한다.


# cd /usr/local/lps/Server/lps-4.7.2/demos
# cp -a videolibrary videolibrary2007
# cd videolibrary2007/
# vi videolibrary.jsp
—————————————————————-



    public String libraryDirectory =
        //”/usr/local/src/red5/webapps/test/instance1/streams/”;
        “/usr/local/red5/webapps/oflaDemo2007/streams/”;



    public String libraryUrl =
        “rtmp://syszone.co.kr/oflaDemo2007/”;
—————————————————————-


# vi videolibrary.lzx
—————————————————————-
    <dataset name=”ds_library”
        src=”
http://syszone.co.kr:8080/lps-4.7.2/demos/videolibrary2007/videolibrary.jsp?method=getLibrary
        request=”true”
    />


    <rtmpconnection id=”rtc”
        autoconnect=”true”
        debug=”true”
        src=”rtmp://syszone.co.kr/oflaDemo2007/”
    />



# cd /usr/local/lps/Server/tomcat-5.0.24/bin/
# ./shutdown.sh
# /etc/rc.d/init.d/red5 stop
# /etc/rc.d/init.d/red5 start
# ./startup.sh



이제 웹 브라우저에서 확인을 한다.


http://domain:8080/lps-4.7.2/demos/videolibrary2007/videolibrary.lzx


본 문서의 데모는 blog.syszone.co.kr 의 동영상앨범과 LINKS 메뉴에서 실제 스트리밍
서비스를 확인해 보면 된다.

서진우

슈퍼컴퓨팅 전문 기업 클루닉스/ 상무(기술이사)/ 정보시스템감리사/ 시스존 블로그 운영자

You may also like...

3 Responses

  1. 2022년 6월 21일

    2missouri

  2. 2023년 1월 26일

    2euphrates

  3. 2024년 10월 7일

    … [Trackback]

    […] Here you will find 8009 additional Info on that Topic: nblog.syszone.co.kr/archives/3540 […]

페이스북/트위트/구글 계정으로 댓글 가능합니다.