private async ValueTask PopulateStreamInfosAsync( ICollection <IStreamInfo> streamInfos, IEnumerable <IStreamInfoExtractor> streamInfoExtractors, CancellationToken cancellationToken = default) { foreach (var streamInfoExtractor in streamInfoExtractors) { var itag = streamInfoExtractor.TryGetItag() ?? throw new YoutubeExplodeException("Could not extract stream itag."); var url = streamInfoExtractor.TryGetUrl() ?? throw new YoutubeExplodeException("Could not extract stream URL."); // Get content length var contentLength = streamInfoExtractor.TryGetContentLength() ?? await _http.TryGetContentLengthAsync(url, false, cancellationToken) ?? 0; if (contentLength <= 0) { continue; // broken stream URL? } var fileSize = new FileSize(contentLength); var container = streamInfoExtractor.TryGetContainer()?.Pipe(s => new Container(s)) ?? throw new YoutubeExplodeException("Could not extract stream container."); var bitrate = streamInfoExtractor.TryGetBitrate()?.Pipe(s => new Bitrate(s)) ?? throw new YoutubeExplodeException("Could not extract stream bitrate."); var audioCodec = streamInfoExtractor.TryGetAudioCodec(); var videoCodec = streamInfoExtractor.TryGetVideoCodec(); // Muxed or video-only stream if (!string.IsNullOrWhiteSpace(videoCodec)) { var framerate = streamInfoExtractor.TryGetFramerate() ?? 24; var videoQualityLabel = streamInfoExtractor.TryGetVideoQualityLabel(); var videoQuality = !string.IsNullOrWhiteSpace(videoQualityLabel) ? VideoQuality.FromLabel(videoQualityLabel, framerate) : VideoQuality.FromItag(itag, framerate); var videoWidth = streamInfoExtractor.TryGetVideoWidth(); var videoHeight = streamInfoExtractor.TryGetVideoHeight(); var videoResolution = videoWidth is not null && videoHeight is not null ? new Resolution(videoWidth.Value, videoHeight.Value) : videoQuality.GetDefaultVideoResolution(); // Muxed if (!string.IsNullOrWhiteSpace(audioCodec)) { var streamInfo = new MuxedStreamInfo( url, container, fileSize, bitrate, audioCodec, videoCodec, videoQuality, videoResolution ); streamInfos.Add(streamInfo); } // Video-only else { var streamInfo = new VideoOnlyStreamInfo( url, container, fileSize, bitrate, videoCodec, videoQuality, videoResolution ); streamInfos.Add(streamInfo); } } // Audio-only else if (!string.IsNullOrWhiteSpace(audioCodec)) { var streamInfo = new AudioOnlyStreamInfo( url, container, fileSize, bitrate, audioCodec ); streamInfos.Add(streamInfo); } else { Debug.Fail("Stream doesn't contain neither audio nor video codec information."); } } }
public DownloadOption(string format, AudioOnlyStreamInfo audioOnlyStreamInfo, VideoOnlyStreamInfo videoOnlyStreamInfo) : this(format, videoOnlyStreamInfo.VideoQualityLabel, new IStreamInfo[] { audioOnlyStreamInfo, videoOnlyStreamInfo }) { }
private static void SelectMediaStreamInfoSet(StreamManifest streamManifest, Settings settings, SettingDownload settingDownload, out AudioOnlyStreamInfo audioStreamInfo, out VideoOnlyStreamInfo videoStreamInfo) { //Todo make a better selection process //by largest container bitrate audioStreamInfo = streamManifest .GetAudioOnly() .Where(s => s.Container == Container.Mp4) .OrderByDescending(s => s.Bitrate) .First(); videoStreamInfo = streamManifest .GetVideoOnly() .Where(s => s.Container == Container.Mp4) .OrderByDescending(s => s.VideoQuality) .ThenByDescending(s => s.Framerate) .First(); if (settingDownload.MediaType == MediaType.Audio) { audioStreamInfo = streamManifest .GetAudioOnly() .OrderByDescending(s => s.Bitrate) .First(); } if (settingDownload.MediaType == MediaType.Video) { videoStreamInfo = streamManifest .GetVideoOnly() .Where(s => s.Container == Container.Mp4) .OrderByDescending(s => s.VideoQuality) .ThenByDescending(s => s.Framerate) .First(); } }