![]() |
|
||||||||||
|
|||||
|
UFO
Регистрация: Jul 2007
Сообщений: 173
|
Часть первая:
Возникла необходимость сделать простенький видеочат, тет-а-тет. Я когда то работал с FCS - ныне FMS, от Адобы поэтому решил что проблем с red5 у меня не возникнет. Ах, как же я ошибался =) Итак, первое что я узнал, это то, что весь серверный скрипт пишется на Java, т.е. придется изучать новый для меня язык. Впринципе я рассчитывал что это будет не сложно, т.к. ActionScript и JavaScript, Java - очень похожи... Итак, первое что я нашел в интернете, это переведнная статья: "Начало разработки с Red5" Следуя инструкциям, я выполнил все шаги по инсталляции эклипса, и самого red5. Единственное что я не сделал сразу, это не качал Flash плагин к эклипсу, т.к. хотелось на скорую руку опробовать сервер в действии написав что нибудь простое во FlashIDE, да и не хотелось разбираться с эклипсом и его плагинами. Вобщем выполнив все действия по шагам, и переместив собранный пример на сервер, я понял что сервер не видит мою серверную часть программы ни в какую =( Первая попытка: NetConnection.Connect.InvalidApp?NetConnection.Connect.Closed Затем: NetConnection.Connect.Failed Очень странно т.к. по идее код простой и все должно работать! Ну деваться некуда, надо как-то разобраться ... нашел примеры в папке сервера, и решил начать сних. Берем пример от oflaDemo, лежащий в папке webapps, и тупо суем в эклипс, эклипс начинает материться что мол нет библиотек - все в красных крестах. Я сначала выборочно смотрел какие библиотеки необходимы, но т.к. разобраться надо в сжатые сроки, добавляю ВСЕ библиотеки из папки lib в red5. Делается это так же как в предыдущем примере: Project ? Properties. Раздел Java Build Path, вкладка Libraries. Нажимаем Add External JARs и выбираем все библиотеки в директории [red5_HOME]/lib нажимаем OK. Так же добавляем библиотеку red5.jar, лежащую в директории установки red5. Ура! Теперь эклипс видит библиотеки, а мы видим вместо скомпилированных классов, Application.class - код Applicayion.java. И никаких красных крестов =) Теперь когда я могу ковырять готовый пример, все пойдет намного быстрее. Итак, лезем в папку WEB-INF/src org.red5.server.webapp.oflaDemo и сразу делаем копию Application.java ( CopyOfApplication.java ). Это возможно пригодится, если я что-то накосячу своими кривыми руками. Ну что теперь? Попробую добить пример описаный в статье, для этого я копирую весь код из примера в статье, в наш Application.java. Копирую проект на сервер, рестартую сервак, и вуаля, флешка говорит что коннект успешен! ( либо не успешен, в зависимости от того какой параметр мы шлем, true или false ) ДА, это работает! Еще один маленький шаг вперед. Теперь у меня есть необходимость попробовать законнектить свою флешку, и постараться отдать поток серверу с веб камеры. Хочется так же, что бы поток именовался именно так как я хочу - это позволит мне раздавать этот поток отталкиваясь для начала лишь от его имени. Я выдрал кусок кода из копии CopyOfApplication.java подправил Application.java, и теперь он выглядит так: package org.red5.server.webapp.oflaDemo;
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IBandwidthConfigure;
import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.stream.IServerStream;
import org.red5.server.api.stream.IStreamCapableConnection;
import org.red5.server.api.stream.support.SimpleConnectionBWConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.red5.server.api.IConnection;
import org.red5.server.adapter.ApplicationAdapter;
public class Application extends ApplicationAdapter
{
private IScope appScope;
private IServerStream serverStream;
/** {@inheritDoc} */
@Override
public boolean appStart ( IScope app )
{
appScope = app;
return true;
}
public boolean appConnect ( IConnection conn , Object[] params )
{
log.info ( "Red5First.appConnect " + conn.getClient ().getId () );
//boolean accept = (Boolean)params[0];
//if ( !accept ) rejectClient( "you passed false..." );
if ( conn instanceof IStreamCapableConnection )
{
IStreamCapableConnection streamConn = ( IStreamCapableConnection ) conn;
SimpleConnectionBWConfig bwConfig = new SimpleConnectionBWConfig ();
bwConfig.getChannelBandwidth () [IBandwidthConfigure.OVERALL_CHANNEL] = 1024 * 1024;
bwConfig.getChannelInitialBurst () [IBandwidthConfigure.OVERALL_CHANNEL] = 128 * 1024;
streamConn.setBandwidthConfigure ( bwConfig );
}
return super.appConnect ( conn, params );
}
private static final Log log = LogFactory.getLog( Application.class );
public void appStop ()
{
log.info ( "Red5First.appStop" );
}
public void appDisconnect ( IConnection conn , Object[] params )
{
log.info ( "Red5First.appDisconnect " + conn.getClient ().getId () );
}
}
var nc:NetConnection;
var camera:Camera;
var microphone:Microphone;
var stream:NetStream;
function createCamera() {
camera = Camera.getCamera ();
microphone = Microphone.getMicrophone ();
if ( camera != null )
{
var widthCam = 640;
var heightCam = 480;
camera.setMode ( widthCam, heightCam, 30 );
camera.setQuality ( 0, 80 );
widthCam = camera.width;
heightCam = camera.height;
var video = new Video ( widthCam, heightCam );
video.width = 160;
video.height = 120;
video.attachCamera ( camera );
addChild ( video );
}
}
function createStream ():void
{
stream = new NetStream ( nc );
stream.addEventListener ( NetStatusEvent.NET_STATUS, netStatus );
stream.attachCamera ( camera );
stream.attachAudio ( microphone );
stream.publish ( "myId", "live" );
}
function createConnect ()
{
nc = new NetConnection ();
nc.objectEncoding = ObjectEncoding.AMF3;
nc.addEventListener ( NetStatusEvent.NET_STATUS, netStatus );
nc.connect ( "rtmp://localhost/oflaDemo" );
}
function netStatus ( event:NetStatusEvent ):void
{
trace ( event.info.code );
if ( event.info.code == "NetConnection.Connect.Rejected" )
{
// trace reject message
trace ( event.info.application );
}
if ( event.info.code == "NetConnection.Connect.Success" )
{
trace ( event.info.application );
createStream ();
}
}
createCamera ();
createConnect ();
Итак, stream.publish ( "myId", "live" ); - позволяет задать имя потока и тип потока налету ("record", "append", "live"). Наш сервер это хавает, создает в папке streams файл с именем myId. Все, пол дела сделано, и это оказалось не так уж и сложно =)) Но это я не вникал в java, а просто тупо скопировал пример. Да, кстати еще такое дело - примеры которые валяются в red5 для клиентской стороны все написаны на АС2.0, и используют кучу библиотек, написанных опять же на 2.0. Я пишу клиентскую часть на АС3, потому что мне так удобнее. Как же забрать поток? А поток забрать с сервера еще проще, чем отдать. Вот пример кода который будет читать по названию файла наш поток. var nc:NetConnection;
function createVideo ()
{
var stream:NetStream = new NetStream ( nc );
stream.addEventListener ( NetStatusEvent.NET_STATUS, netStatus );
//stream.client = new CustomClient();
var video:Video = new Video();
video.attachNetStream ( stream );
stream.play ( "myId", -1 );
addChild ( video );
}
function createConnect ()
{
nc = new NetConnection ();
nc.objectEncoding = ObjectEncoding.AMF3;
nc.addEventListener ( NetStatusEvent.NET_STATUS, netStatus );
nc.connect ( "rtmp://localhost/oflaDemo" );
}
function netStatus ( event:NetStatusEvent ):void
{
trace ( event.info.code );
if ( event.info.code == "NetConnection.Connect.Rejected" )
{
// trace reject message
trace ( event.info.application );
}
if ( event.info.code == "NetConnection.Connect.Success" )
{
trace ( event.info.application );
createVideo ();
}
}
Ну вот собственно дело сдвинулось с мертвой точки. Я немного разобрался в эклипсе, немного в яве. В следущий раз напишу как я делал соединение сокетами локального сервера проверки id и сервером red5 ( надеюсь это возможно ). Последний раз редактировалось ALiEN_; 13.11.2007 в 21:54. |
![]() |
Часовой пояс GMT +4, время: 11:58. |
|
|
« Предыдущая тема | Следующая тема » |
|
|