private async void DownloadAudio(int position, string path) { if (position < 0 || position > queue.Count || queue[position].State != DownloadState.None) { return; } System.Console.WriteLine("&Downloading audio of: " + queue[position].Name); queue[position].State = DownloadState.Initialization; UpdateList(position); while (downloadCount >= maxDownload) { await Task.Delay(1000); } downloadCount++; currentStrike++; CreateNotification(queue[position].Name); try { YoutubeClient client = new YoutubeClient(); Video video = await client.GetVideoAsync(queue[position].YoutubeID); MediaStreamInfoSet mediaStreamInfo = await client.GetVideoMediaStreamInfosAsync(queue[position].YoutubeID); MediaStreamInfo streamInfo; if (mediaStreamInfo.Audio.Count > 0) { streamInfo = mediaStreamInfo.Audio.Where(x => x.Container == Container.Mp4).OrderBy(s => s.Bitrate).Last(); } else if (mediaStreamInfo.Muxed.Count > 0) { streamInfo = mediaStreamInfo.Muxed.Where(x => x.Container == Container.Mp4).OrderBy(x => x.Resolution).Last(); } else { queue[position].State = DownloadState.Error; downloadCount--; if (queue.Count != 0) { DownloadAudio(queue.FindIndex(x => x.State == DownloadState.None), path); } Playlist.instance?.Activity.RunOnUiThread(() => { Playlist.instance.CheckForSync(); }); return; } queue[position].State = DownloadState.Downloading; UpdateList(position); string title = video.Title; foreach (char c in Path.GetInvalidFileNameChars()) //Make the title a valid filename (remove /, \, : etc). { title = title.Replace(c, ' '); } string fileExtension = "m4a"; //audio only extension containing aac (audio codex of the mp4) string outpath = path; if (queue[position].PlaylistName != null) { outpath = Path.Combine(path, queue[position].PlaylistName); Directory.CreateDirectory(outpath); } string filePath = Path.Combine(outpath, title + "." + fileExtension); if (File.Exists(filePath)) { int i = 1; string defaultPath = filePath; do { filePath = Path.Combine(outpath, title + " (" + i + ")." + fileExtension); i++; }while (File.Exists(filePath)); } MediaStream input = await client.GetMediaStreamAsync(streamInfo); queue[position].Path = filePath; files.Add(filePath); FileStream output = File.Create(filePath); byte[] buffer = new byte[4096]; int byteReaded = 0; while (byteReaded < input.Length) { int read = await input.ReadAsync(buffer, 0, 4096); await output.WriteAsync(buffer, 0, read); byteReaded += read; UpdateProgressBar(position, byteReaded / input.Length); } output.Dispose(); queue[position].State = DownloadState.MetaData; UpdateList(position); if (queue.Count == 1) { SetNotificationProgress(100, true); } SetMetaData(position, video.Title, video.Author, video.Thumbnails); files.Remove(filePath); downloadCount--; if (queue.Count != 0) { DownloadAudio(queue.FindIndex(x => x.State == DownloadState.None), path); } Playlist.instance?.Activity.RunOnUiThread(() => { Playlist.instance.CheckForSync(); }); } catch (System.Net.Http.HttpRequestException) { MainActivity.instance.Timout(); Cancel(); } catch (DirectoryNotFoundException) { Handler handler = new Handler(Looper.MainLooper); handler.Post(() => { Toast.MakeText(Application.Context, Resource.String.download_path_error, ToastLength.Long).Show(); }); Cancel(); } catch { MainActivity.instance.UnknowError(ErrorCode.DL1); Cancel(); } }