public void publish(bool dontStop) { if (!dontStop) { IConnection connection = FluorineContext.Current.Connection; if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; int currentStreamId = this.GetCurrentStreamId(); IClientStream streamById = connection2.GetStreamById(currentStreamId); if (streamById is IBroadcastStream) { IBroadcastStream stream2 = streamById as IBroadcastStream; if (stream2.PublishedName != null) { IBroadcastScope broadcastScope = this.GetBroadcastScope(connection.Scope, stream2.PublishedName); if (broadcastScope != null) { broadcastScope.Unsubscribe(stream2.Provider); if (connection is BaseConnection) { (connection as BaseConnection).UnregisterBasicScope(broadcastScope); } } stream2.Close(); connection2.DeleteStreamById(currentStreamId); } } } } }
public void seek(double position) { IConnection connection = FluorineContext.Current.Connection; if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; int currentStreamId = this.GetCurrentStreamId(); IClientStream streamById = connection2.GetStreamById(currentStreamId); if ((streamById != null) && (streamById is ISubscriberStream)) { ISubscriberStream stream2 = streamById as ISubscriberStream; try { stream2.Seek((int)position); } catch (NotSupportedException exception) { StatusASO status = new StatusASO("NetStream.Seek.Failed") { clientid = currentStreamId, description = "The stream doesn't support seeking.", level = "error", details = exception.Message }; (connection2 as RtmpConnection).GetChannel((byte)(4 + ((currentStreamId - 1) * 5))).SendStatus(status); } } } }
public void publish(bool dontStop) { if (!dontStop) { IConnection connection = FluorineContext.Current.Connection; if (!(connection is IStreamCapableConnection)) { return; } IStreamCapableConnection streamConnection = connection as IStreamCapableConnection; int streamId = GetCurrentStreamId(); IClientStream stream = streamConnection.GetStreamById(streamId); if (!(stream is IBroadcastStream)) { return; } IBroadcastStream bs = stream as IBroadcastStream; if (bs.PublishedName == null) { return; } IBroadcastScope bsScope = GetBroadcastScope(connection.Scope, bs.PublishedName); if (bsScope != null) { bsScope.Unsubscribe(bs.Provider); if (connection is BaseConnection) { (connection as BaseConnection).UnregisterBasicScope(bsScope); } } bs.Close(); streamConnection.DeleteStreamById(streamId); } }
public void seek(double position) { IConnection connection = FluorineContext.Current.Connection; if (!(connection is IStreamCapableConnection)) { return; } IStreamCapableConnection streamConnection = connection as IStreamCapableConnection; int streamId = GetCurrentStreamId(); IClientStream stream = streamConnection.GetStreamById(streamId); if (stream == null || !(stream is ISubscriberStream)) { return; } ISubscriberStream subscriberStream = stream as ISubscriberStream; try { subscriberStream.Seek((int)position); } catch (NotSupportedException ex) { StatusASO seekFailed = new StatusASO(StatusASO.NS_SEEK_FAILED); seekFailed.clientid = streamId; seekFailed.description = "The stream doesn't support seeking."; seekFailed.level = "error"; seekFailed.details = ex.Message; // FIXME: there should be a direct way to send the status RtmpChannel channel = (streamConnection as RtmpConnection).GetChannel((byte)(4 + ((streamId - 1) * 5))); channel.SendStatus(seekFailed); } }
public void pause(bool pausePlayback, double position) { IConnection connection = FluorineContext.Current.Connection; if (!(connection is IStreamCapableConnection)) { return; } IStreamCapableConnection streamConnection = connection as IStreamCapableConnection; int streamId = GetCurrentStreamId(); IClientStream stream = streamConnection.GetStreamById(streamId); if (stream == null || !(stream is ISubscriberStream)) { return; } ISubscriberStream subscriberStream = stream as ISubscriberStream; if (pausePlayback) { subscriberStream.Pause((int)position); } else { subscriberStream.Resume((int)position); } }
/* * FlexInvoke flexInvoke = new FlexInvoke(); * flexInvoke.Cmd = "onstatus"; * flexInvoke.DataType = DataType.TypeUnknown; * StatusASO statusASO = StatusASO.GetStatusObject(StatusASO.NC_CONNECT_CLOSED, connection.ObjectEncoding); * flexInvoke.Parameters = new object[]{ statusASO }; * RtmpChannel channel = connection.GetChannel(3); * channel.Write(flexInvoke); */ protected override void OnChunkSize(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ChunkSize chunkSize) { if (connection is IStreamCapableConnection) { IStreamCapableConnection streamCapableConnection = connection as IStreamCapableConnection; { foreach (IClientStream stream in streamCapableConnection.GetStreams()) { if (stream is IClientBroadcastStream) { IClientBroadcastStream bs = stream as IClientBroadcastStream; IBroadcastScope scope = bs.Scope.GetBasicScope(Constants.BroadcastScopeType, bs.PublishedName) as IBroadcastScope; if (scope == null) { continue; } OOBControlMessage setChunkSize = new OOBControlMessage(); setChunkSize.Target = "ClientBroadcastStream"; setChunkSize.ServiceName = "chunkSize"; setChunkSize.ServiceParameterMap.Add("chunkSize", chunkSize.Size); scope.SendOOBControlMessage((IConsumer)null, setChunkSize); if (log.IsDebugEnabled) { log.Debug("Sending chunksize " + chunkSize + " to " + bs.Provider); } } } } } }
protected override void OnChunkSize(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ChunkSize chunkSize) { if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; foreach (IClientStream stream in connection2.GetStreams()) { if (stream is IClientBroadcastStream) { IClientBroadcastStream stream2 = stream as IClientBroadcastStream; IBroadcastScope basicScope = stream2.Scope.GetBasicScope("bs", stream2.PublishedName) as IBroadcastScope; if (basicScope != null) { OOBControlMessage oobCtrlMsg = new OOBControlMessage { Target = "ClientBroadcastStream", ServiceName = "chunkSize" }; oobCtrlMsg.ServiceParameterMap.Add("chunkSize", chunkSize.Size); basicScope.SendOOBControlMessage(null, oobCtrlMsg); if (log.get_IsDebugEnabled()) { log.Debug(string.Concat(new object[] { "Sending chunksize ", chunkSize, " to ", stream2.Provider })); } } } } } }
public void deleteStream(int streamId) { IConnection connection = FluorineContext.Current.Connection; if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; this.deleteStream(connection2, streamId); } }
public void deleteStream(int streamId) { IConnection connection = FluorineContext.Current.Connection; if (!(connection is IStreamCapableConnection)) { return; } IStreamCapableConnection streamConnection = connection as IStreamCapableConnection; deleteStream(streamConnection, streamId); }
public void deleteStream(IStreamCapableConnection connection, int streamId) { IClientStream stream = connection.GetStreamById(streamId); if (stream != null) { if (stream is IClientBroadcastStream) { IClientBroadcastStream bs = stream as IClientBroadcastStream; IBroadcastScope bsScope = GetBroadcastScope(connection.Scope, bs.PublishedName); if (bsScope != null && connection is BaseConnection) { (connection as BaseConnection).UnregisterBasicScope(bsScope); } } stream.Close(); } connection.UnreserveStreamId(streamId); }
public void receiveVideo(bool receive) { IConnection connection = FluorineContext.Current.Connection; if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; int currentStreamId = this.GetCurrentStreamId(); IClientStream streamById = connection2.GetStreamById(currentStreamId); if ((streamById != null) && (streamById is ISubscriberStream)) { (streamById as ISubscriberStream).ReceiveVideo(receive); } } }
public IMessageOutput GetConsumerOutput(IClientStream stream) { IStreamCapableConnection connection = stream.Connection; if (!((connection != null) && (connection is RtmpConnection))) { return(null); } RtmpConnection connection2 = connection as RtmpConnection; OutputStream stream2 = connection2.CreateOutputStream(stream.StreamId); IPipe pipe = new InMemoryPushPushPipe(); pipe.Subscribe(new ConnectionConsumer(connection2, stream2.Video.ChannelId, stream2.Audio.ChannelId, stream2.Data.ChannelId), null); return(pipe); }
public void play(bool dontStop) { if (!dontStop) { IConnection connection = FluorineContext.Current.Connection; if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; int currentStreamId = this.GetCurrentStreamId(); IClientStream streamById = connection2.GetStreamById(currentStreamId); if (streamById != null) { streamById.Stop(); } } } }
public IMessageOutput GetConsumerOutput(IClientStream stream) { IStreamCapableConnection streamConnection = stream.Connection; if (streamConnection == null || !(streamConnection is RtmpConnection)) { return(null); } RtmpConnection connection = streamConnection as RtmpConnection; // TODO Better manage channels. // now we use OutputStream as a channel wrapper. OutputStream outputStream = connection.CreateOutputStream(stream.StreamId); IPipe pipe = new InMemoryPushPushPipe(); pipe.Subscribe(new ConnectionConsumer(connection, outputStream.Video.ChannelId, outputStream.Audio.ChannelId, outputStream.Data.ChannelId), null); return(pipe); }
public void play(bool dontStop) { if (!dontStop) { IConnection connection = FluorineContext.Current.Connection; if (!(connection is IStreamCapableConnection)) { return; } IStreamCapableConnection streamConnection = connection as IStreamCapableConnection; int streamId = GetCurrentStreamId(); IClientStream stream = streamConnection.GetStreamById(streamId); if (stream != null) { stream.Stop(); } } }
public void deleteStream(IStreamCapableConnection connection, int streamId) { IClientStream streamById = connection.GetStreamById(streamId); if (streamById != null) { if (streamById is IClientBroadcastStream) { IClientBroadcastStream stream2 = streamById as IClientBroadcastStream; IBroadcastScope broadcastScope = this.GetBroadcastScope(connection.Scope, stream2.PublishedName); if ((broadcastScope != null) && (connection is BaseConnection)) { (connection as BaseConnection).UnregisterBasicScope(broadcastScope); } } streamById.Close(); } connection.UnreserveStreamId(streamId); }
public void receiveAudio(bool receive) { IConnection connection = FluorineContext.Current.Connection; if (!(connection is IStreamCapableConnection)) { return; } IStreamCapableConnection streamConnection = connection as IStreamCapableConnection; int streamId = GetCurrentStreamId(); IClientStream stream = streamConnection.GetStreamById(streamId); if (stream == null || !(stream is ISubscriberStream)) { return; } ISubscriberStream subscriberStream = stream as ISubscriberStream; subscriberStream.ReceiveAudio(receive); }
public void pause(bool pausePlayback, double position) { IConnection connection = FluorineContext.Current.Connection; if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; int currentStreamId = this.GetCurrentStreamId(); IClientStream streamById = connection2.GetStreamById(currentStreamId); if ((streamById != null) && (streamById is ISubscriberStream)) { ISubscriberStream stream2 = streamById as ISubscriberStream; if (pausePlayback) { stream2.Pause((int)position); } else { stream2.Resume((int)position); } } } }
/// <summary> /// Saves broadcasted stream. /// </summary> /// <param name="name"></param> /// <param name="isAppend"></param> public void SaveAs(string name, bool isAppend) { if (log.IsDebugEnabled) { log.Debug("SaveAs - name: " + name + " append: " + isAppend); } // Get stream scope IStreamCapableConnection connection = this.Connection; if (connection == null) { // TODO: throw other exception here? throw new IOException("Stream is no longer connected"); } IScope scope = connection.Scope; // Get stream filename generator IStreamFilenameGenerator generator = ScopeUtils.GetScopeService(scope, typeof(IStreamFilenameGenerator)) as IStreamFilenameGenerator; // Generate filename string filename = generator.GenerateFilename(scope, name, ".flv", GenerationType.RECORD); // Get file for that filename FileInfo file; if (generator.ResolvesToAbsolutePath) { file = new FileInfo(filename); } else { file = scope.Context.GetResource(filename).File; } // If append mode is on... if (!isAppend) { 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. file.Delete(); } } else { if (!file.Exists) { // Per livedoc of FCS/FMS: // If a recorded stream at the same URI does not already exist, // "append" creates the stream as though "record" was passed. isAppend = false; } } //Requery file = new FileInfo(file.FullName); if (!file.Exists) { // Make sure the destination directory exists string directory = Path.GetDirectoryName(file.FullName); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } } if (!file.Exists) { using (FileStream fs = file.Create()) { } } if (log.IsDebugEnabled) { log.Debug("Recording file: " + file.FullName); } _recordingFile = new FileConsumer(scope, file); #if !(NET_1_1) Dictionary <string, object> parameterMap = new Dictionary <string, object>(); #else Hashtable parameterMap = new Hashtable(); #endif if (isAppend) { parameterMap.Add("mode", "append"); } else { parameterMap.Add("mode", "record"); } _recordPipe.Subscribe(_recordingFile, parameterMap); _recording = true; _recordingFilename = filename; }
public void SaveAs(string name, bool isAppend) { FileInfo file; if (log.get_IsDebugEnabled()) { log.Debug(string.Concat(new object[] { "SaveAs - name: ", name, " append: ", isAppend })); } IStreamCapableConnection connection = base.Connection; if (connection == null) { throw new IOException("Stream is no longer connected"); } IScope scope = connection.Scope; IStreamFilenameGenerator scopeService = ScopeUtils.GetScopeService(scope, typeof(IStreamFilenameGenerator)) as IStreamFilenameGenerator; string fileName = scopeService.GenerateFilename(scope, name, ".flv", GenerationType.RECORD); if (scopeService.ResolvesToAbsolutePath) { file = new FileInfo(fileName); } else { file = scope.Context.GetResource(fileName).File; } if (!isAppend) { if (file.Exists) { file.Delete(); } } else if (!file.Exists) { isAppend = false; } file = new FileInfo(file.FullName); if (!file.Exists) { string directoryName = Path.GetDirectoryName(file.FullName); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } } if (!file.Exists) { using (file.Create()) { } } if (log.get_IsDebugEnabled()) { log.Debug("Recording file: " + file.FullName); } this._recordingFile = new FileConsumer(scope, file); Dictionary <string, object> parameterMap = new Dictionary <string, object>(); if (isAppend) { parameterMap.Add("mode", "append"); } else { parameterMap.Add("mode", "record"); } this._recordPipe.Subscribe(this._recordingFile, parameterMap); this._recording = true; this._recordingFilename = fileName; }
public void play(string name, double start, double length, bool flushPlaylist) { IConnection connection = FluorineContext.Current.Connection; if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; IScope scope = connection.Scope; int currentStreamId = this.GetCurrentStreamId(); if ((name == null) || string.Empty.Equals(name)) { this.SendNSFailed(connection2 as RtmpConnection, "The stream name may not be empty.", name, currentStreamId); } else { IStreamSecurityService scopeService = ScopeUtils.GetScopeService(scope, typeof(IStreamSecurityService)) as IStreamSecurityService; if (scopeService != null) { IEnumerator streamPlaybackSecurity = scopeService.GetStreamPlaybackSecurity(); while (streamPlaybackSecurity.MoveNext()) { IStreamPlaybackSecurity current = streamPlaybackSecurity.Current as IStreamPlaybackSecurity; if (!current.IsPlaybackAllowed(scope, name, (long)start, (long)length, flushPlaylist)) { this.SendNSFailed(connection2 as RtmpConnection, "You are not allowed to play the stream.", name, currentStreamId); return; } } } IClientStream streamById = connection2.GetStreamById(currentStreamId); bool flag = false; if (streamById == null) { streamById = connection2.NewPlaylistSubscriberStream(currentStreamId); streamById.Start(); flag = true; } if (streamById is ISubscriberStream) { ISubscriberStream stream2 = streamById as ISubscriberStream; SimplePlayItem item = new SimplePlayItem { Name = name, Start = (long)start, Length = (long)length }; if (stream2 is IPlaylistSubscriberStream) { IPlaylistSubscriberStream stream3 = stream2 as IPlaylistSubscriberStream; if (flushPlaylist) { stream3.RemoveAllItems(); } stream3.AddItem(item); } else if (stream2 is ISingleItemSubscriberStream) { ISingleItemSubscriberStream stream4 = stream2 as ISingleItemSubscriberStream; stream4.PlayItem = item; } else { return; } try { stream2.Play(); } catch (IOException exception) { if (flag) { streamById.Close(); connection2.DeleteStreamById(currentStreamId); } this.SendNSFailed(connection2 as RtmpConnection, exception.Message, name, currentStreamId); } } } } }
public void publish(string name, string mode) { IConnection connection = FluorineContext.Current.Connection; if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; IScope scope = connection.Scope; int currentStreamId = this.GetCurrentStreamId(); if ((name == null) || string.Empty.Equals(name)) { this.SendNSFailed(connection2 as RtmpConnection, "The stream name may not be empty.", name, currentStreamId); } else { IStreamSecurityService scopeService = ScopeUtils.GetScopeService(scope, typeof(IStreamSecurityService)) as IStreamSecurityService; if (scopeService != null) { IEnumerator streamPublishSecurity = scopeService.GetStreamPublishSecurity(); while (streamPublishSecurity.MoveNext()) { IStreamPublishSecurity current = streamPublishSecurity.Current as IStreamPublishSecurity; if (!current.IsPublishAllowed(scope, name, mode)) { this.SendNSFailed(connection2 as RtmpConnection, "You are not allowed to publish the stream.", name, currentStreamId); return; } } } IBroadcastScope broadcastScope = this.GetBroadcastScope(scope, name); if ((broadcastScope != null) && (broadcastScope.GetProviders().Count > 0)) { StatusASO status = new StatusASO("NetStream.Publish.BadName") { clientid = currentStreamId, details = name, level = "error" }; (connection2 as RtmpConnection).GetChannel((byte)(4 + ((currentStreamId - 1) * 5))).SendStatus(status); } else { IClientStream streamById = connection2.GetStreamById(currentStreamId); if ((streamById == null) || (streamById is IClientBroadcastStream)) { bool flag = false; if (streamById == null) { streamById = connection2.NewBroadcastStream(currentStreamId); flag = true; } IClientBroadcastStream broadcastStream = streamById as IClientBroadcastStream; try { broadcastStream.PublishedName = name; IScopeContext context = connection.Scope.Context; IProviderService service2 = ScopeUtils.GetScopeService(connection.Scope, typeof(IProviderService)) as IProviderService; if (service2.RegisterBroadcastStream(connection.Scope, name, broadcastStream)) { broadcastScope = this.GetBroadcastScope(connection.Scope, name); broadcastScope.SetAttribute("_transient_publishing_stream", broadcastStream); if (connection is BaseConnection) { (connection as BaseConnection).RegisterBasicScope(broadcastScope); } } if ("record".Equals(mode)) { broadcastStream.Start(); broadcastStream.SaveAs(name, false); } else if ("append".Equals(mode)) { broadcastStream.Start(); broadcastStream.SaveAs(name, true); } else if ("live".Equals(mode)) { broadcastStream.Start(); } broadcastStream.StartPublishing(); } catch (IOException exception) { StatusASO saso2 = new StatusASO("NetStream.Record.NoAccess") { clientid = currentStreamId, description = "The file could not be created/written to." + exception.Message, details = name, level = "error" }; (connection2 as RtmpConnection).GetChannel((byte)(4 + ((currentStreamId - 1) * 5))).SendStatus(saso2); broadcastStream.Close(); if (flag) { connection2.DeleteStreamById(currentStreamId); } } catch (Exception exception2) { log.Warn("Publish caught exception", exception2); } } } } } }
public void publish(string name, string mode) { IConnection connection = FluorineContext.Current.Connection; if (!(connection is IStreamCapableConnection)) { return; } IStreamCapableConnection streamConnection = connection as IStreamCapableConnection; IScope scope = connection.Scope; int streamId = GetCurrentStreamId(); if (name == null || string.Empty.Equals(name)) { SendNSFailed(streamConnection as RtmpConnection, "The stream name may not be empty.", name, streamId); return; } IStreamSecurityService security = ScopeUtils.GetScopeService(scope, typeof(IStreamSecurityService)) as IStreamSecurityService; if (security != null) { IEnumerator handlers = security.GetStreamPublishSecurity(); while (handlers.MoveNext()) { IStreamPublishSecurity handler = handlers.Current as IStreamPublishSecurity; if (!handler.IsPublishAllowed(scope, name, mode)) { SendNSFailed(streamConnection as RtmpConnection, "You are not allowed to publish the stream.", name, streamId); return; } } } IBroadcastScope bsScope = GetBroadcastScope(scope, name); if (bsScope != null && bsScope.GetProviders().Count > 0) { // Another stream with that name is already published. StatusASO badName = new StatusASO(StatusASO.NS_PUBLISH_BADNAME); badName.clientid = streamId; badName.details = name; badName.level = "error"; // FIXME: there should be a direct way to send the status RtmpChannel channel = (streamConnection as RtmpConnection).GetChannel((byte)(4 + ((streamId - 1) * 5))); channel.SendStatus(badName); return; } IClientStream stream = streamConnection.GetStreamById(streamId); if (stream != null && !(stream is IClientBroadcastStream)) { return; } bool created = false; if (stream == null) { stream = streamConnection.NewBroadcastStream(streamId); created = true; } IClientBroadcastStream bs = stream as IClientBroadcastStream; try { bs.PublishedName = name; IScopeContext context = connection.Scope.Context; //IProviderService providerService = (IProviderService)context.getBean(IProviderService.BEAN_NAME); IProviderService providerService = ScopeUtils.GetScopeService(connection.Scope, typeof(IProviderService)) as IProviderService; // TODO handle registration failure if (providerService.RegisterBroadcastStream(connection.Scope, name, bs)) { bsScope = GetBroadcastScope(connection.Scope, name); bsScope.SetAttribute(Constants.BroadcastScopeStreamAttribute, bs); if (connection is BaseConnection) { (connection as BaseConnection).RegisterBasicScope(bsScope); } } if (Constants.ClientStreamModeRecord.Equals(mode)) { bs.Start(); bs.SaveAs(name, false); } else if (Constants.ClientStreamModeAppend.Equals(mode)) { bs.Start(); bs.SaveAs(name, true); } else if (Constants.ClientStreamModeLive.Equals(mode)) { bs.Start(); } bs.StartPublishing(); } catch (System.IO.IOException ex) { StatusASO accessDenied = new StatusASO(StatusASO.NS_RECORD_NOACCESS); accessDenied.clientid = streamId; accessDenied.description = "The file could not be created/written to." + ex.Message; accessDenied.details = name; accessDenied.level = "error"; // FIXME: there should be a direct way to send the status RtmpChannel channel = (streamConnection as RtmpConnection).GetChannel((byte)(4 + ((streamId - 1) * 5))); channel.SendStatus(accessDenied); bs.Close(); if (created) { streamConnection.DeleteStreamById(streamId); } } catch (Exception ex) { log.Warn("Publish caught exception", ex); } }
public void play(string name, double start, double length, bool flushPlaylist) { IConnection connection = FluorineContext.Current.Connection; if (!(connection is IStreamCapableConnection)) { return; } IStreamCapableConnection streamConnection = connection as IStreamCapableConnection; IScope scope = connection.Scope; int streamId = GetCurrentStreamId(); if (name == null || string.Empty.Equals(name)) { SendNSFailed(streamConnection as RtmpConnection, "The stream name may not be empty.", name, streamId); return; } IStreamSecurityService security = ScopeUtils.GetScopeService(scope, typeof(IStreamSecurityService)) as IStreamSecurityService; if (security != null) { IEnumerator handlers = security.GetStreamPlaybackSecurity(); while (handlers.MoveNext()) { IStreamPlaybackSecurity handler = handlers.Current as IStreamPlaybackSecurity; if (!handler.IsPlaybackAllowed(scope, name, (long)start, (long)length, flushPlaylist)) { SendNSFailed(streamConnection as RtmpConnection, "You are not allowed to play the stream.", name, streamId); return; } } } IClientStream stream = streamConnection.GetStreamById(streamId); bool created = false; if (stream == null) { stream = streamConnection.NewPlaylistSubscriberStream(streamId); stream.Start(); created = true; } if (!(stream is ISubscriberStream)) { return; } ISubscriberStream subscriberStream = stream as ISubscriberStream; SimplePlayItem item = new SimplePlayItem(); item.Name = name; item.Start = (long)start; item.Length = (long)length; if (subscriberStream is IPlaylistSubscriberStream) { IPlaylistSubscriberStream playlistStream = subscriberStream as IPlaylistSubscriberStream; if (flushPlaylist) { playlistStream.RemoveAllItems(); } playlistStream.AddItem(item); } else if (subscriberStream is ISingleItemSubscriberStream) { ISingleItemSubscriberStream singleStream = subscriberStream as ISingleItemSubscriberStream; singleStream.PlayItem = item; } else { // not supported by this stream service return; } try { subscriberStream.Play(); } catch (System.IO.IOException ex) { if (created) { stream.Close(); streamConnection.DeleteStreamById(streamId); } SendNSFailed(streamConnection as RtmpConnection, ex.Message, name, streamId); } }