public async void Download(Download video) { using (var cli = Client.For(new YouTube())) //use a libvideo client to get video metadata { IEnumerable <YouTubeVideo> downloadLinks = null; try { downloadLinks = cli.GetAllVideos(video.VideoData.Url).OrderBy(br => - br.AudioBitrate); //sort by highest audio quality } catch (ArgumentException) { video.DownloadFailed = true; downloadManager.RemoveActive(video); //invalid url gui.DisplayMessage("Invalid URL!"); threadHandler.RemoveActive(Thread.CurrentThread); Thread.CurrentThread.Abort(); } YouTubeVideo highestQuality = null; try { highestQuality = downloadLinks.First(); //grab best quality link } catch { video.DownloadFailed = true; downloadManager.RemoveActive(video); gui.DisplayMessage("Unable to download video"); gui.OnProgressChanged(); return; } //setup http web request to get video bytes var asyncRequest = await highestQuality.GetUriAsync(); var request = (HttpWebRequest)HttpWebRequest.Create(Convert.ToString(asyncRequest)); request.AllowAutoRedirect = true; request.Method = "GET"; request.Proxy = HttpWebRequest.DefaultWebProxy; request.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials; //execute request and save bytes to buffer using (var response = (HttpWebResponse)request.GetResponse()) { var len = response.ContentLength; var buffer = new byte[256]; using (var stream = response.GetResponseStream()) { stream.ReadTimeout = 5000; using (var tempbytes = new TempFile()) { FileStream bytes = new FileStream(tempbytes.Path, FileMode.Open); while (bytes.Length < len) { try { var read = stream.Read(buffer, 0, buffer.Length); if (read > 0) { bytes.Write(buffer, 0, read); double percentage = bytes.Length * 100 / len; if (video.DownloadProgress != percentage) { video.SetDownloadProgress(percentage); gui.OnProgressChanged(); } } else { break; } } catch { video.DownloadFailed = true; downloadManager.RemoveActive(video); //thread aborted return; } } //check integrity of byte array if (bytes.Length != len) { video.DownloadFailed = true; downloadManager.RemoveActive(video); gui.DisplayMessage("File content is corrupted!"); threadHandler.RemoveActive(Thread.CurrentThread); Thread.CurrentThread.Abort(); } else { if (video.Bitrate == 0) //video { video.SetConvertProgress(100); string videoPath = Path.Combine(downloadManager.DownloadsPath, highestQuality.FullName); File.Copy(tempbytes.Path, videoPath, true); gui.DisplayMessage("Successful!"); } else //mp3 { //create temp video file to convert to mp3 and dispose of when done TimeSpan duration = GetVideoDuration(tempbytes.Path); string mp3Name = highestQuality.FullName + ".mp3"; string audioPath = Path.Combine(downloadManager.DownloadsPath, mp3Name); ToMp3(tempbytes.Path, audioPath, duration, video, video.Bitrate); //convert to mp3 } } bytes.Dispose(); bytes.Close(); } } } } downloadManager.RemoveActive(video); }
/// <summary> /// Convert a video file to an mp3 of a desired bitrate /// </summary> /// <param name="videoPath">The file path of the video</param> /// <param name="audioPath">The file path to save the mp3</param> /// /// <param name="duration">The duration of the video file. Used to calculate progress</param> /// <param name="bitrate">Determines quality of the output mp3. 320kbps = high</param> /// <returns>Returns true if the conversion was successful</returns> private bool ToMp3(string videoPath, string audioPath, TimeSpan duration, Download video, uint bitrate = 320) { //setup an ffmpeg process var ffmpeg = new Process { StartInfo = { UseShellExecute = false, RedirectStandardError = true, FileName = ffmpegPath, CreateNoWindow = true } }; var arguments = String.Format( @"-y -i ""{0}"" -b:a {1}K -vn ""{2}""", videoPath, bitrate, audioPath ); ffmpeg.StartInfo.Arguments = arguments; try { //try to invoke ffmpeg if (!ffmpeg.Start()) { video.DownloadFailed = true; Debug.WriteLine("Unable to start ffmpeg!"); return(false); } var reader = ffmpeg.StandardError; string line; while ((line = reader.ReadLine()) != null) { //get the line saying the time - use this to calculate percentage if (line.Contains("time=")) { string[] lineSplit = line.Split(' '); foreach (string part in lineSplit) { if (part.Contains("time=")) { TimeSpan timeConverted = TimeSpan.Parse(part.Replace("time=", "")); double percentage = ((double)timeConverted.Ticks / (double)duration.Ticks) * 100; if (video.ConvertProgress != percentage) { video.SetConvertProgress(percentage); gui.OnProgressChanged(); } break; } } } } } catch { video.DownloadFailed = true; downloadManager.RemoveActive(video); return(false); //exception was thrown, conversion failed } video.SetConvertProgress(100); gui.OnProgressChanged(); ffmpeg.Close(); using (StreamWriter sw = new StreamWriter("output.txt", append: true)) { if (File.Exists(audioPath)) { sw.WriteLine("File successfully created - filename length: " + audioPath.Length); } else { sw.WriteLine("Error, file not created - filename length: " + audioPath.Length); } sw.Flush(); } return(true); }