|
|
|||||
UFO
Регистрация: Jul 2007
Сообщений: 173
|
Изучаю Red5 с нуля =)
Часть первая:
Возникла необходимость сделать простенький видеочат, тет-а-тет. Я когда то работал с 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. |
|
|||||
UFO
Регистрация: Jul 2007
Сообщений: 173
|
Часть вторая:
Итак немного помучавшись, почучав друзей решил приступить к написанию простой вещи, red5 создает сокет, коннектится к внутреннему серверу и делает запрос на существование в базе данных юзера с заданным id. Для начала я пошел в гугл и просто поискал примеры "java socket пример", и т.д. ковырялся надо сказать долго, потому что все время всплывали ошибки =) в итоге подключив несколько библиотек, я написал простую функцию, которая коннектится к серверу, шлет запрос, получает ответ и возвращает нам true или false. private boolean getSession ( String user_id ) { try { String data = "user_id=" + user_id + "\n"; Socket sock = new Socket (); sock.connect ( new InetSocketAddress ( "devel3.mlan", 11717 ), 500); PrintWriter out = new PrintWriter(sock.getOutputStream(), true); out.print(data); out.flush(); BufferedReader in = new BufferedReader ( new InputStreamReader ( sock.getInputStream () ) ); while (!in.ready () ) {} String read = in.readLine(); out.close(); in.close(); String falseString = "NOTFOUND"; if ( read.equals (falseString) ) { return false; } else { return true; } } catch (Exception e) { return false; } } Хочется сказать несколько слов о яве. По сравнению с синтаксисом ActionScript, Java, ближе к С =) Например обозначить функцию на яве можно так: private boolean getSession ( String user_id ) а в АС так: private function getSession ( String user_id ) : boolean Так же и имена переменных: java String data = "user_id=" + user_id + "\n"; AS var data:String = "user_id=" + user_id + "\n"; Как оказалось - ничего сложного. Немного поправил основную функцию, которая теперь принимает параметром id нашей флешки. public boolean appConnect ( IConnection conn , Object[] params ) { //log.info ( "Red5First.appConnect " + conn.getClient ().getId () ); if ( getSession ( ( String ) params[0] ) == false ) { rejectClient( "NOTFOUND" ); return super.appConnect ( conn, params ); } else { 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 ); } } Соответственно и клиентская часть притерпела изменения: Самое интересное, что все это работает! =) а как страшно было начинать!! =))) |
|
|||||
UFO
Регистрация: Jul 2007
Сообщений: 173
|
Цитата:
Проблем с установкой под макосью не возникло вообще - действовал по инструкции по первой ссылке. Под линуксом пришлось повозиться, потому что тащит он за собой всякого очень много. НО! инструкции по установке в сети тоже есть. |
|
|||||
Регистрация: Nov 2007
Сообщений: 4
|
Вообще-то в Red5 можно писать webapps на целой куче языков от javascript до jython... Только надо это уметь делать
|
|
|||||
Регистрация: Sep 2008
Сообщений: 20
|
а еще там написано что можно в принципе для любого языка интерпритатор написать , но интерпритатор не есть компилятор...
|
|
|||||
ну почему же у меня постоянно не получаеться((((
Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: flash.net.NetConnection was unable to invoke callback onBWDone. error=ReferenceError: Error #1069: Property onBWDone not found on flash.net.NetConnection and there is no default value. at Untitled_fla::MainTimeline/createConnect() at Untitled_fla::MainTimeline/Untitled_fla::frame1() NetConnection.Connect.Success null NetStream.Publish.Start я уже четверо суток юзаю различное ПО, готовые исходки, гугл и всё напрасно. просто ппц, что я насколько слаб(( Подскажите подалуйста, я просто сойду с ума... И какое ПО нужно для разработки? У меня стоит: Red5 v2.1 Adobe Flash CS3 Proffesional edition Adobe Flex Builder 3 Eclipse Platform v3.4.1 Build id: M20080911-1700 NetBeans IDE 5.5 Build 200612070100
__________________
return this... Последний раз редактировалось AlexCooper; 14.11.2008 в 17:13. |
|
|||||
Регистрация: Apr 2004
Адрес: город 312
Сообщений: 116
|
Цитата:
версия 0.63 тянет более менее 200 юзеров а вот 0.7 частенько просто выпинывает клиентов
__________________
человек - переходная ступень от обезьяны к программисту |
Часовой пояс GMT +4, время: 18:17. |
|
« Предыдущая тема | Следующая тема » |
|
|