/// <inheritdoc />
        public async Task DownloadAndProcessMediaStreamsAsync(IReadOnlyList <MediaStreamInfo> mediaStreamInfos,
                                                              string filePath, string format,
                                                              IProgress <double> progress         = null,
                                                              CancellationToken cancellationToken = default(CancellationToken))
        {
            mediaStreamInfos.GuardNotNull(nameof(mediaStreamInfos));
            filePath.GuardNotNull(nameof(filePath));
            format.GuardNotNull(nameof(format));

            // Determine if transcoding is required for at least one of the streams
            var transcode = mediaStreamInfos.Any(s => IsTranscodingRequired(s.Container, format));

            // Set up progress-related stuff
            var progressMixer           = progress != null ? new ProgressMixer(progress) : null;
            var downloadProgressPortion = transcode ? 0.15 : 0.99;
            var ffmpegProgressPortion   = 1 - downloadProgressPortion;
            var totalContentLength      = mediaStreamInfos.Sum(s => s.Size);

            // Keep track of the downloaded streams
            var streamFilePaths = new List <string>();

            try
            {
                // Download all streams
                foreach (var streamInfo in mediaStreamInfos)
                {
                    // Generate file path
                    var streamIndex    = streamFilePaths.Count + 1;
                    var streamFilePath = $"{filePath}.stream-{streamIndex}.tmp";

                    // Add file path to list
                    streamFilePaths.Add(streamFilePath);

                    // Set up download progress handler
                    var streamDownloadProgress =
                        progressMixer?.Split(downloadProgressPortion * streamInfo.Size / totalContentLength);

                    // Download stream
                    await _youtubeClient.DownloadMediaStreamAsync(streamInfo, streamFilePath, streamDownloadProgress, cancellationToken);
                }

                // Set up process progress handler
                var ffmpegProgress = progressMixer?.Split(ffmpegProgressPortion);

                // Process streams (mux/transcode/etc)
                await _ffmpeg.ProcessAsync(streamFilePaths, filePath, format, transcode, ffmpegProgress, cancellationToken);

                // Report completion in case there are rounding issues in progress reporting
                progress?.Report(1);
            }
            finally
            {
                // Delete all stream files
                foreach (var streamFilePath in streamFilePaths)
                {
                    FileEx.TryDelete(streamFilePath);
                }
            }
        }