private async Task StartDownloadAndReadContentsAsync() { try { // Retrieve a random access stream from the download operation. Every OpenReadAsync() operation returns // a new stream instance that is independent of previous ones (i.e., the seek position of one stream // isn't affected by calls on another stream). // // This sample demonstrates the direct usage of a DownloadOperation's random access stream and its // effects on the ongoing transfer. However, bear in mind that there are a variety of operations // that can manage the stream on the app's behalf for specific scenarios. For instance, a // DownloadOperation pointing to a video URL can be consumed by the MediaPlayer class in four easy // steps: // // var randomAccessStreamReference = download.GetResultRandomAccessStreamReference(); // stream = await randomAccessStreamReference.OpenReadAsync(); // var mediaPlayer = new Windows.Media.Playback.MediaPlayer(); // mediaPlayer.Source = Windows.Media.Core.MediaSource.CreateFromStream(stream, stream.ContentType); var randomAccessStreamReference = download.GetResultRandomAccessStreamReference(); randomAccessStream = await randomAccessStreamReference.OpenReadAsync(); // Start the download. If the server doesn't support random access, the download will fail // with WebErrorStatus.InsufficientRangeSupport or WebErrorStatus.MissingContentLengthSupport. IAsyncOperationWithProgress <DownloadOperation, DownloadOperation> downloadOperation = download.StartAsync(); downloadOperation.Progress += OnDownloadProgress; Task downloadTask = downloadOperation.AsTask(); startDownloadButton.IsEnabled = false; pauseDownloadButton.IsEnabled = true; // Read data while the download is still ongoing. Use a 1 MB read buffer for that purpose. var readBuffer = new Windows.Storage.Streams.Buffer(BytesPerMegaByte); while (!downloadTask.IsCompleted) { ulong readOffsetInBytes = randomAccessStream.Position; PreviousReadText.Text = CurrentReadText.Text; CurrentReadText.Text = $"Reading from offset {readOffsetInBytes:n0}"; readOperation = randomAccessStream.ReadAsync( readBuffer, readBuffer.Capacity, InputStreamOptions.None). AsTask(readCancellationTokenSource.Token); // Update the UI to show the current read's position. currentPositionSlider.Value = readOffsetInBytes / BytesPerMegaByte; try { // Wait for the read to complete. IBuffer bytesRead = await readOperation; CurrentReadText.Text += $", completed with {bytesRead.Length:n0} bytes"; // At this point, a real app would process the 'bytesRead' data to do something interesting // with it (e.g., display video and/or play audio). if (randomAccessStream.Position >= randomAccessStream.Size) { // We have reached EOF. Wrap around to the beginning while we wait for the download to complete. randomAccessStream.Seek(0); } } catch (OperationCanceledException) { // The ongoing read was canceled by SeekDownload_Click(...) in order for a new download // position to take effect immediately. CurrentReadText.Text += ", cancelled."; } } // Wait for the download to complete. await downloadTask; rootPage.NotifyUser("Download completed successfully", NotifyType.StatusMessage); } catch (Exception ex) when(IsWebException("Execution error", ex)) { // Abandon the operation if a web exception occurs. } finally { download = null; randomAccessStream = null; readOperation = null; startDownloadButton.IsEnabled = true; pauseDownloadButton.IsEnabled = false; resumeDownloadButton.IsEnabled = false; } }
public async Task <MediaSource> RequestMusic(MusicModel model) { EventHandler <DownloadOperation> downloadProgressHandler = (o, e) => { _logger.Debug($"Downloading status of {model.Title}:\n\t{e.Progress.Status}, ({e.Progress.BytesReceived}/{e.Progress.TotalBytesToReceive})"); switch (e.Progress.Status) { case BackgroundTransferStatus.Completed: _utilityHelper.RunAtUIThread(() => model.HasCached = true); break; default: break; } }; IRandomAccessStreamReference ras = null; DownloadOperation downloadOperation = null; var downloadProgress = new Progress <DownloadOperation>(); downloadProgress.ProgressChanged += downloadProgressHandler; var cacheFile = await _createMusicFile(model); if (cacheFile == null) { var operations = await BackgroundDownloader.GetCurrentDownloadsForTransferGroupAsync(_backgroundDownloaderGroup); foreach (var item in operations) { if (item.ResultFile is StorageFile cachedFile) { if (cachedFile.Name == _utilityHelper.CreateMd5HashString(model.Title)) { downloadOperation = item; break; } } } if (downloadOperation != null) { ras = downloadOperation.GetResultRandomAccessStreamReference(); downloadOperation.AttachAsync().AsTask(downloadProgress); } else { _logger.Warning($"Don't find the downloading task for {model.Title}"); return(null); } } else { downloadOperation = _backgroundDownloader.CreateDownload(model.Uri, cacheFile); downloadOperation.IsRandomAccessRequired = true; ras = downloadOperation.GetResultRandomAccessStreamReference(); downloadOperation.StartAsync().AsTask(downloadProgress); } var source = MediaSource.CreateFromStreamReference(ras, "audio/mpeg"); return(source); }