Пример #1
0
 public RxBuffer(int capacity, DataReadyHandler onMainDataReady = null, AltDataReadyHandler onAltDataReady = null)
 {
     buffer           = new byte[capacity];
     endIndex         = 0;
     OnMainDataReady += onMainDataReady;
     OnAltDataReady  += onAltDataReady;
 }
Пример #2
0
 /// <summary>
 /// Receive callback</summary>
 /// <param name="ar">Operation status passed from begin/receive</param>
 private void ReceiveClb(IAsyncResult ar)
 {
     try
     {
         byte[] data   = ar.AsyncState as byte[];
         int    nBytes = 0;
         if (IsConnected)
         {
             lock (m_syncSocket)
             {
                 nBytes = m_theSocket.EndReceive(ar);
             }
         }
         if (nBytes > 0)
         {
             byte[] tmpBuf = new byte[nBytes];
             Buffer.BlockCopy(data, 0, tmpBuf, 0, nBytes);
             DataReadyHandler dr = DataReady;
             if (dr != null)
             {
                 // raise data ready event on the gui thread.
                 m_cctx.Post(delegate
                 {
                     dr(this, tmpBuf);
                 }, null);
             }
         }
         StartReceive();
     }
     catch (Exception ex)
     {
         bool disconnected = false;
         lock (m_syncSocket)
         {
             if (m_theSocket != null && !m_theSocket.Connected)
             {
                 m_theSocket.Close();
                 m_theSocket  = null;
                 disconnected = true;
             }
         }
         if (disconnected)
         {
             OnDisconnected();
             m_curTarget = null;
         }
         OnUnHandledException(ex);
     }
 }
Пример #3
0
        public void WriteFLV(RTMP rtmp, DataReadyHandler DataReady, System.Net.Sockets.Socket socket)
        {
            // rtmp must be connected and ready for playback data
            if (!rtmp.IsConnected() || !rtmp.Playing) return;

            Stream outputStream = null;

            // we will be writing in chunks, so use our own stream
            MemoryStream ms = new MemoryStream();

            // header
            ms.Write(FLVStream.flvHeader, 0, FLVStream.flvHeader.Length);

            // write stream
            uint timeStamp = 0;
            int result = 0;
            int packets = 0;
            int httpChunkSize = 1024 * 10; // first chunk should be big enough so the direct show filter can get all the info and do some buffering
            int reconnects = 0;
            do
            {
                try
                {
                    int retries = 0;
                    do
                    {
                        RTMPPacket packet = null;
                        result = rtmp.GetNextMediaPacket(out packet);
                        if (result == 1)
                        {
                            if (!WriteStream(packet, ms, out timeStamp)) break;

                            packets++;
                            if (packets > 10 && ms.Length > httpChunkSize)
                            {
                                if (outputStream == null) // first time writing data
                                {
                                    if (rtmp.CombinedTracksLength > 0)
                                    {
                                        EstimatedLength = rtmp.CombinedTracksLength + (rtmp.CombinedTracksLength / rtmp.InChunkSize) * 11;
                                    }
                                    else if (rtmp.CombinedBitrates > 0)
                                    {
                                        EstimatedLength = (long)(rtmp.CombinedBitrates * 1000 / 8 * (rtmp.Duration <= 0 ? 10800 : rtmp.Duration)); // set 3h if no duration in metadata
                                    }
                                    else
                                    {
                                        // nothing was in the metadata -> just use duration and a bitrate of 2000
                                        EstimatedLength = (long)(2000 * 1000 / 8 * (rtmp.Duration <= 0 ? 10800 : rtmp.Duration)); // set 3h if no duration in metadata
                                    }

                                    EstimatedLength = (long)((double)EstimatedLength * 1.5d);

                                    if (EstimatedLength > 0x7fffffff) EstimatedLength = 0x7fffffff; // honor 2GB size limit

                                    outputStream = DataReady(); // get the stream
                                    httpChunkSize = 1024; // reduce chunksize
                                }

                                byte[] buffer = ms.ToArray();
                                outputStream.Write(buffer, 0, buffer.Length);
                                Length += (uint)buffer.Length;
                                ms = new MemoryStream();
                            }
                        }
                        else if (result == 0)
                        {
                            if (retries > 0)
                            {
                                rtmp.invalidRTMPHeader = true;
                                break;
                            }
                            /* Did we already try pausing, and it still didn't work? */
                            if (rtmp.Pausing == 3)
                            {
                                // Only one try at reconnecting...
                                retries = 1;
                                if (!rtmp.ReconnectStream())
                                {
                                    rtmp.invalidRTMPHeader = true;
                                    Logger.Log("Failed to reconnect the stream.");
                                    break;
                                }
                            }
                            else if (!rtmp.ToggleStream())
                            {
                                rtmp.invalidRTMPHeader = true;
                                Logger.Log("Failed to resume the stream.");
                                break;
                            }
                        }
                    }
                    while (result != 2 && rtmp.Playing && socket.Connected);
                }
                catch (Exception ex)
                {
                    Logger.Log(ex.ToString());
                }
                finally
                {
                    // if data already received and connection now closed - try reconnecting rtmp
                    if (result != 2 && timeStamp > 0 && reconnects < 1)
                    {
                        Logger.Log("Connection failed before playback ended - trying reconnect");
                        rtmp.Link.seekTime = timeStamp;
                        reconnects++;
                        if (rtmp.Connect()) reconnects = 0;
                    }
                }
            }
            while (reconnects <= 1 && result != 2 && rtmp.Playing && socket.Connected);
        }