byte[] GetMessageBytes(RtmpMessage message, Action <AmfWriter, RtmpMessage> handler)
 {
     using (var stream = new MemoryStream())
         using (var messageWriter = new AmfWriter(stream, writer.SerializationContext, objectEncoding))
         {
             handler(messageWriter, message);
             return(stream.ToArray());
         }
 }
 void WriteData(AmfWriter writer, RtmpMessage o, ObjectEncoding encoding)
 {
     if (o is Command)
     {
         WriteCommandOrData(writer, o, encoding);
     }
     else if (o is ByteData)
     {
         writer.WriteBytes(((ByteData)o).Data);
     }
 }
        public void Queue(RtmpMessage message, int streamId, int messageStreamId)
        {
            var header = new RtmpHeader();
            var packet = new RtmpPacket(header, message);

            header.StreamId        = streamId;
            header.Timestamp       = message.Timestamp;
            header.MessageStreamId = messageStreamId;
            header.MessageType     = message.MessageType;
            if (message.Header != null)
            {
                header.IsTimerRelative = message.Header.IsTimerRelative;
            }
            queuedPackets.Enqueue(packet);
            // packetAvailableEvent.Set();
            Interlocked.Exchange(ref packetAvailable, 1);
        }
        /// <summary>
        /// 写入命令或数据
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="o"></param>
        /// <param name="encoding"></param>
        void WriteCommandOrData(AmfWriter writer, RtmpMessage o, ObjectEncoding encoding)
        {
            var command    = o as Command;
            var methodCall = command.MethodCall;
            var isInvoke   = command is Invoke;

            // write the method name or result type (first section)
            var isRequest = methodCall.CallStatus == CallStatus.Request;

            if (isRequest)
            {
                writer.WriteAmfItem(encoding, methodCall.Name);
            }
            else
            {
                writer.WriteAmfItem(encoding, methodCall.IsSuccess ? "_result" : "_error");
            }

            if (methodCall.Name == "@setDataFrame")
            {
                writer.WriteAmfItem(encoding, command.ConnectionParameters);
            }

            if (isInvoke)
            {
                writer.WriteAmfItem(encoding, command.InvokeId);
                writer.WriteAmfItem(encoding, command.ConnectionParameters);


                if (!methodCall.IsSuccess)
                {
                    methodCall.Parameters = new object[] { new StatusAsObject(StatusCode.CallFailed, "error", "Call failed.") }
                }
                ;
            }
            // write arguments
            foreach (var arg in methodCall.Parameters)
            {
                writer.WriteAmfItem(encoding, arg);
            }
        }
    }
Beispiel #5
0
 public RtmpPacket(RtmpHeader header, RtmpMessage body) : this(header)
 {
     Body   = body;
     Length = header.PacketLength;
 }
Beispiel #6
0
 public RtmpPacket(RtmpMessage body)
 {
     Body = body;
 }
 void WriteProtocolControlMessage(RtmpMessage @event)
 {
     Writer.Queue(@event, CONTROL_CSID, 0);
 }
 public void SendAmf0Data(RtmpMessage e)
 {
     //var timestamp = (int)(DateTime.UtcNow - connectTime).TotalMilliseconds;
     //e.Timestamp = timestamp;
     Writer.Queue(e, StreamID, _random.Next());
 }
        byte[] GetMessageBytes(RtmpHeader header, RtmpMessage message)
        {
            switch (header.MessageType)
            {
            case MessageType.SetChunkSize:
                return(GetMessageBytes(message, (w, o) => w.WriteInt32(((ChunkSize)o).Size)));

            case MessageType.AbortMessage:
                return(GetMessageBytes(message, (w, o) => w.WriteInt32(((Abort)o).StreamId)));

            case MessageType.Acknowledgement:
                return(GetMessageBytes(message, (w, o) => w.WriteInt32(((Acknowledgement)o).BytesRead)));

            case MessageType.UserControlMessage:
                return(GetMessageBytes(message, (w, o) =>
                {
                    var m = (UserControlMessage)o;
                    w.WriteUInt16((ushort)m.EventType);
                    foreach (var v in m.Values)
                    {
                        w.WriteInt32(v);
                    }
                }));

            case MessageType.WindowAcknowledgementSize:
                return(GetMessageBytes(message, (w, o) => w.WriteInt32(((WindowAcknowledgementSize)o).Count)));

            case MessageType.SetPeerBandwith:
                return(GetMessageBytes(message, (w, o) =>
                {
                    var m = (PeerBandwidth)o;
                    w.WriteInt32(m.AcknowledgementWindowSize);
                    w.WriteByte((byte)m.LimitType);
                }));

            case MessageType.Audio:
            case MessageType.Video:
                return(GetMessageBytes(message, (w, o) => WriteData(w, o, ObjectEncoding.Amf0)));


            case MessageType.DataAmf0:
                return(GetMessageBytes(message, (w, o) => WriteCommandOrData(w, o, ObjectEncoding.Amf0)));

            case MessageType.SharedObjectAmf0:
                return(new byte[0]);    // todo: `SharedObject`s

            case MessageType.CommandAmf0:
                return(GetMessageBytes(message, (w, o) => WriteCommandOrData(w, o, ObjectEncoding.Amf0)));


            case MessageType.DataAmf3:
                return(GetMessageBytes(message, (w, o) => WriteData(w, o, ObjectEncoding.Amf3)));

            case MessageType.SharedObjectAmf3:
                return(new byte[0]);    // todo: `SharedObject`s

            case MessageType.CommandAmf3:
                return(GetMessageBytes(message, (w, o) =>
                {
                    w.WriteByte(0);
                    WriteCommandOrData(w, o, ObjectEncoding.Amf3);
                }));

            case MessageType.Aggregate:
                // todo: Aggregate messages
                System.Diagnostics.Debugger.Break();
                return(new byte[0]);    // todo: `Aggregate`

            default:
                throw new ArgumentOutOfRangeException("Unknown RTMP message type: " + (int)header.MessageType);
            }
        }