/**
  * Close stream. This method can close both IClientBroadcastStream (coming from Flash Player to
  * Red5) and ISubscriberStream (from Red5 to Flash Player). Corresponding application handlers
  * (streamSubscriberClose, etc.) are called as if close was initiated by Flash Player.
  *
  * <p>It is recommended to remember stream id in application handlers, ex.:
  *
  * <pre>
  * public void streamBroadcastStart(IBroadcastStream stream) {
  * 	super.streamBroadcastStart(stream);
  * 	if (stream instanceof IClientBroadcastStream) {
  * 		int publishedStreamId = ((ClientBroadcastStream)stream).getStreamId();
  * 		Red5.getConnectionLocal().setAttribute(PUBLISHED_STREAM_ID_ATTRIBUTE, publishedStreamId);
  * 	}
  * }
  * </pre>
  *
  * <pre>
  * public void streamPlaylistItemPlay(IPlaylistSubscriberStream stream, IPlayItem item, boolean isLive) {
  * 	super.streamPlaylistItemPlay(stream, item, isLive);
  * 	Red5.getConnectionLocal().setAttribute(WATCHED_STREAM_ID_ATTRIBUTE, stream.getStreamId());
  * }
  * </pre>
  *
  * When stream is closed, corresponding NetStream status will be sent to stream provider /
  * consumers. Implementation is based on Red5's StreamService.close()
  *
  * @param conn client connection
  * @param streamId stream ID (number: 1,2,...)
  */
 public void closeStream(IConnection conn, int streamId) {
   log.info("closeStream: streamId={}, connection={}", streamId, conn);
   if (conn instanceof IStreamCapableConnection) {
     IStreamCapableConnection scConn = (IStreamCapableConnection) conn;
     IClientStream stream = scConn.getStreamById(streamId);
     if (stream != null) {
       if (stream instanceof IClientBroadcastStream) {
         // this is a broadcasting stream (from Flash Player to Red5)
         IClientBroadcastStream bs = (IClientBroadcastStream) stream;
         IBroadcastScope bsScope = getBroadcastScope(conn.getScope(), bs.getPublishedName());
         if (bsScope != null && conn instanceof BaseConnection) {
           ((BaseConnection) conn).unregisterBasicScope(bsScope);
         }
       }
       stream.close();
       scConn.deleteStreamById(streamId);
       // in case of broadcasting stream, status is sent automatically by Red5
       if (!(stream instanceof IClientBroadcastStream)) {
         StreamService.sendNetStreamStatus(
             conn,
             StatusCodes.NS_PLAY_STOP,
             "Stream closed by server",
             stream.getName(),
             Status.STATUS,
             streamId);
       }
     } else {
       log.info("Stream not found: streamId={}, connection={}", streamId, conn);
     }
   } else {
     log.warn("Connection is not instance of IStreamCapableConnection: {}", conn);
   }
 }
 /** {@inheritDoc} */
 public void deleteStream(IStreamCapableConnection conn, int streamId) {
   IClientStream stream = conn.getStreamById(streamId);
   if (stream != null) {
     if (stream instanceof IClientBroadcastStream) {
       IClientBroadcastStream bs = (IClientBroadcastStream) stream;
       IBroadcastScope bsScope = getBroadcastScope(conn.getScope(), bs.getPublishedName());
       if (bsScope != null && conn instanceof BaseConnection) {
         ((BaseConnection) conn).unregisterBasicScope(bsScope);
       }
     }
     stream.close();
   }
   conn.unreserveStreamId(streamId);
 }
 public RTMPConnection createConnection(Class<?> connCls) {
   log.debug("Creating connection, class: {}", connCls.getName());
   if (!RTMPConnection.class.isAssignableFrom(connCls)) {
     throw new IllegalArgumentException("Class was not assignable");
   }
   try {
     RTMPConnection conn = (RTMPConnection) connCls.newInstance();
     // the id may become confused with the Object/String client id
     conn.setId(BaseConnection.getNextClientId());
     log.debug("Connection id set {}", conn.getId());
     rtmpConnections.add(conn);
     log.debug("Connection added to the map");
     return conn;
   } catch (Exception e) {
     log.error("RTMPConnection creation failed", e);
     throw new RuntimeException(e);
   }
 }
 /** {@inheritDoc} */
 public void initStream(int streamId) {
   IConnection conn = Red5.getConnectionLocal();
   log.info("initStream: id={} current id: {} connection={}", streamId, conn.getStreamId(), conn);
   if (conn instanceof IStreamCapableConnection) {
     ((IStreamCapableConnection) conn).reserveStreamId(streamId);
     IClientStream stream = ((IStreamCapableConnection) conn).getStreamById(streamId);
     if (stream != null) {
       if (stream instanceof IClientBroadcastStream) {
         IClientBroadcastStream bs = (IClientBroadcastStream) stream;
         IBroadcastScope bsScope = getBroadcastScope(conn.getScope(), bs.getPublishedName());
         if (bsScope != null && conn instanceof BaseConnection) {
           ((BaseConnection) conn).unregisterBasicScope(bsScope);
         }
       }
       stream.close();
     }
     ((IStreamCapableConnection) conn).deleteStreamById(streamId);
   } else {
     log.warn("ERROR in intiStream, connection is not stream capable");
   }
 }
  /** {@inheritDoc} */
  @Override
  public void close() {
    getWriteLock().lock();
    try {
      if (keepAliveJobName != null) {
        schedulingService.removeScheduledJob(keepAliveJobName);
        keepAliveJobName = null;
      }
    } finally {
      getWriteLock().unlock();
    }
    Red5.setConnectionLocal(this);
    IStreamService streamService =
        (IStreamService) getScopeService(scope, IStreamService.class, StreamService.class);
    if (streamService != null) {
      for (Map.Entry<Integer, IClientStream> entry : streams.entrySet()) {
        IClientStream stream = entry.getValue();
        if (stream != null) {
          log.debug("Closing stream: {}", stream.getStreamId());
          streamService.deleteStream(this, stream.getStreamId());
          usedStreams.decrementAndGet();
        }
      }
      streams.clear();
    }
    channels.clear();

    getWriteLock().lock();
    try {
      if (bwContext != null && getScope() != null && getScope().getContext() != null) {
        IBWControlService bwController =
            (IBWControlService) getScope().getContext().getBean(IBWControlService.KEY);
        bwController.unregisterBWControllable(bwContext);
        bwContext = null;
      }
    } finally {
      getWriteLock().unlock();
    }
    super.close();
  }
 /** {@inheritDoc} */
 public void publish(Boolean dontStop) {
   if (!dontStop) {
     IConnection conn = Red5.getConnectionLocal();
     if (conn instanceof IStreamCapableConnection) {
       IStreamCapableConnection streamConn = (IStreamCapableConnection) conn;
       int streamId = conn.getStreamId();
       IClientStream stream = streamConn.getStreamById(streamId);
       if (stream instanceof IBroadcastStream) {
         IBroadcastStream bs = (IBroadcastStream) stream;
         if (bs.getPublishedName() != null) {
           IBroadcastScope bsScope = getBroadcastScope(conn.getScope(), bs.getPublishedName());
           if (bsScope != null) {
             bsScope.unsubscribe(bs.getProvider());
             if (conn instanceof BaseConnection) {
               ((BaseConnection) conn).unregisterBasicScope(bsScope);
             }
           }
           bs.close();
           streamConn.deleteStreamById(streamId);
         }
       }
     }
   }
 }
Exemple #7
0
 /** {@inheritDoc} */
 @Override
 public void close() {
   getWriteLock().lock();
   try {
     if (keepAliveJobName != null) {
       schedulingService.removeScheduledJob(keepAliveJobName);
       keepAliveJobName = null;
     }
   } finally {
     getWriteLock().unlock();
   }
   Red5.setConnectionLocal(this);
   IStreamService streamService =
       (IStreamService) getScopeService(scope, IStreamService.class, StreamService.class);
   if (streamService != null) {
     for (Map.Entry<Integer, IClientStream> entry : streams.entrySet()) {
       IClientStream stream = entry.getValue();
       if (stream != null) {
         log.debug("Closing stream: {}", stream.getStreamId());
         streamService.deleteStream(this, stream.getStreamId());
         usedStreams.decrementAndGet();
       }
     }
   }
   // close the base connection - disconnect scopes and unregister client
   super.close();
   // kill all the collections etc
   if (channels != null) {
     channels.clear();
     channels = null;
   } else {
     log.trace("Channels collection was null");
   }
   if (streams != null) {
     streams.clear();
     streams = null;
   } else {
     log.trace("Streams collection was null");
   }
   if (pendingCalls != null) {
     pendingCalls.clear();
     pendingCalls = null;
   } else {
     log.trace("PendingCalls collection was null");
   }
   if (deferredResults != null) {
     deferredResults.clear();
     deferredResults = null;
   } else {
     log.trace("DeferredResults collection was null");
   }
   if (pendingVideos != null) {
     pendingVideos.clear();
     pendingVideos = null;
   } else {
     log.trace("PendingVideos collection was null");
   }
   if (streamBuffers != null) {
     streamBuffers.clear();
     streamBuffers = null;
   } else {
     log.trace("StreamBuffers collection was null");
   }
 }
 /** {@inheritDoc} */
 public void publish(String name, String mode) {
   Map<String, String> params = null;
   if (name != null && name.contains("?")) {
     // read and utilize the query string values
     params = new HashMap<String, String>();
     String tmp = name;
     // check if we start with '?' or not
     if (name.charAt(0) != '?') {
       tmp = name.split("\\?")[1];
     } else if (name.charAt(0) == '?') {
       tmp = name.substring(1);
     }
     // now break up into key/value blocks
     String[] kvs = tmp.split("&");
     // take each key/value block and break into its key value parts
     for (String kv : kvs) {
       String[] split = kv.split("=");
       params.put(split[0], split[1]);
     }
     // grab the streams name
     name = name.substring(0, name.indexOf("?"));
   }
   log.debug("publish called with name {} and mode {}", name, mode);
   IConnection conn = Red5.getConnectionLocal();
   if (conn instanceof IStreamCapableConnection) {
     IScope scope = conn.getScope();
     IStreamCapableConnection streamConn = (IStreamCapableConnection) conn;
     int streamId = conn.getStreamId();
     if (StringUtils.isEmpty(name)) {
       sendNSFailed(
           streamConn, StatusCodes.NS_FAILED, "The stream name may not be empty.", name, streamId);
       log.error("The stream name may not be empty.");
       return;
     }
     IStreamSecurityService security =
         (IStreamSecurityService) ScopeUtils.getScopeService(scope, IStreamSecurityService.class);
     if (security != null) {
       Set<IStreamPublishSecurity> handlers = security.getStreamPublishSecurity();
       for (IStreamPublishSecurity handler : handlers) {
         if (!handler.isPublishAllowed(scope, name, mode)) {
           sendNSFailed(
               streamConn,
               StatusCodes.NS_PUBLISH_BADNAME,
               "You are not allowed to publish the stream.",
               name,
               streamId);
           log.error("You are not allowed to publish the stream {}", name);
           return;
         }
       }
     }
     IBroadcastScope bsScope = getBroadcastScope(scope, name);
     if (bsScope != null && !bsScope.getProviders().isEmpty()) {
       // another stream with that name is already published
       sendNSFailed(streamConn, StatusCodes.NS_PUBLISH_BADNAME, name, name, streamId);
       log.error("Bad name {}", name);
       return;
     }
     IClientStream stream = streamConn.getStreamById(streamId);
     if (stream != null && !(stream instanceof IClientBroadcastStream)) {
       log.error(
           "Stream not found or is not instance of IClientBroadcastStream, name: {}, streamId: {}",
           name,
           streamId);
       return;
     }
     boolean created = false;
     if (stream == null) {
       stream = streamConn.newBroadcastStream(streamId);
       created = true;
     }
     IClientBroadcastStream bs = (IClientBroadcastStream) stream;
     try {
       // set publish name
       bs.setPublishedName(name);
       // set stream parameters if they exist
       if (params != null) {
         bs.setParameters(params);
       }
       IContext context = conn.getScope().getContext();
       IProviderService providerService =
           (IProviderService) context.getBean(IProviderService.BEAN_NAME);
       // TODO handle registration failure
       if (providerService.registerBroadcastStream(conn.getScope(), name, bs)) {
         bsScope = getBroadcastScope(conn.getScope(), name);
         bsScope.setClientBroadcastStream(bs);
         if (conn instanceof BaseConnection) {
           ((BaseConnection) conn).registerBasicScope(bsScope);
         }
       }
       log.debug("Mode: {}", mode);
       if (IClientStream.MODE_RECORD.equals(mode)) {
         bs.start();
         bs.saveAs(name, false);
       } else if (IClientStream.MODE_APPEND.equals(mode)) {
         bs.start();
         bs.saveAs(name, true);
       } else {
         bs.start();
       }
       bs.startPublishing();
     } catch (IOException e) {
       log.warn("Stream I/O exception", e);
       sendNSFailed(
           streamConn,
           StatusCodes.NS_RECORD_NOACCESS,
           "The file could not be created/written to.",
           name,
           streamId);
       bs.close();
       if (created) {
         streamConn.deleteStreamById(streamId);
       }
     } catch (Exception e) {
       log.warn("Exception on publish", e);
     }
   }
 }