Example #1
0
        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);
            }
        }
Example #2
0
        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);
                    }
                }
            }
        }
Example #3
0
 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);
                 }
             }
         }
     }
 }
Example #4
0
        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);
            }
        }
Example #5
0
        public void closeStream()
        {
            IConnection connection = FluorineContext.Current.Connection;

            if (!(connection is IStreamCapableConnection))
            {
                return;
            }

            IClientStream stream = (connection as IStreamCapableConnection).GetStreamById(GetCurrentStreamId());

            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 as IStreamCapableConnection).DeleteStreamById(GetCurrentStreamId());
        }
 protected void RegisterStream(IClientStream stream)
 {
     lock (((ICollection)this._streams).SyncRoot)
     {
         this._streams[stream.StreamId - 1] = stream;
     }
 }
Example #7
0
 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 OnOOBControlMessage(IMessageComponent source, IPipe pipe, OOBControlMessage oobCtrlMsg)
 {
     if ("ConnectionConsumer".Equals(oobCtrlMsg.Target))
     {
         if ("pendingCount".Equals(oobCtrlMsg.ServiceName))
         {
             oobCtrlMsg.Result = this._connection.PendingMessages;
         }
         else if ("pendingVideoCount".Equals(oobCtrlMsg.ServiceName))
         {
             IClientStream streamByChannelId = null;
             if (this._connection is IStreamCapableConnection)
             {
                 streamByChannelId = (this._connection as IStreamCapableConnection).GetStreamByChannelId(this._video.ChannelId);
             }
             if (streamByChannelId != null)
             {
                 oobCtrlMsg.Result = this._connection.GetPendingVideoMessages(streamByChannelId.StreamId);
             }
             else
             {
                 oobCtrlMsg.Result = 0L;
             }
         }
         else if ("writeDelta".Equals(oobCtrlMsg.ServiceName))
         {
             long            num = 0L;
             IBWControllable parentBWControllable = this._connection as IBWControllable;
             while ((parentBWControllable != null) && (parentBWControllable.BandwidthConfiguration == null))
             {
                 parentBWControllable = parentBWControllable.GetParentBWControllable();
             }
             if ((parentBWControllable != null) && (parentBWControllable.BandwidthConfiguration != null))
             {
                 IBandwidthConfigure bandwidthConfiguration = parentBWControllable.BandwidthConfiguration;
                 if (bandwidthConfiguration is IConnectionBWConfig)
                 {
                     num = (bandwidthConfiguration as IConnectionBWConfig).DownstreamBandwidth / 8L;
                 }
             }
             if (num <= 0L)
             {
                 num = 0x1e000L;
             }
             oobCtrlMsg.Result = new long[] { this._connection.WrittenBytes - this._connection.ClientBytesRead, num / 2L };
         }
         else if ("chunkSize".Equals(oobCtrlMsg.ServiceName))
         {
             int num2 = (int)oobCtrlMsg.ServiceParameterMap["chunkSize"];
             if (num2 != this._chunkSize)
             {
                 this._chunkSize = num2;
                 ChunkSize message = new ChunkSize(this._chunkSize);
                 this._connection.GetChannel(2).Write(message);
             }
         }
     }
 }
Example #9
0
		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;
		}
Example #10
0
        public void Write(IRtmpEvent message)
        {
            IClientStream streamByChannelId = null;

            if (this._connection is IStreamCapableConnection)
            {
                streamByChannelId = (this._connection as IStreamCapableConnection).GetStreamByChannelId(this._channelId);
            }
            if ((this._channelId <= 3) || (streamByChannelId != null))
            {
                int streamId = (streamByChannelId == null) ? 0 : streamByChannelId.StreamId;
                this.Write(message, streamId);
            }
        }
Example #11
0
        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);
                }
            }
        }
Example #12
0
        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);
        }
Example #13
0
        public override void MessageSent(RtmpConnection connection, object message)
        {
            base.MessageSent(connection, message);
            RtmpPacket    packet            = message as RtmpPacket;
            int           channelId         = packet.Header.ChannelId;
            IClientStream streamByChannelId = null;

            if (connection is IStreamCapableConnection)
            {
                streamByChannelId = (connection as IStreamCapableConnection).GetStreamByChannelId(channelId);
            }
            if ((streamByChannelId != null) && (streamByChannelId is PlaylistSubscriberStream))
            {
                (streamByChannelId as PlaylistSubscriberStream).Written(packet.Message);
            }
        }
Example #14
0
        /// <summary>
        /// Writes packet from event data to the RTMP connection.
        /// </summary>
        /// <param name="message">Event data.</param>
        public void Write(IRtmpEvent message)
        {
            IClientStream stream = null;

            if (_connection is IStreamCapableConnection)
            {
                stream = (_connection as IStreamCapableConnection).GetStreamByChannelId(_channelId);
            }
            if (_channelId > 3 && stream == null)
            {
                //Stream doesn't exist any longer, discarding message
                return;
            }
            int streamId = (stream == null) ? 0 : stream.StreamId;

            Write(message, streamId);
        }
Example #15
0
 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();
             }
         }
     }
 }
Example #16
0
        public override void MessageSent(RtmpConnection connection, object message)
        {
            base.MessageSent(connection, message);
            RtmpPacket    sent      = message as RtmpPacket;
            int           channelId = sent.Header.ChannelId;
            IClientStream stream    = null;

            if (connection is IStreamCapableConnection)
            {
                stream = (connection as IStreamCapableConnection).GetStreamByChannelId(channelId);
            }
            // XXX we'd better use new event model for notification
            if (stream != null && (stream is PlaylistSubscriberStream))
            {
                (stream as PlaylistSubscriberStream).Written(sent.Message);
            }
        }
Example #17
0
        protected override void OnPing(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, Ping ping)
        {
            switch (ping.Value1)
            {
            case 3:
            {
                if (ping.Value2 == 0)
                {
                    log.Warn("Unhandled ping: " + ping);
                    break;
                }
                IClientStream streamById = null;
                if (connection is IStreamCapableConnection)
                {
                    streamById = (connection as IStreamCapableConnection).GetStreamById(ping.Value2);
                }
                int bufferDuration = ping.Value3;
                if (streamById == null)
                {
                    if (connection is RtmpServerConnection)
                    {
                        (connection as RtmpServerConnection).RememberStreamBufferDuration(ping.Value2, bufferDuration);
                    }
                    if (log.get_IsInfoEnabled())
                    {
                        log.Info("Remembering client buffer on stream: " + bufferDuration);
                    }
                    break;
                }
                streamById.SetClientBufferDuration(bufferDuration);
                if (log.get_IsInfoEnabled())
                {
                    log.Info("Setting client buffer on stream: " + bufferDuration);
                }
                break;
            }

            case 7:
                connection.PingReceived(ping);
                break;

            default:
                log.Warn("Unhandled ping: " + ping);
                break;
            }
        }
Example #18
0
        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 DeferredClose()
 {
     lock (base.SyncRoot)
     {
         if (this._keepAliveJobName != null)
         {
             (base.Scope.GetService(typeof(ISchedulingService)) as ISchedulingService).RemoveScheduledJob(this._keepAliveJobName);
             this._keepAliveJobName = null;
         }
         if (!base.IsDisposed && !this.IsDisconnected)
         {
             this._state = 0;
             IStreamService scopeService = ScopeUtils.GetScopeService(base.Scope, typeof(IStreamService)) as IStreamService;
             if (scopeService != null)
             {
                 lock (((ICollection)this._streams).SyncRoot)
                 {
                     IClientStream[] array = new IClientStream[this._streams.Count];
                     this._streams.Values.CopyTo(array, 0);
                     foreach (IClientStream stream in array)
                     {
                         if (stream != null)
                         {
                             if (log.get_IsDebugEnabled())
                             {
                                 log.Debug("Closing stream: " + stream.StreamId);
                             }
                             scopeService.deleteStream(this, stream.StreamId);
                             this._streamCount--;
                         }
                     }
                     this._streams.Clear();
                 }
             }
             if (((this._bwContext != null) && (base.Scope != null)) && (base.Scope.Context != null))
             {
                 (base.Scope.GetService(typeof(IBWControlService)) as IBWControlService).UnregisterBWControllable(this._bwContext);
                 this._bwContext = null;
             }
             base.Close();
             this._rtmpServer.OnConnectionClose(this);
             this._rtmpNetworkStream.Close();
         }
     }
 }
Example #20
0
        protected override void OnPing(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, Ping ping)
        {
            switch (ping.PingType)
            {
            case Ping.ClientBuffer:
                IClientStream stream = null;
                // Get the stream id
                int streamId = ping.Value2;
                // Get requested buffer size in milliseconds
                int buffer = ping.Value3;
                if (streamId != 0)
                {
                    // The client wants to set the buffer time
                    stream = connection.GetStreamById(streamId);
                    if (stream != null)
                    {
                        stream.SetClientBufferDuration(buffer);
                        if (log.IsDebugEnabled)
                        {
                            log.Debug(string.Format("Client sent a buffer size: {0} ms for stream id: {1}", buffer, streamId));
                        }
                    }
                }
                // Catch-all to make sure buffer size is set
                if (stream == null)
                {
                    // Remember buffer time until stream is created
                    connection.RememberStreamBufferDuration(streamId, buffer);
                    if (log.IsDebugEnabled)
                    {
                        log.Debug(string.Format("Remembering client buffer size: {0} on stream id: {1} ", buffer, streamId));
                    }
                }
                break;

            case Ping.PongServer:
                // This is the response to an IConnection.Ping request
                connection.PingReceived(ping);
                break;

            default:
                log.Warn("Unhandled ping: " + ping);
                break;
            }
        }
Example #21
0
 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();
         }
     }
 }
Example #22
0
        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);
        }
Example #23
0
        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);
        }
Example #24
0
        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);
        }
Example #25
0
        public void closeStream()
        {
            IConnection connection = FluorineContext.Current.Connection;

            if (connection is IStreamCapableConnection)
            {
                IClientStream streamById = (connection as IStreamCapableConnection).GetStreamById(this.GetCurrentStreamId());
                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 as IStreamCapableConnection).DeleteStreamById(this.GetCurrentStreamId());
            }
        }
Example #26
0
        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);
                    }
                }
            }
        }
Example #27
0
        /// <summary>
        /// Message recieved.
        /// </summary>
        /// <param name="connection">Connection object.</param>
        /// <param name="obj">Message object.</param>
        public void MessageReceived(RtmpConnection connection, object obj)
        {
            IRtmpEvent    message = null;
            RtmpPacket    packet  = null;
            RtmpHeader    header  = null;
            RtmpChannel   channel = null;
            IClientStream stream  = null;

            try {
                packet  = obj as RtmpPacket;
                message = packet.Message;
                header  = packet.Header;
                channel = connection.GetChannel(header.ChannelId);
                if (connection is IStreamCapableConnection)
                {
                    stream = (connection as IStreamCapableConnection).GetStreamById(header.StreamId);
                }

                // Support stream ids
#if !SILVERLIGHT
                FluorineContext.ValidateContext();
                FluorineContext.Current.Connection.SetAttribute(FluorineContext.FluorineStreamIdKey, header.StreamId);
#endif
                // Increase number of received messages
                connection.MessageReceived();

#if !SILVERLIGHT
                if (log != null && log.IsDebugEnabled)
                {
                    log.Debug("RtmpConnection message received, type = " + header.DataType);
                }
#endif

                if (message != null)
                {
                    message.Source = connection;
                }

                switch (header.DataType)
                {
                case Constants.TypeInvoke:
                    OnInvoke(connection, channel, header, message as Invoke);
                    if (message.Header.StreamId != 0 &&
                        (message as Invoke).ServiceCall.ServiceName == null &&
                        (message as Invoke).ServiceCall.ServiceMethodName == BaseRtmpHandler.ACTION_PUBLISH)
                    {
                        if (stream != null)                                 //Dispatch if stream was created
                        {
                            (stream as IEventDispatcher).DispatchEvent(message);
                        }
                    }
                    break;

                case Constants.TypeFlexInvoke:
                    OnFlexInvoke(connection, channel, header, message as FlexInvoke);
                    if (message.Header.StreamId != 0 &&
                        (message as Invoke).ServiceCall.ServiceName == null &&
                        (message as Invoke).ServiceCall.ServiceMethodName == BaseRtmpHandler.ACTION_PUBLISH)
                    {
                        if (stream != null)                                 //Dispatch if stream was created
                        {
                            (stream as IEventDispatcher).DispatchEvent(message);
                        }
                    }
                    break;

                case Constants.TypeNotify:                        // just like invoke, but does not return
                    if ((message as Notify).Data != null && stream != null)
                    {
                        // Stream metadata
                        (stream as IEventDispatcher).DispatchEvent(message);
                    }
                    else
                    {
                        OnInvoke(connection, channel, header, message as Notify);
                    }
                    break;

                case Constants.TypePing:
                    OnPing(connection, channel, header, message as Ping);
                    break;

                case Constants.TypeBytesRead:
                    OnStreamBytesRead(connection, channel, header, message as BytesRead);
                    break;

                case Constants.TypeSharedObject:
                case Constants.TypeFlexSharedObject:
                    OnSharedObject(connection, channel, header, message as SharedObjectMessage);
                    break;

                case Constants.TypeFlexStreamEnd:
                    if (stream != null)
                    {
                        (stream as IEventDispatcher).DispatchEvent(message);
                    }
                    break;

                case Constants.TypeChunkSize:
                    OnChunkSize(connection, channel, header, message as ChunkSize);
                    break;

                case Constants.TypeAudioData:
                case Constants.TypeVideoData:
                    // NOTE: If we respond to "publish" with "NetStream.Publish.BadName",
                    // the client sends a few stream packets before stopping. We need to
                    // ignore them.
                    if (stream != null)
                    {
                        ((IEventDispatcher)stream).DispatchEvent(message);
                    }
                    break;

                case Constants.TypeServerBandwidth:
                    OnServerBW(connection, channel, header, message as ServerBW);
                    break;

                case Constants.TypeClientBandwidth:
                    OnClientBW(connection, channel, header, message as ClientBW);
                    break;

                default:
#if !SILVERLIGHT
                    if (log != null && log.IsDebugEnabled)
                    {
                        log.Debug("RtmpService event not handled: " + header.DataType);
                    }
#endif
                    break;
                }
            } catch (Exception ex) {
#if !SILVERLIGHT
                if (log.IsErrorEnabled)
                {
                    log.Error(__Res.GetString(__Res.Rtmp_HandlerError), ex);
                    log.Error(__Res.GetString(__Res.Error_ContextDump));
                    //log.Error(Environment.NewLine);
                    log.Error(packet);
                }
#endif
            }
        }
Example #28
0
		/// <summary>
		/// Adds the client stream.
		/// This method supports the infrastructure and is not intended to be used directly from your code.
		/// </summary>
		/// <param name="stream">The stream.</param>
		public void AddClientStream(IClientStream stream) {
			int streamId = stream.StreamId;
			try {
				ReaderWriterLock.AcquireWriterLock();
				if (_reservedStreams.Length > streamId - 1 && _reservedStreams[streamId - 1])
					return;//Already reserved
				if (_reservedStreams.Length <= streamId - 1)
					_reservedStreams.Length = streamId;
				_reservedStreams[streamId - 1] = true;
			} finally {
				ReaderWriterLock.ReleaseWriterLock();
			}
			_streams[streamId - 1] = stream;
			_streamCount.Increment();
		}
Example #29
0
		/// <summary>
		/// Remove a stream from the connection.
		/// </summary>
		/// <param name="stream"></param>
		private void UnregisterStream(IClientStream stream) {
			_streams.Remove(stream.StreamId);
		}
Example #30
0
		/// <summary>
		/// Store a stream in the connection.
		/// </summary>
		/// <param name="stream"></param>
		protected void RegisterStream(IClientStream stream) {
			_streams[stream.StreamId - 1] = stream;
		}
Example #31
0
        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);
            }
        }
Example #32
0
        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);
            }
        }
        protected override void OnPing(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, Ping ping)
        {
            switch (ping.PingType)
            {
            case Ping.PingClient:
            case Ping.StreamBegin:
            case Ping.RecordedStream:
            case Ping.StreamPlayBufferClear:
                // The server wants to measure the RTT
                Ping pong = new Ping();
                pong.PingType = Ping.PongServer;
                // The event data is a 4-byte timestamp, which was received with the in the Ping request
                pong.Value2 = ping.Value2;
                connection.Ping(pong);
                break;

            case Ping.StreamDry:
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("Stream indicates there is no data available");
                }
#endif
                break;

            case Ping.ClientBuffer:
                //Set the client buffer
                IClientStream stream = null;
                //Get the stream id
                int streamId = ping.Value2;
                //Get requested buffer size in milliseconds
                int buffer = ping.Value3;
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(string.Format("Client sent a buffer size: {0} ms for stream id: {1}", buffer, streamId));
                }
#endif
                if (streamId != 0)
                {
                    // The client wants to set the buffer time
                    stream = connection.GetStreamById(streamId);
                    if (stream != null)
                    {
                        stream.SetClientBufferDuration(buffer);
#if !SILVERLIGHT
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug(string.Format("Setting client buffer on stream: {0}", streamId));
                        }
#endif
                    }
                }
                //Catch-all to make sure buffer size is set
                if (stream == null)
                {
                    // Remember buffer time until stream is created
                    connection.RememberStreamBufferDuration(streamId, buffer);
#if !SILVERLIGHT
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug(string.Format("Remembering client buffer on stream: {0}", streamId));
                    }
#endif
                }
                break;

            default:
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(string.Format("Unhandled ping: {0}", ping));
                }
#endif
                break;
            }
        }
        public void OnOOBControlMessage(IMessageComponent source, IPipe pipe, OOBControlMessage oobCtrlMsg)
        {
            if (!"ConnectionConsumer".Equals(oobCtrlMsg.Target))
            {
                return;
            }

            if ("pendingCount".Equals(oobCtrlMsg.ServiceName))
            {
                oobCtrlMsg.Result = _connection.PendingMessages;
            }
            else if ("pendingVideoCount".Equals(oobCtrlMsg.ServiceName))
            {
                IClientStream stream = null;
                if (_connection is IStreamCapableConnection)
                {
                    stream = (_connection as IStreamCapableConnection).GetStreamByChannelId(_video.ChannelId);
                }
                if (stream != null)
                {
                    oobCtrlMsg.Result = _connection.GetPendingVideoMessages(stream.StreamId);
                }
                else
                {
                    oobCtrlMsg.Result = (long)0;
                }
            }
            else if ("writeDelta".Equals(oobCtrlMsg.ServiceName))
            {
                long            maxStream      = 0;
                IBWControllable bwControllable = _connection as IBWControllable;
                // Search FC containing valid BWC
                while (bwControllable != null && bwControllable.BandwidthConfiguration == null)
                {
                    bwControllable = bwControllable.GetParentBWControllable();
                }
                if (bwControllable != null && bwControllable.BandwidthConfiguration != null)
                {
                    IBandwidthConfigure bwc = bwControllable.BandwidthConfiguration;
                    if (bwc is IConnectionBWConfig)
                    {
                        maxStream = (bwc as IConnectionBWConfig).DownstreamBandwidth / 8;
                    }
                }
                if (maxStream <= 0)
                {
                    // Use default value
                    // TODO: this should be configured somewhere and sent to the client when connecting
                    maxStream = 120 * 1024;
                }
                // Return the current delta between sent bytes and bytes the client
                // reported to have received, and the interval the client should use
                // for generating BytesRead messages (half of the allowed bandwidth).
                oobCtrlMsg.Result = new long[] { _connection.WrittenBytes - _connection.ClientBytesRead, maxStream / 2 };
            }
            else if ("chunkSize".Equals(oobCtrlMsg.ServiceName))
            {
                int newSize = (int)oobCtrlMsg.ServiceParameterMap["chunkSize"];
                if (newSize != _chunkSize)
                {
                    _chunkSize = newSize;
                    SendChunkSize();
                }
            }
        }