public PlaybackManifestGenerator(
            ISequenceRegistry sequenceRegistry,
            IConfigurationService configurationSettings,
            IUserSettingsService userSettingsService)
        {
            this.dispatcher          = Application.Current.RootVisual.Dispatcher;
            this.sequenceRegistry    = sequenceRegistry;
            this.userSettingsService = userSettingsService;
            this.streamsByUri        = new Dictionary <Uri, Stream>();
            this.pendingDownloads    = new List <Uri>();
            this.downloaderManager   = new RCE.Infrastructure.Services.DownloaderManager();
            this.downloaderManager.DownloadCompleted += this.OnManifestDownloadCompleted;
            this.treatGapsAsError = configurationSettings.GetTreatGapAsError();

            if (!this.treatGapsAsError)
            {
                this.GetGapAttributesFromUserSettings(configurationSettings);
            }
        }
        public void GetMetadata(object target)
        {
            Uri smoothStreamingManifestUri = target as Uri;

            if (smoothStreamingManifestUri == null)
            {
                this.OnGetManifestCompleted(null);
            }
            else
            {
                var manager = new RCE.Infrastructure.Services.DownloaderManager();

                manager.DownloadCompleted +=
                    (s, e) =>
                {
                    Stream manifestStream            = e.Stream;
                    SmoothStreamingMetadata metadata = new SmoothStreamingMetadata();

                    if (manifestStream != null)
                    {
                        SmoothStreamingManifestParser parser = new SmoothStreamingManifestParser(manifestStream);

                        IEnumerable <StreamInfo> audioStreams = parser.ManifestInfo.Streams.Where(x => x.StreamType.Equals("audio", StringComparison.OrdinalIgnoreCase));

                        StreamInfo videoStreamInfo = parser.ManifestInfo.Streams.SingleOrDefault(x => x.StreamType.Equals("video", StringComparison.OrdinalIgnoreCase));

                        if (videoStreamInfo != null)
                        {
                            QualityLevel firstQualityLevel = videoStreamInfo.QualityLevels.FirstOrDefault();

                            string bitrate;
                            string cameraAngle;

                            if (firstQualityLevel != null && firstQualityLevel.Attributes.TryGetValue("Bitrate", out bitrate) && firstQualityLevel.CustomAttributes.TryGetValue("cameraAngle", out cameraAngle))
                            {
                                List <string> cameraAngles = new List <string>();

                                foreach (QualityLevel qualityLevel in videoStreamInfo.QualityLevels)
                                {
                                    if (qualityLevel.Attributes["Bitrate"] == bitrate && qualityLevel.CustomAttributes.TryGetValue("cameraAngle", out cameraAngle))
                                    {
                                        cameraAngles.Add(cameraAngle);
                                    }
                                }

                                // order by string comparison
                                cameraAngles.Sort();

                                if (cameraAngles.Count() > 0)
                                {
                                    metadata.AddMetadataField(new MetadataField("VideoStreams", cameraAngles));
                                }
                            }
                        }

                        metadata.AddMetadataField(new MetadataField("Duration", parser.ManifestInfo.ManifestDuration));

                        metadata.AddMetadataField(new MetadataField("AudioStreams", audioStreams));
                    }

                    this.OnGetManifestCompleted(metadata);
                };

                manager.DownloadManifestAsync(smoothStreamingManifestUri, false, null);
            }
        }