Beispiel #1
0
        /// <summary>
        /// Analyzes and responds if required to the given <see cref="RTMPPacket"/>.
        /// </summary>
        /// <param name="packet">The <see cref="RTMPPacket"/> to inspect amnd react to.</param>
        /// <returns>0 (false) for OK/Failed/error, 1 for 'Stop or Complete' (true)</returns>
        bool HandleInvoke(RTMPPacket packet)
        {
            bool ret = false;

            if (packet.m_body[0] != 0x02) // make sure it is a string method name we start with
            {
                Logger.Log("HandleInvoke: Sanity failed. no string method in invoke packet");
                return false;
            }

            AMFObject obj = new AMFObject();
            int nRes = obj.Decode(packet.m_body, 0, (int)packet.m_nBodySize, false);
            if (nRes < 0)
            {
                Logger.Log("HandleInvoke: error decoding invoke packet");
                return false;
            }

            obj.Dump();
            string method = obj.GetProperty(0).GetString();
            double txn = obj.GetProperty(1).GetNumber();

            Logger.Log(string.Format("server invoking <{0}>", method));

            if (method == "_result")
            {
                string methodInvoked = m_methodCalls.Dequeue();

                Logger.Log(string.Format("received result for method call <{0}>", methodInvoked));

                if (methodInvoked == "connect")
                {
                    if (!string.IsNullOrEmpty(Link.token))
                    {
                        List<AMFObjectProperty> props = new List<AMFObjectProperty>();
                        obj.FindMatchingProperty("secureToken", props, int.MaxValue);
                        if (props.Count > 0)
                        {
                            string decodedToken = Tea.Decrypt(props[0].GetString(), Link.token);
                            SendSecureTokenResponse(decodedToken);
                        }
                    }
                    SendServerBW();
                    if (!SkipCreateStream)
                    {
                        SendPing(3, 0, 300);
                        SendCreateStream();
                    }
                    if (!string.IsNullOrEmpty(Link.subscribepath)) SendFCSubscribe(Link.subscribepath);
                    else if (Link.bLiveStream) SendFCSubscribe(Link.playpath);
                }
                else if (methodInvoked == "createStream")
                {
                    m_stream_id = (int)obj.GetProperty(3).GetNumber();
                    SendPlay();
                    SendPing(3, (uint)m_stream_id, (uint)m_nBufferMS);
                }
                else if (methodInvoked == "play")
                {
                    Playing = true;
                }
            }
            else if (method == "onBWDone")
            {
                if (m_nBWCheckCounter == 0) SendCheckBW();
            }
            else if (method == "_onbwcheck")
            {
                SendCheckBWResult(txn);
            }
            else if (method == "_onbwdone")
            {
                if (m_methodCalls.Contains("_checkbw"))
                {
                    string[] queue = m_methodCalls.ToArray();
                    m_methodCalls.Clear();
                    for (int i = 0; i < queue.Length; i++) if (queue[i] != "_checkbw") m_methodCalls.Enqueue(queue[i]);
                }
            }
            else if (method == "_error")
            {
                Logger.Log("rtmp server sent error");
            }
            else if (method == "close")
            {
                Logger.Log("rtmp server requested close");
                Close();
            }
            else if (method == "onStatus")
            {
                string code = obj.GetProperty(3).GetObject().GetProperty("code").GetString();
                string level = obj.GetProperty(3).GetObject().GetProperty("level").GetString();

                Logger.Log(string.Format("onStatus: code :{0}, level: {1}", code, level));

                if (code == "NetStream.Failed" || code == "NetStream.Play.Failed" || code == "NetStream.Play.StreamNotFound" || code == "NetConnection.Connect.InvalidApp")
                {
                    Close();
                }
                else if (code == "NetStream.Play.Start" || code == "NetStream.Publish.Start")
                {
                    Playing = true;
                }
                else if (code == "NetStream.Play.Complete" || code == "NetStream.Play.Stop")
                {
                    Close();
                    ret = true;
                }
                else if (code == "NetStream.Pause.Notify")
                {
                    if (Pausing == 1 || Pausing == 2)
                    {
                        SendPause(false);
                        Pausing = 3;
                    }
                }
            }
            else if (MethodHookHandler != null)
            {
                ret = MethodHookHandler(method, obj, this);
            }
            else
            {

            }

            return ret;
        }
Beispiel #2
0
        void HandleMetadata(byte[] buffer, int offset, int size)
        {
            AMFObject obj = new AMFObject();
            int nRes = obj.Decode(buffer, offset, size, false);
            if (nRes < 0)
            {
                //Log(LOGERROR, "%s, error decoding meta data packet", __FUNCTION__);
                return;
            }

            if (!Playing) obj.Dump();
            string metastring = obj.GetProperty(0).GetString();

            if (metastring == "onMetaData")
            {
                if (Playing) obj.Dump(); // always dump metadata for further analyzing

                List<AMFObjectProperty> props = new List<AMFObjectProperty>();
                obj.FindMatchingProperty("duration", props, 1);
                if (props.Count > 0)
                {
                    Duration = props[0].GetNumber();
                    Logger.Log(string.Format("Set duration: {0}", Duration));
                }
                props.Clear();
                obj.FindMatchingProperty("audiodatarate", props, 1);
                if (props.Count > 0)
                {
                    int audiodatarate = (int)props[0].GetNumber();
                    CombinedBitrates += audiodatarate;
                    Logger.Log(string.Format("audiodatarate: {0}", audiodatarate));
                }
                props.Clear();
                obj.FindMatchingProperty("videodatarate", props, 1);
                if (props.Count > 0)
                {
                    int videodatarate = (int)props[0].GetNumber();
                    CombinedBitrates += videodatarate;
                    Logger.Log(string.Format("videodatarate: {0}", videodatarate));
                }
                if (CombinedTracksLength == 0)
                {
                    props.Clear();
                    obj.FindMatchingProperty("filesize", props, int.MaxValue);
                    if (props.Count > 0)
                    {
                        CombinedTracksLength = (int)props[0].GetNumber();
                        Logger.Log(string.Format("Set CombinedTracksLength from filesize: {0}", CombinedTracksLength));
                    }
                }
                if (CombinedTracksLength == 0)
                {
                    props.Clear();
                    obj.FindMatchingProperty("datasize", props, int.MaxValue);
                    if (props.Count > 0)
                    {
                        CombinedTracksLength = (int)props[0].GetNumber();
                        Logger.Log(string.Format("Set CombinedTracksLength from datasize: {0}", CombinedTracksLength));
                    }
                }
            }
        }