/// <summary> /// Translates the given JSON object extracted from YouTube to its managed representation. /// </summary> protected virtual YouTubeMuxedStream TranslateMuxedStream(JObject input) { if (input == null) { throw new ArgumentNullException(nameof(input)); } var result = new YouTubeMuxedStream { iTag = input.Value <int?>("itag"), Type = input.Value <string>("mimeType"), AudioSampleRate = input.Value <long>("audioSampleRate"), ContentLength = input.Value <long>("contentLength"), Quality = input.Value <string>("quality"), QualityLabel = input.Value <string>("qualityLabel"), Url = input.Value <string>("url"), FrameSize = input.ContainsKey("width") && input.ContainsKey("height") ? new Size(input.Value <int>("width"), input.Value <int>("height")) : null }; result.Mime = ExtractActualMime(result.Type); // get cipher info (+signatureCipher) var cipher = input.Value <string>("cipher") ?? input.Value <string>("signatureCipher"); if (!string.IsNullOrEmpty(cipher)) { UpdateStreamCipherInfo(result, cipher); } return(result); }
/// <summary> /// Gets invoked by <see cref="DownloadMetadata"/> to extract muxed streams from metadata. /// </summary> protected virtual List <YouTubeMuxedStream> ExtractMuxedStreamsMetadata(List <KeyValuePair <string, string> > fmtStreamMapEntries) { var list = new List <YouTubeMuxedStream>(); var propertySet = new HashSet <string>(); var draft = new YouTubeMuxedStream(); void CommitDraft() { if (draft?.iTag != null && draft.Url != null) { list.Add(draft); } propertySet.Clear(); draft = new YouTubeMuxedStream(); } void Feed(string key, string value) { // check for force commit if (key == null) { CommitDraft(); return; } // check for rotation if (propertySet.Contains(key)) { CommitDraft(); } propertySet.Add(key); // update draft switch (key.ToLowerInvariant()) { case "itag": draft.iTag = int.Parse(value); break; case "type": draft.Type = value; var parts = value.Split(new[] { ';' }, 2, StringSplitOptions.RemoveEmptyEntries); draft.Mime = parts[0]; break; case "quality": draft.Quality = value; break; case "url": draft.Url = value; break; case "s": draft.Signature = value; break; } } UnmangleEntries(fmtStreamMapEntries, Feed); return(list); }