/** * 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 seek(int position) { log.trace("seek - position:{}", position); IConnection conn = Red5.getConnectionLocal(); if (conn instanceof IStreamCapableConnection) { IStreamCapableConnection streamConn = (IStreamCapableConnection) conn; int streamId = conn.getStreamId(); IClientStream stream = streamConn.getStreamById(streamId); if (stream != null && stream instanceof ISubscriberStream) { ISubscriberStream subscriberStream = (ISubscriberStream) stream; try { subscriberStream.seek(position); } catch (OperationNotSupportedException err) { sendNSFailed( streamConn, StatusCodes.NS_SEEK_FAILED, "The stream doesn't support seeking.", stream.getName(), streamId); } } } }