Пример #1
0
        /// <summary>
        /// Creates media frame data segments.
        /// </summary>
        /// <param name="mediaFrame">Media frame.</param>
        /// <param name="metadataRequired">Indicates whether to include metadata.</param>
        /// <returns>An array of data segments.</returns>
        private static ArraySegment <byte>[] CreateDataSegments(RawFrame mediaFrame, bool metadataRequired)
        {
            if (!metadataRequired)
            {
                return new[] { new byte[] { 0 }, mediaFrame.FrameSegment }
            }
            ;

            var codecName = mediaFrame switch
            {
                RawAACFrame _ => "AAC",
                RawG711AFrame _ => "G711A",
                RawG711UFrame _ => "G711U",
                RawG726Frame _ => "G726",
                RawPCMFrame _ => "PCM",
                RawH264IFrame _ => "H264",
                RawH264PFrame _ => "H264",
                RawJpegFrame _ => "MJPEG",
                _ => string.Empty
            };

            var bitsPerCodedUnit = mediaFrame switch
            {
                RawG726Frame rawG726Frame => rawG726Frame.BitsPerCodedSample,
                _ => 0
            };

            var configSegment = mediaFrame switch
            {
                RawAACFrame rawAacFrame => rawAacFrame.ConfigSegment,
                RawH264IFrame rawH264IFrame => rawH264IFrame.SpsPpsSegment,
                _ => default
            };

            var codecBytes = Encoding.UTF8.GetBytes(codecName);

            Array.Resize(ref codecBytes, 10);

            var metaSegment = new byte[19];

            using var stream = new MemoryStream(metaSegment);
            using var writer = new EndianBinaryWriter(stream);

            writer.Write((byte)1);
            writer.Write(codecBytes);
            writer.Write(bitsPerCodedUnit);
            writer.Write(configSegment.Count);

            return(configSegment.Count > 0
                ? new[] { metaSegment, configSegment, mediaFrame.FrameSegment }
                : new[] { metaSegment, mediaFrame.FrameSegment });
        }
Пример #2
0
        protected void streamingThreadLoop()
        {
            try
            {
                CancellationToken cancellationToken = streamingCancelTokenSource.Token;

                Uri serverUri = new Uri(Url);

                ConnectionParameters connectionParameters;
                if (!string.IsNullOrWhiteSpace(Username))
                {
                    connectionParameters = new ConnectionParameters(serverUri, new NetworkCredential(Username, Password));
                }
                else
                {
                    connectionParameters = new ConnectionParameters(serverUri);
                }
                connectionParameters.RtpTransport = RtpTransportProtocol.TCP;

                string openH264DllPath = Globals.ApplicationDirectoryBase + "openh264-1.8.0-win" + (Environment.Is64BitProcess ? "64" : "32") + ".dll";
                using (OpenH264Lib.Decoder decoder = new OpenH264Lib.Decoder(openH264DllPath))
                    using (RtspClient rtspClient = new RtspClient(connectionParameters))
                    {
                        rtspClient.FrameReceived += (sender2, frame) =>
                        {
                            //process (e.g. decode/save to file) encoded frame here or
                            //make deep copy to use it later because frame buffer (see FrameSegment property) will be reused by client
                            if (frame is RawH264IFrame)
                            {
                                RawH264IFrame iFrame = frame as RawH264IFrame;
                                DecodeFrame(decoder, iFrame.SpsPpsSegment.ToArray(), frame.Timestamp);
                                DecodeFrame(decoder, iFrame.FrameSegment.ToArray(), frame.Timestamp);
                            }
                            else if (frame is RawH264PFrame)
                            {
                                DecodeFrame(decoder, frame.FrameSegment.ToArray(), frame.Timestamp);
                            }
                        };
                        rtspClient.ConnectAsync(cancellationToken).Wait();
                        rtspClient.ReceiveAsync(cancellationToken).Wait();
                    }
            }
            catch (ThreadAbortException) { }
            catch (TaskCanceledException)
            {
                Stop();
            }
            catch (Exception ex)
            {
                if (ex is AggregateException)
                {
                    AggregateException aex = ex as AggregateException;
                    if (aex.InnerExceptions.Count == 1 && aex.InnerException is TaskCanceledException)
                    {
                        return;
                    }
                }
                Logger.Debug(ex);
                OnError(this, ex);
                Stop();
            }
        }