Youtubeexplode: Button to Pause and Cancel Download

Created on 28 Jul 2017  路  5Comments  路  Source: Tyrrrz/YoutubeExplode

Hi Bro !! I'm again I want to know how to do a button to pause and cancel video or audio download in Youtube Explode. It can be done?

question

All 5 comments

If you're using DownloadMediaStreamAsync then it has CancellationToken parameter

Do you have any more questions regarding this issue?

@Tyrrrz I know this is old but my question is on topic - is there a way to "pause" and "resume" DownloadMediaStreamAsync?

@derekantrican nope, you would have to manage this yourself via the stream coming from GetMediaStreamAsync

Ok, for anyone that finds this later I have adapted this solution into this:

Usage:

FileDownload fileDownload;

private async void DownloadVideo()
{
    //Do YoutubeClient & MuxedStreamInfo setup stuff

    using (MediaStream stream = await client.GetMediaStreamAsync(videoQuality).ConfigureAwait(false))
    {
        fileDownload = new FileDownload(stream, targetPath, progress: progress);
        await fileDownload.Start();
    }
}

private void PauseDownload()
{
    fileDownload.Pause();
}

private void ResumeDownload()
{
    fileDownload.Start();
}

FileDownload class

public class FileDownload
{
    private volatile bool _allowedToRun;
    private Stream _sourceStream;
    private string _sourceUrl;
    private string _destination;
    private bool _disposeOnCompletion;
    private int _chunkSize;
    private IProgress<double> _progress;
    private Lazy<int> _contentLength;

    public int BytesWritten { get; private set; }
    public int ContentLength { get { return _contentLength.Value; } }

    public bool Done { get { return ContentLength == BytesWritten; } }

    public FileDownload(Stream source, string destination, bool disposeOnCompletion = true, int chunkSizeInBytes = 10000 /*Default to 0.01 mb*/, IProgress<double> progress = null)
    {
        _allowedToRun = true;

        _sourceStream = source;
        _destination = destination;
        _disposeOnCompletion = disposeOnCompletion;
        _chunkSize = chunkSizeInBytes;
        _contentLength = new Lazy<int>(() => Convert.ToInt32(GetContentLength()));
        _progress = progress;

        BytesWritten = 0;
    }

    public FileDownload(string source, string destination, int chunkSizeInBytes = 10000 /*Default to 0.01 mb*/, IProgress<double> progress = null)
    {
        _allowedToRun = true;

        _sourceUrl = source;
        _destination = destination;
        _chunkSize = chunkSizeInBytes;
        _contentLength = new Lazy<int>(() => Convert.ToInt32(GetContentLength()));
        _progress = progress;

        BytesWritten = 0;
    }

    private long GetContentLength()
    {
        if (_sourceStream != null)
            return _sourceStream.Length;
        else
        {
            var request = (HttpWebRequest)WebRequest.Create(_sourceUrl);
            request.Method = "HEAD";

            using (var response = request.GetResponse())
                return response.ContentLength;
        }
    }

    private async Task Start(int range)
    {
        if (!_allowedToRun)
            throw new InvalidOperationException();

        if (_sourceStream != null)
        {
            using (var fs = new FileStream(_destination, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
            {
                while (_allowedToRun)
                {
                    var buffer = new byte[_chunkSize];
                    var bytesRead = await _sourceStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);

                    if (bytesRead == 0) break;

                    await fs.WriteAsync(buffer, 0, bytesRead);
                    BytesWritten += bytesRead;
                    _progress?.Report((double)BytesWritten / ContentLength);
                }

                await fs.FlushAsync();
            }

            //Control whether the stream should be disposed here or outside of this class
            if (BytesWritten == ContentLength && _disposeOnCompletion)
                _sourceStream?.Dispose();
        }
        else
        {
            var request = (HttpWebRequest)WebRequest.Create(_sourceUrl);
            request.Method = "GET";
            request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
            request.AddRange(range);

            using (var response = await request.GetResponseAsync())
            {
                using (var responseStream = response.GetResponseStream())
                {
                    using (var fs = new FileStream(_destination, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
                    {
                        while (_allowedToRun)
                        {
                            var buffer = new byte[_chunkSize];
                            var bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);

                            if (bytesRead == 0) break;

                            await fs.WriteAsync(buffer, 0, bytesRead);
                            BytesWritten += bytesRead;
                            _progress?.Report((double)BytesWritten / ContentLength);
                        }

                        await fs.FlushAsync();
                    }
                }
            }
        }
    }

    public Task Start()
    {
        _allowedToRun = true;
        return Start(BytesWritten);
    }

    public void Pause()
    {
        _allowedToRun = false;
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

nk34player picture nk34player  路  4Comments

jungjanos picture jungjanos  路  6Comments

NoobInTraining picture NoobInTraining  路  5Comments

spoikbr picture spoikbr  路  5Comments

DavidBarishev picture DavidBarishev  路  8Comments