[Red5commits] [2176] Merged with trunk
sgong
luke at codegent.com
Mon Jul 9 00:22:16 EDT 2007
Merged with trunk
Timestamp: 07/07/07 04:24:25 EST (2 days ago)
Change: 2176
Author: sgong
Files (see diff or trac for details):
java/server/branches/clustering/conf/log4j.properties
java/server/branches/clustering/conf/red5.xml
java/server/branches/clustering/conf/war/log4j.properties
java/server/branches/clustering/src/org/red5/server/BasicScope.java
java/server/branches/clustering/src/org/red5/server/ClientList.java
java/server/branches/clustering/src/org/red5/server/ClientRegistry.java
java/server/branches/clustering/src/org/red5/server/JettyLoader.java
java/server/branches/clustering/src/org/red5/server/PersistableAttributeStore.java
java/server/branches/clustering/src/org/red5/server/Scope.java
java/server/branches/clustering/src/org/red5/server/Shutdown.java
java/server/branches/clustering/src/org/red5/server/Standalone.java
java/server/branches/clustering/src/org/red5/server/TomcatLoader.java
java/server/branches/clustering/src/org/red5/server/api/persistence/IPersistenceStore.java
java/server/branches/clustering/src/org/red5/server/api/persistence/PersistenceUtils.java
java/server/branches/clustering/src/org/red5/server/api/stream/IStreamFilenameGenerator.java
java/server/branches/clustering/src/org/red5/server/net/rtmp/RTMPMinaIoHandler.java
java/server/branches/clustering/src/org/red5/server/net/rtmp/codec/RTMPProtocolDecoder.java
java/server/branches/clustering/src/org/red5/server/net/rtmpt/RTMPTHandler.java
java/server/branches/clustering/src/org/red5/server/persistence/FilePersistence.java
java/server/branches/clustering/src/org/red5/server/persistence/FilePersistenceThread.java
java/server/branches/clustering/src/org/red5/server/persistence/RamPersistence.java
java/server/branches/clustering/src/org/red5/server/service/ServiceUtils.java
java/server/branches/clustering/src/org/red5/server/stream/BroadcastScope.java
java/server/branches/clustering/src/org/red5/server/stream/ClientBroadcastStream.java
java/server/branches/clustering/src/org/red5/server/stream/DefaultStreamFilenameGenerator.java
java/server/branches/clustering/src/org/red5/server/stream/ProviderService.java
java/server/branches/clustering/src/org/red5/server/stream/ServerStream.java
Trac: http://mirror1.cvsdude.com/trac/osflash/red5/changeset/2176
Index: /java/server/branches/clustering/conf/war/log4j.properties
===================================================================
--- /java/server/branches/clustering/conf/war/log4j.properties (revision 2034)
+++ /java/server/branches/clustering/conf/war/log4j.properties (revision 2176)
@@ -50,5 +50,5 @@
log4j.appender.CONSOLE.Threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
-log4j.appender.CONSOLE.layout.ConversionPattern=[%p] %r %t:( %c.%M ) %m %n
+log4j.appender.CONSOLE.layout.ConversionPattern=[%p] %d{ISO8601} %t:( %c.%M ) %m %n
log4j.appender.FLOG=org.apache.log4j.RollingFileAppender
@@ -58,5 +58,5 @@
log4j.appender.FLOG.MaxBackupIndex=1
log4j.appender.FLOG.layout=org.apache.log4j.PatternLayout
-log4j.appender.FLOG.layout.ConversionPattern=[%p] %r %t:( %c{1}.%M ) %m %n
+log4j.appender.FLOG.layout.ConversionPattern=[%p] %d{ISO8601} %t:( %c{1}.%M ) %m %n
log4j.appender.PROXY=org.apache.log4j.RollingFileAppender
@@ -66,3 +66,3 @@
log4j.appender.PROXY.MaxBackupIndex=1
log4j.appender.PROXY.layout=org.apache.log4j.PatternLayout
-log4j.appender.PROXY.layout.ConversionPattern=[%c{1}] (%r) %m %n
+log4j.appender.PROXY.layout.ConversionPattern=[%c{1}] (%d{ISO8601}) %m %n
Index: /java/server/branches/clustering/conf/red5.xml
===================================================================
--- /java/server/branches/clustering/conf/red5.xml (revision 1654)
+++ /java/server/branches/clustering/conf/red5.xml (revision 2176)
@@ -7,4 +7,9 @@
<!-- This file just wires together the context tree. Its accessed by ContextSingletonBeanFactoryLocator -->
+
+ <bean id="placeholderConfig"
+ class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="location" value="classpath:/red5.properties" />
+ </bean>
<!-- First we load the common context, its shared between all the other contexts -->
@@ -33,7 +38,13 @@
<!-- Now we can load the servlet engine, this has to happen after the context are loaded -->
- <bean id="jetty6.server" class="org.red5.server.JettyLoader" init-method="init" autowire="byType" depends-on="context.loader" />
+ <bean id="jetty6.server" class="org.red5.server.JettyLoader" init-method="init" autowire="byType" depends-on="context.loader">
+ <property name="webappFolder" value="${red5.root}/webapps" />
+ </bean>
+
<!--
<bean id="tomcat.server" class="org.red5.server.TomcatLoader" init-method="init" destroy-method="shutdown" autowire="byType" depends-on="context.loader">
+ <!- - Note: the webapp root folder must be specified before the "contexts" property - ->
+ <property name="webappFolder" value="${red5.root}/webapps" />
+
<property name="embedded">
<bean class="org.apache.catalina.startup.Embedded" />
Index: /java/server/branches/clustering/conf/log4j.properties
===================================================================
--- /java/server/branches/clustering/conf/log4j.properties (revision 1947)
+++ /java/server/branches/clustering/conf/log4j.properties (revision 2176)
@@ -67,5 +67,5 @@
log4j.appender.CONSOLE.Threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
-log4j.appender.CONSOLE.layout.ConversionPattern=[%p] %r %t:( %c.%M ) %m %n
+log4j.appender.CONSOLE.layout.ConversionPattern=[%p] %d{ISO8601} %t:( %c.%M ) %m %n
log4j.appender.FLOG=org.apache.log4j.RollingFileAppender
@@ -75,5 +75,5 @@
log4j.appender.FLOG.MaxBackupIndex=1
log4j.appender.FLOG.layout=org.apache.log4j.PatternLayout
-log4j.appender.FLOG.layout.ConversionPattern=[%p] %r %t:( %c{1}.%M ) %m %n
+log4j.appender.FLOG.layout.ConversionPattern=[%p] %d{ISO8601} %t:( %c{1}.%M ) %m %n
log4j.appender.PROXY=org.apache.log4j.RollingFileAppender
@@ -83,3 +83,3 @@
log4j.appender.PROXY.MaxBackupIndex=1
log4j.appender.PROXY.layout=org.apache.log4j.PatternLayout
-log4j.appender.PROXY.layout.ConversionPattern=[%c{1}] (%r) %m %n
+log4j.appender.PROXY.layout.ConversionPattern=[%c{1}] (%d{ISO8601}) %m %n
Index: /java/server/branches/clustering/src/org/red5/server/persistence/FilePersistence.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/persistence/FilePersistence.java (revision 2076)
+++ /java/server/branches/clustering/src/org/red5/server/persistence/FilePersistence.java (revision 2176)
@@ -67,9 +67,14 @@
/**
- * Whether there's ned to check for empty directories
+ * Whether there's need to check for empty directories
*/
// TODO: make this configurable
private boolean checkForEmptyDirectories = true;
+ /**
+ * Thread to serialize persistent objects.
+ */
+ private FilePersistenceThread storeThread = null;
+
/**
* Create file persistence object from given resource pattern resolver
@@ -79,4 +84,5 @@
super(resolver);
setPath(path);
+ storeThread = FilePersistenceThread.getInstance();
}
@@ -88,4 +94,5 @@
super(scope);
setPath(path);
+ storeThread = FilePersistenceThread.getInstance();
}
@@ -224,5 +231,5 @@
// We need to create the object first
try {
- Class theClass = Class.forName(className);
+ Class<?> theClass = Class.forName(className);
Constructor constructor = null;
try {
@@ -323,5 +330,5 @@
* @return <code>true</code> on success, <code>false</code> otherwise
*/
- private boolean saveObject(IPersistable object) {
+ protected boolean saveObject(IPersistable object) {
String path = getObjectFilepath(object, true);
Resource resPath = resources.getResource(path);
@@ -363,5 +370,5 @@
return true;
} catch (IOException e) {
- log.error("Could not create / write file " + filename);
+ log.error("Could not create / write file " + filename, e);
return false;
}
@@ -375,7 +382,7 @@
}
- boolean persistent = this.saveObject(object);
- object.setPersistent(persistent);
- return persistent;
+ storeThread.modified(object, this);
+ object.setPersistent(true);
+ return true;
}
@@ -448,3 +455,11 @@
}
+ /** {@inheritDoc} */
+ @Override
+ public void notifyClose() {
+ // Write any pending objects
+ storeThread.notifyClose(this);
+ super.notifyClose();
+ }
+
}
Index: /java/server/branches/clustering/src/org/red5/server/persistence/RamPersistence.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/persistence/RamPersistence.java (revision 1935)
+++ /java/server/branches/clustering/src/org/red5/server/persistence/RamPersistence.java (revision 2176)
@@ -174,3 +174,8 @@
return objects.values();
}
+
+ /** {@inheritDoc} */
+ public void notifyClose() {
+ objects.clear();
+ }
}
Index: /java/server/branches/clustering/src/org/red5/server/persistence/FilePersistenceThread.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/persistence/FilePersistenceThread.java (revision 2176)
+++ /java/server/branches/clustering/src/org/red5/server/persistence/FilePersistenceThread.java (revision 2176)
@@ -0,0 +1,187 @@
+package org.red5.server.persistence;
+
+/*
+ * RED5 Open Source Flash Server - http://www.osflash.org/red5
+ *
+ * Copyright (c) 2006-2007 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.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.red5.server.api.persistence.IPersistable;
+
+/**
+ * Thread that writes modified persistent objects to the filesystem periodically.
+ *
+ * @author The Red5 Project (red5 at osflash.org)
+ * @author Joachim Bauch (jojo at struktur.de)
+ */
+public class FilePersistenceThread extends Thread {
+
+ /**
+ * Logger
+ */
+ private Log log = LogFactory.getLog(FilePersistenceThread.class.getName());
+
+ /**
+ * Interval to serialize modified objects in milliseconds.
+ *
+ */
+ // TODO: make this configurable
+ private int storeInterval = 10000;
+
+ /**
+ * Modified objects that need to be stored.
+ */
+ private Map<IPersistable, FilePersistence> modifiedObjects = new HashMap<IPersistable, FilePersistence>();
+
+ /**
+ * Modified objects for each store.
+ */
+ private Map<FilePersistence, Set<IPersistable>> objectStores = new HashMap<FilePersistence, Set<IPersistable>>();
+
+ /**
+ * Singleton instance.
+ */
+ private static volatile FilePersistenceThread instance = null;
+
+ /**
+ * Return singleton instance of the thread.
+ *
+ * @return
+ */
+ public static FilePersistenceThread getInstance() {
+ if (instance == null) {
+ // Only synchronize if thread doesn't exist yet.
+ synchronized (FilePersistenceThread.class) {
+ if (instance == null) {
+ instance = new FilePersistenceThread();
+ instance.start();
+ }
+ }
+ }
+
+ return instance;
+ }
+
+ /**
+ * Create instance of the thread.
+ */
+ private FilePersistenceThread() {
+ super();
+ setName("FilePersistenceThread");
+ }
+
+ /**
+ * Notify thread that an object was modified in a persistence store.
+ *
+ * @param object
+ * @param store
+ */
+ protected void modified(IPersistable object, FilePersistence store) {
+ FilePersistence previous;
+ synchronized (modifiedObjects) {
+ previous = modifiedObjects.put(object, store);
+ Set<IPersistable> objects = objectStores.get(store);
+ if (objects == null) {
+ objects = new HashSet<IPersistable>();
+ objectStores.put(store, objects);
+ }
+ objects.add(object);
+ }
+
+ if (previous != null && !previous.equals(store)) {
+ log.warn("Object " + object + " was also modified in " + previous + ", saving instantly");
+ previous.saveObject(object);
+ Set<IPersistable> objects = objectStores.get(previous);
+ if (objects != null) {
+ objects.remove(previous);
+ }
+ }
+ }
+
+ /**
+ * Write any pending objects for the given store to disk.
+ *
+ * @param store
+ */
+ protected void notifyClose(FilePersistence store) {
+ Set<IPersistable> objects;
+ // Get snapshot of currently modified objects.
+ synchronized (modifiedObjects) {
+ objects = objectStores.remove(store);
+ if (objects != null) {
+ for (IPersistable object: objects) {
+ modifiedObjects.remove(object);
+ }
+ }
+ }
+
+ if (objects == null || objects.isEmpty()) {
+ return;
+ }
+
+ // Store pending objects
+ for (IPersistable object: objects) {
+ try {
+ store.saveObject(object);
+ } catch (Throwable e) {
+ log.error("Error while saving " + object + " in " + store, e);
+ }
+ }
+ }
+
+ /**
+ * Write modified objects to the filesystem periodically.
+ */
+ public void run() {
+ while (isAlive()) {
+ long start = System.currentTimeMillis();
+ if (!modifiedObjects.isEmpty()) {
+ Map<IPersistable, FilePersistence> objects;
+ // Get snapshot of currently modified objects.
+ synchronized (modifiedObjects) {
+ objects = new HashMap<IPersistable, FilePersistence>(modifiedObjects);
+ modifiedObjects.clear();
+ objectStores.clear();
+ }
+
+ for (Map.Entry<IPersistable, FilePersistence> entry: objects.entrySet()) {
+ try {
+ entry.getValue().saveObject(entry.getKey());
+ } catch (Throwable e) {
+ log.error("Error while saving " + entry.getKey() + " in " + entry.getValue(), e);
+ }
+ }
+ }
+ long end = System.currentTimeMillis();
+ try {
+ long delay = storeInterval - (end - start);
+ if (delay > 0) {
+ Thread.sleep(delay);
+ }
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ }
+
+}
Index: /java/server/branches/clustering/src/org/red5/server/ClientRegistry.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/ClientRegistry.java (revision 2000)
+++ /java/server/branches/clustering/src/org/red5/server/ClientRegistry.java (revision 2176)
@@ -91,4 +91,5 @@
* @return Collection of clients
*/
+ @SuppressWarnings("unchecked")
protected Collection<IClient> getClients() {
if (!hasClients()) {
Index: /java/server/branches/clustering/src/org/red5/server/ClientList.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/ClientList.java (revision 1947)
+++ /java/server/branches/clustering/src/org/red5/server/ClientList.java (revision 2176)
@@ -26,3 +26,8 @@
public class ClientList<E> extends ArrayList<E> implements ListMBean {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3127064371410565214L;
+
}
Index: /java/server/branches/clustering/src/org/red5/server/Shutdown.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/Shutdown.java (revision 2022)
+++ /java/server/branches/clustering/src/org/red5/server/Shutdown.java (revision 2176)
@@ -49,5 +49,5 @@
JMXServiceURL url = null;
JMXConnector jmxc = null;
- HashMap env = null;
+ HashMap<String, Object> env = null;
if (null == args || args.length < 1) {
@@ -62,5 +62,5 @@
if (args.length > 1) {
- env = new HashMap(1);
+ env = new HashMap<String, Object>(1);
String[] credentials = new String[] {args[1], args[2]};
env.put("jmx.remote.credentials", credentials);
Index: /java/server/branches/clustering/src/org/red5/server/BasicScope.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/BasicScope.java (revision 2133)
+++ /java/server/branches/clustering/src/org/red5/server/BasicScope.java (revision 2176)
@@ -116,5 +116,5 @@
public void removeEventListener(IEventListener listener) {
listeners.remove(listener);
- if (!keepOnDisconnect && ScopeUtils.isRoom(this) && isPersistent() && listeners.isEmpty()) {
+ if (!keepOnDisconnect && ScopeUtils.isRoom(this) && listeners.isEmpty()) {
// Delete empty rooms
parent.removeChildScope(this);
Index: /java/server/branches/clustering/src/org/red5/server/stream/DefaultStreamFilenameGenerator.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/stream/DefaultStreamFilenameGenerator.java (revision 1900)
+++ /java/server/branches/clustering/src/org/red5/server/stream/DefaultStreamFilenameGenerator.java (revision 2176)
@@ -67,3 +67,12 @@
}
+ /**
+ * The default filenames are relative to the scope path, so always return <code>false</code>.
+ *
+ * @return always <code>false</code>
+ */
+ public boolean resolvesToAbsolutePath() {
+ return false;
+ }
+
}
Index: /java/server/branches/clustering/src/org/red5/server/stream/ServerStream.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/stream/ServerStream.java (revision 1984)
+++ /java/server/branches/clustering/src/org/red5/server/stream/ServerStream.java (revision 2176)
@@ -321,15 +321,21 @@
String filename = generator.generateFilename(scope, name, ".flv", GenerationType.RECORD);
- Resource res = scope.getContext().getResource(filename);
+ // Get file for that filename
+ File file;
+ if (generator.resolvesToAbsolutePath()) {
+ file = new File(filename);
+ } else {
+ file = scope.getContext().getResource(filename).getFile();
+ }
if (!isAppend) {
- if (res.exists()) {
+ if (file.exists()) {
// Per livedoc of FCS/FMS:
// When "live" or "record" is used,
// any previously recorded stream with the same stream URI is deleted.
- if (!res.getFile().delete())
+ if (!file.delete())
throw new IOException("file could not be deleted");
}
} else {
- if (!res.exists()) {
+ if (!file.exists()) {
// Per livedoc of FCS/FMS:
// If a recorded stream at the same URI does not already exist,
@@ -339,8 +345,7 @@
}
- if (!res.exists()) {
+ if (!file.exists()) {
// Make sure the destination directory exists
- try {
- String path = res.getFile().getAbsolutePath();
+ String path = file.getAbsolutePath();
int slashPos = path.lastIndexOf(File.separator);
if (slashPos != -1) {
@@ -351,18 +356,14 @@
tmp.mkdirs();
}
- } catch (IOException err) {
- log.error("Could not create destination directory.", err);
- }
- res = scope.getResource(filename);
- }
-
- if (!res.exists()) {
- if (!res.getFile().canWrite()) {
- log.warn("File cannot be written to "
- + res.getFile().getCanonicalPath());
- }
- res.getFile().createNewFile();
- }
- FileConsumer fc = new FileConsumer(scope, res.getFile());
+ }
+
+ if (!file.exists()) {
+ if (!file.canWrite()) {
+ log.warn("File cannot be written to "
+ + file.getCanonicalPath());
+ }
+ file.createNewFile();
+ }
+ FileConsumer fc = new FileConsumer(scope, file);
Map<Object, Object> paramMap = new HashMap<Object, Object>();
if (isAppend) {
@@ -371,7 +372,7 @@
paramMap.put("mode", "record");
}
- if (null == recordPipe) {
- recordPipe = new InMemoryPushPushPipe();
- }
+ if (null == recordPipe) {
+ recordPipe = new InMemoryPushPushPipe();
+ }
recordPipe.subscribe(fc, paramMap);
recordingFilename = filename;
Index: /java/server/branches/clustering/src/org/red5/server/stream/BroadcastScope.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/stream/BroadcastScope.java (revision 1928)
+++ /java/server/branches/clustering/src/org/red5/server/stream/BroadcastScope.java (revision 2176)
@@ -168,5 +168,5 @@
* @return <code>true</code> on success, <code>false</code> otherwise
*/
- public synchronized boolean subscribe(IProvider provider, Map paramMap) {
+ public boolean subscribe(IProvider provider, Map paramMap) {
synchronized (pipe) {
return !hasRemoved && pipe.subscribe(provider, paramMap);
Index: /java/server/branches/clustering/src/org/red5/server/stream/ProviderService.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/stream/ProviderService.java (revision 2010)
+++ /java/server/branches/clustering/src/org/red5/server/stream/ProviderService.java (revision 2176)
@@ -101,6 +101,5 @@
File file = null;
try {
- file = scope.getContext().getResources(getStreamFilename(scope, name))[0]
- .getFile();
+ file = getStreamFile(scope, name);
} catch (IOException e) {
log.error("Problem getting file: " + name);
@@ -158,5 +157,5 @@
}
- private String getStreamFilename(IScope scope, String name) {
+ private File getStreamFile(IScope scope, String name) throws IOException {
IStreamableFileFactory factory = (IStreamableFileFactory) ScopeUtils
.getScopeService(scope, IStreamableFileFactory.class);
@@ -177,5 +176,13 @@
ScopeUtils.getScopeService(scope, IStreamFilenameGenerator.class, DefaultStreamFilenameGenerator.class);
- return filenameGenerator.generateFilename(scope, name, GenerationType.PLAYBACK);
+ String filename = filenameGenerator.generateFilename(scope, name, GenerationType.PLAYBACK);
+ File file;
+ if (filenameGenerator.resolvesToAbsolutePath()) {
+ file = new File(filename);
+ } else {
+ file = scope.getContext().getResource(filename).getFile();
+ }
+ return file;
+
}
Index: /java/server/branches/clustering/src/org/red5/server/stream/ClientBroadcastStream.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/stream/ClientBroadcastStream.java (revision 2034)
+++ /java/server/branches/clustering/src/org/red5/server/stream/ClientBroadcastStream.java (revision 2176)
@@ -229,6 +229,8 @@
&& (event.getType() != IEvent.Type.STREAM_CONTROL)
&& (event.getType() != IEvent.Type.STREAM_DATA) || closed) {
- //ignored event
- log.debug("dispatchEvent: " + event.getType());
+ // ignored event
+ if (log.isDebugEnabled()) {
+ log.debug("dispatchEvent: " + event.getType());
+ }
return;
}
@@ -505,5 +507,7 @@
public void saveAs(String name, boolean isAppend) throws IOException,
ResourceNotFoundException, ResourceExistException {
- log.debug("SaveAs - name: " + name + " append: " + isAppend);
+ if (log.isDebugEnabled()) {
+ log.debug("SaveAs - name: " + name + " append: " + isAppend);
+ }
// Get stream scope
IStreamCapableConnection conn = getConnection();
@@ -521,18 +525,23 @@
String filename = generator.generateFilename(scope, name, ".flv",
GenerationType.RECORD);
- // Get resource for that filename
- Resource res = scope.getContext().getResource(filename);
+ // Get file for that filename
+ File file;
+ if (generator.resolvesToAbsolutePath()) {
+ file = new File(filename);
+ } else {
+ file = scope.getContext().getResource(filename).getFile();
+ }
// If append mode is on...
if (!isAppend) {
- if (res.exists()) {
+ if (file.exists()) {
// Per livedoc of FCS/FMS:
// When "live" or "record" is used,
// any previously recorded stream with the same stream URI is deleted.
- if (!res.getFile().delete()) {
+ if (!file.delete()) {
throw new IOException("file could not be deleted");
}
}
} else {
- if (!res.exists()) {
+ if (!file.exists()) {
// Per livedoc of FCS/FMS:
// If a recorded stream at the same URI does not already exist,
@@ -542,7 +551,7 @@
}
- if (!res.exists()) {
+ if (!file.exists()) {
// Make sure the destination directory exists
- String path = res.getFile().getAbsolutePath();
+ String path = file.getAbsolutePath();
int slashPos = path.lastIndexOf(File.separator);
if (slashPos != -1) {
@@ -555,9 +564,11 @@
}
- if (!res.exists()) {
- res.getFile().createNewFile();
- }
- log.debug("Recording file: " + res.getFile().getCanonicalPath());
- recordingFile = new FileConsumer(scope, res.getFile());
+ if (!file.exists()) {
+ file.createNewFile();
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Recording file: " + file.getCanonicalPath());
+ }
+ recordingFile = new FileConsumer(scope, file);
Map<Object, Object> paramMap = new HashMap<Object, Object>();
if (isAppend) {
@@ -691,5 +702,7 @@
*/
public void setPublishedName(String name) {
- log.debug("setPublishedName: " + name);
+ if (log.isDebugEnabled()) {
+ log.debug("setPublishedName: " + name);
+ }
//check to see if we are setting the name to the same string
if (!name.equals(publishedName)) {
Index: /java/server/branches/clustering/src/org/red5/server/net/rtmp/RTMPMinaIoHandler.java
===================================================================
--- /java/server/branches/clustering/src/org/red5/server/net/rtmp/RTMPMinaIoHandler.java (revision 2133)
+++ /java/server/branches/clustering/src/org/red5/server/net/rtmp/RTMPMinaIoHandler.java (revision 2176)
@@ -148,5 +148,7 @@
out.put(in);
out.flip();
- rtmp.setHandshake(out, 1, Constants.HANDSHAKE_SIZE);
+ // Skip first 8 bytes when comparing the handshake, they seem to
+ // be changed when connecting from a Mac client.
+ rtmp.setHandshake(out, 9, Constants.HANDSHAKE_SIZE-8);
//in.release();
session.write(out);
Index: /java/server/branches/clustering/src/org/red5/server/net/rtmp/codec/RTMPProtocolDecoder.java
==========================
Note:
Diffs are chopped if more than 25k.
This is to get past the limit on the mailing list.
More information about the Red5commits
mailing list