Implemented video publishing, but still has stack overflow

This commit is contained in:
Hugo Lazzari 2014-01-23 10:01:13 -02:00
parent 8d18dfe118
commit 595368050f
9 changed files with 53 additions and 257 deletions

View File

@ -1,26 +0,0 @@
/*
* RED5 Open Source Flash Server - http://code.google.com/p/red5/
*
* Copyright 2006-2012 by respective authors (see below). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bigbluebutton.app.video;
public enum StreamState {
STOPPED, CONNECTING, STREAM_CREATING, PUBLISHING, PUBLISHED, UNPUBLISHED;
}

View File

@ -1,193 +0,0 @@
package org.bigbluebutton.app.video;
/*
* RED5 Open Source Flash Server - http://code.google.com/p/red5/
*
* Copyright (c) 2006-2010 by respective authors (see below). All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any later
* version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.red5.io.utils.ObjectMap;
import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IPendingServiceCallback;
import org.red5.server.messaging.IMessage;
import org.red5.server.messaging.IMessageComponent;
import org.red5.server.messaging.IPipe;
import org.red5.server.messaging.IPipeConnectionListener;
import org.red5.server.messaging.IPushableConsumer;
import org.red5.server.messaging.OOBControlMessage;
import org.red5.server.messaging.PipeConnectionEvent;
;
import org.red5.server.net.rtmp.event.Notify;
import org.red5.server.net.rtmp.status.StatusCodes;
import org.red5.server.stream.message.RTMPMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.red5.client.net.rtmp.INetStreamEventHandler;
/**
* A proxy to publish stream from server to server.
*
* TODO: Use timer to monitor the connect/stream creation.
*
* @author Steven Gong (steven.gong@gmail.com)
* @author Andy Shaules (bowljoman@hotmail.com)
*/
public class StreamingProxy implements IPushableConsumer, IPipeConnectionListener, INetStreamEventHandler,
IPendingServiceCallback {
private static Logger log = LoggerFactory.getLogger(StreamingProxy.class);
private List<IMessage> frameBuffer = new ArrayList<IMessage>();
public static final String LIVE = "live";
public static final String RECORD = "record";
public static final String APPEND = "append";
private static final int STOPPED = 0;
private static final int CONNECTING = 1;
private static final int STREAM_CREATING = 2;
private static final int PUBLISHING = 3;
private static final int PUBLISHED = 4;
private String host;
private int port;
private String app;
private RTMPClient rtmpClient;
private int state;
private String publishName;
private int streamId;
private String publishMode;
public void init() {
rtmpClient = new RTMPClient();
state = STOPPED;
}
public synchronized void start(String publishName, String publishMode, Object[] params) {
System.out.println("CONECTANDO");
state = CONNECTING;
this.publishName = publishName;
this.publishMode = publishMode;
Map<String, Object> defParams = rtmpClient.makeDefaultConnectionParams(host, port, app);
System.out.println(host);
System.out.println(defParams);
System.out.println(port);
System.out.println(params);
rtmpClient.connect(host, port, defParams, this, params);
}
public synchronized void stop() {
if (state >= STREAM_CREATING) {
rtmpClient.disconnect();
}
state = STOPPED;
}
public void onPipeConnectionEvent(PipeConnectionEvent event) {
// nothing to do
}
synchronized public void pushMessage(IPipe pipe, IMessage message) throws IOException {
if (state >= PUBLISHED && message instanceof RTMPMessage) {
RTMPMessage rtmpMsg = (RTMPMessage) message;
//rtmpClient.publishStreamData(streamId, rtmpMsg);
} else {
frameBuffer.add(message);
}
}
public void onOOBControlMessage(IMessageComponent source, IPipe pipe, OOBControlMessage oobCtrlMsg) {
}
public void setHost(String host) {
this.host = host;
}
public void setPort(int port) {
this.port = port;
}
public void setApp(String app) {
this.app = app;
}
public synchronized void onStreamEvent(Notify notify) {
log.debug("onStreamEvent: {}", notify);
ObjectMap<?, ?> map = (ObjectMap<?, ?>) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
log.debug("<:{}", code);
if (StatusCodes.NS_PUBLISH_START.equals(code)) {
state = PUBLISHED;
//rtmpClient.invoke("FCPublish", new Object[] { publishName }, this);
//while (frameBuffer.size() > 0) {
// rtmpClient.publishStreamData(streamId, frameBuffer.remove(0));
//}
}
}
public synchronized void resultReceived(IPendingServiceCall call) {
System.out.println("RECEBI RESULTADO");
System.out.println("RECEBI RESULTADO");
System.out.println("RECEBI RESULTADO");
System.out.println("RECEBI RESULTADO");
System.out.println("RECEBI RESULTADO");
System.out.println("RECEBI RESULTADO");
System.out.println("RECEBI RESULTADO");
System.out.println("RECEBI RESULTADO");
System.out.println("RECEBI RESULTADO");
log.debug("resultReceived:> {}", call.getServiceMethodName());
if ("connect".equals(call.getServiceMethodName())) {
state = STREAM_CREATING;
System.out.println("CRIANDO STREAM");
//rtmpClient.createStream(this);
} else if ("createStream".equals(call.getServiceMethodName())) {
System.out.println("CRIANDO STREAM 2");
state = PUBLISHING;
Object result = call.getResult();
if (result instanceof Integer) {
Integer streamIdInt = (Integer) result;
streamId = streamIdInt.intValue();
log.debug("Publishing: {}", state);
//rtmpClient.publish(streamIdInt.intValue(), publishName, publishMode, this);
} else {
rtmpClient.disconnect();
state = STOPPED;
}
}
}
}

View File

@ -56,14 +56,8 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
@Override
public boolean appConnect(IConnection conn, Object[] params) {
log.info("oflaDemo appConnect");
System.out.println("TESTE 2");
System.out.println("TESTE 2");
System.out.println("TESTE 2");
System.out.println("TESTE 2");
System.out.println(conn);
System.out.println(params);
return super.appConnect(conn, params);
return super.appConnect(conn, params);
}
@Override
@ -97,20 +91,20 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
super.streamBroadcastStart(stream);
log.info("streamBroadcastStart " + stream.getPublishedName() + " " + System.currentTimeMillis() + " " + conn.getScope().getName());
if (recordVideoStream) {
recordStream(stream);
VideoStreamListener listener = new VideoStreamListener();
listener.setEventRecordingService(recordingService);
stream.addStreamListener(listener);
streamListeners.put(conn.getScope().getName() + "-" + stream.getPublishedName(), listener);
}
//if (recordVideoStream) {
// recordStream(stream);
// VideoStreamListener listener = new VideoStreamListener();
// listener.setEventRecordingService(recordingService);
// stream.addStreamListener(listener);
// streamListeners.put(conn.getScope().getName() + "-" + stream.getPublishedName(), listener);
// }
System.out.println("TESTE " + stream.getPublishedName());
System.out.println("TESTE");
/* System.out.println("TESTE " + stream.getPublishedName());
System.out.println("TESTE");
System.out.println("TESTE");
System.out.println("TESTE");
System.out.println("TESTE");
System.out.println("TESTE");*/
//IScope scope = stream.getScope();
//IBroadcastScope bsScope = getBroadcastScope(scope, stream.getPublishedName());
//StreamingProxy proxy = new StreamingProxy();

View File

@ -34,6 +34,8 @@ import org.red5.server.api.stream.IStreamListener;
import org.red5.server.stream.ClientBroadcastStream;
import org.slf4j.Logger;
import com.flazr.rtmp.RtmpReader;
public class VideoApplication extends MultiThreadedApplicationAdapter {
private static Logger log = Red5LoggerFactory.getLogger(VideoApplication.class, "video");
@ -107,7 +109,12 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
VideoProxyReceiver v = new VideoProxyReceiver("143.54.10.63", "videoproxy", "conferencia", stream.getPublishedName(), rtmpReader);
v.start();
VideoProxyPublisher proxy_publisher = new VideoProxyPublisher("143.54.10.63", "video", "conferencia", rtmpReader, "MY_STRING");
//String videoFilename = "/home/mconf/bbbot/bot/etc/video-sample.flv";
//FlvPreLoader loader = new FlvPreLoader(videoFilename);
//RtmpReader reader = new GlobalFlvReader(loader);
VideoProxyPublisher proxy_publisher = new VideoProxyPublisher("143.54.10.63", "video", "", rtmpReader, "320x240-teste");
proxy_publisher.start();
//proxy_publisher.fireFirstFrame();
}

View File

@ -42,7 +42,7 @@ public class VideoProxyPublisher {
opt = new ClientOptions();
opt.setClientVersionToUse(Utils.fromHex("00000000"));
opt.setHost(host);
opt.setAppName("video/" + conference);
opt.setAppName(app + "/" + conference);
opt.publishLive();
opt.setStreamName(streamName);
opt.setReaderToPublish(reader);

View File

@ -72,7 +72,7 @@ public class VideoProxyReceiver {
protected void onVideo(Video video) {
//Retransmit video package
//Received Video
//reader.addFrame(video);
reader.addFrame(video);
//System.out.println("Received Video data " + video.getHeader().getTime());
log.debug("received video package: {}", video.getHeader().getTime());
}

View File

@ -34,6 +34,7 @@ public class VideoRtmpReader implements RtmpReader {
public VideoRtmpReader(String streamName, int width, int height) {
state = START;
this.streamName = streamName;
@ -75,9 +76,8 @@ public class VideoRtmpReader implements RtmpReader {
public void addFrame(Video video) {
synchronized(this) {
framesList.add(video);
this.notifyAll();
}
}
@ -109,6 +109,14 @@ public class VideoRtmpReader implements RtmpReader {
@Override
public boolean hasNext() {
synchronized(this) {
if(framesList.isEmpty())
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(state == START)
return true;
@ -118,18 +126,12 @@ public class VideoRtmpReader implements RtmpReader {
@Override
public Video next() {
Video v;
synchronized(this) {
System.out.println("SEND FRAME");
if(framesList.isEmpty() == false) {
v = framesList.get(0);
framesList.remove(0);
}
else {
v = new Video();
}
if(framesList != null && !framesList.isEmpty())
return framesList.remove(0);
else
return new Video();
}
return v;
}
@Override

View File

@ -70,7 +70,7 @@ package org.bigbluebutton.modules.videoconf.business
public function connect():void {
LogUtil.debug("OLD: " + _url);
_url = "rtmp://143.54.10.63/video/conferencia";
_url = "rtmp://143.54.10.63/videoproxy/conferencia";
nc.connect(_url);
}

View File

@ -64,6 +64,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.videoconf.events.CloseAllWindowsEvent;
import org.bigbluebutton.modules.videoconf.model.VideoConfOptions;
import flash.net.NetConnection;
private var ns:NetStream;
private var globalDispatcher:Dispatcher;
@ -75,11 +78,18 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
[Bindable] public var glowColor:String = "";
[Bindable] public var glowBlurSize:Number = 0;
public var connection2:NetConnection;
override public function getWindowType():String {
return windowType;
}
private function onCreationComplete():void{
//connection2.connect("rtmp://143.54.10.63/video/conferencia");
this.glowColor = videoOptions.glowColor;
this.glowBlurSize = videoOptions.glowBlurSize;
@ -174,6 +184,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
public function startVideo(connection:NetConnection, stream:String):void{
var stream2 = "320x240-rgheqrhe5odq-1390474656405";
ns = new NetStream(connection);
ns.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus );
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
@ -182,7 +194,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
ns.receiveVideo(true);
ns.receiveAudio(false);
var res:Array = getVideoResolution(stream);
var res:Array = getVideoResolution(stream2);
if (res == null) // error
return;
_video = new Video(Number(res[0]), Number(res[1]));
@ -208,14 +220,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
filter.divisor = videoOptions.filterDivisor;
_video.filters = [filter];
}
LogUtil.debug("PLyaying: " + stream);
LogUtil.debug("PLyaying: " + stream2);
//ns.play(stream);
ns.play("MY_STRING");
ns.play("320x240-teste");
LogUtil.debug("Playing MY_STRING 2");
this.streamName = "MY_STRING";
ns.play("MY_STRING");
this.width = _video.width + paddingHorizontal;
this.height = _video.height + paddingVertical;