ตันฉบับโค้ด
https://markheath.net/post/how-to-get-media-file-duration-in-c
คือ ผมจะ Do while จนกว่า จะมีค่า duration เวลา ดาวน์โหลด ครับ
หรือใครมีวิธีเช็ค การสิ้นสุดการดาวน์โหลด ของ youtube_dl.exe ไม๊ ครับ ว่าจะเช็คยังไง
ผมลองใช้ process.Exited ดักแล้วก็ยังไม่ได้ครับ
Code
[Spoil] คลิกเพื่อดูข้อความที่ซ่อนไว้using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using NLog;
using TorServices;
using Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
namespace PlaylistDownloader
{
//https://github.com/bertyhell/PlaylistDownloader/blob/master/PlaylistDownloader/PlaylistDownloader/Downloader.cs
public class Downloader : BackgroundWorker
{
private readonly List<PlaylistItem> _playlist;
private readonly RunSettings _runSettings;
private int _progress;
private int _totalSongs;
private int _completeSongs;
private CancellationTokenSource _cts;
private static Logger logger = LogManager.GetCurrentClassLogger();
public double progressValue = 0d;
private bool ConverttoMP3;
public Downloader(RunSettings settings, ICollection<PlaylistItem> playlist,bool converttomp3)
{
_playlist = playlist.ToList<PlaylistItem>
);
_totalSongs = _playlist.Count;
_cts = new CancellationTokenSource();
_runSettings = settings;
ConverttoMP3 = converttomp3;
}
int itemIndex = 0;
protected override void OnDoWork(DoWorkEventArgs args)
{
_progress = 0;
// LimitedConcurrencyLevelTaskScheduler scheduler = new LimitedConcurrencyLevelTaskScheduler(1);
// var factory = new TaskFactory(scheduler);
// var tasks = new List<Task>
);
_playlist.ForEach(plst =>
{
DownloadPlaylistItem(plst);
// tasks.Add(factory.StartNew(() => DownloadPlaylistItem(plst)));
});
// Task.WaitAll(tasks.ToArray());
}
//https://markheath.net/post/how-to-get-media-file-duration-in-c
TimeSpan GetDuration(string filePath)
{
using (var shell = ShellObject.FromParsingName(filePath))
{
IShellProperty prop = shell.Properties.System.Media.Duration;
var t = (ulong)prop.ValueAsObject;
return TimeSpan.FromTicks((long)t);
}
}
public void DownloadPlaylistItem(PlaylistItem item)
{
string destinationFilePathWithoutExtension = null;
// string tempFilePathWithoutExtension = null;
item.DownloadProgress = 5;
if (!string.IsNullOrWhiteSpace(item.FileName))
{
// tempFilePathWithoutExtension = Path.Combine(_runSettings.FolTemp, item.FileName.MakeValidFileName());
destinationFilePathWithoutExtension = Path.Combine(_runSettings.SongsFolder, item.FileName.MakeValidFileName()) ;
item.DownloadProgress = 10;
if (!File.Exists(destinationFilePathWithoutExtension + ".mp4"))
{
StartProcessyoutube_dl(item, destinationFilePathWithoutExtension, ParseYoutubeDlProgress);
}
else
{
Finish(item, destinationFilePathWithoutExtension);
}
}
else
{
Finish(item, destinationFilePathWithoutExtension);
}
}
private string StartProcessyoutube_dl(PlaylistItem item, string desFile, Action<string, PlaylistItem> parseProgressFunc)
{
string executablePath = _runSettings.YoutubeDlPath;
string destinationFilePathWithoutExtension = desFile;
var promise = new TaskCompletionSource<string>
);
string arguments = string.Format( " --audio-quality 0 --no-part --output \"{0}\" {1}", destinationFilePathWithoutExtension + ".mp4", item.Link);
logger.Info("[RUN CMD] " + executablePath + arguments);
string _filename = executablePath;
Process process = new Process
{
StartInfo =
{
FileName = executablePath,
Arguments = arguments,
CreateNoWindow = !_runSettings.IsDebug,
WindowStyle = _runSettings.IsDebug ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
},
EnableRaisingEvents = true
};
// --audio-quality 5 --extract-audio --audio-format mp3 -o "c:\Users\Julian\Music\PlaylistDownloader\\%(title)s.%(ext)s" https://www.youtube.com/watch?v=mDuElaL1dU0
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
{
string consoleLine = e.Data;
if (!string.IsNullOrWhiteSpace(consoleLine))
{
logger.Info(consoleLine);
parseProgressFunc(consoleLine, item);
}
if (CancellationPending)
{
logger.Info("Canceling process because of user: " + executablePath);
process.Close();
promise.SetResult(null);
}
};
process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
{
string consoleLine = e.Data;
if (!string.IsNullOrWhiteSpace(consoleLine))
{
logger.Info("Error: " + consoleLine);
parseProgressFunc(consoleLine, item);
}
if (CancellationPending)
{
logger.Info("Canceling process because of user: " + executablePath);
process.Close();
promise.SetResult(null);
}
// Finish(item, tempFilePathWithoutExtension);
};
process.Exited += new EventHandler((object sender, EventArgs e) =>
{
process.Dispose();
logger.Info("Closing process");
promise.SetResult(null);
if (File.Exists(destinationFilePathWithoutExtension + ".mp4"))
{
if (new FileInfo(destinationFilePathWithoutExtension + ".mp4").Length > 0)
{
Thread.Sleep(1000);
if (ConverttoMP3)
{
if (!System.IO.File.Exists(destinationFilePathWithoutExtension + ".mp3"))
{
StartProcessffmpeg(item, destinationFilePathWithoutExtension);
}
else
{
Finish(item, destinationFilePathWithoutExtension);
}
}
else
{
Finish(item, destinationFilePathWithoutExtension);
}
//Finish(item, destinationFilePathWithoutExtension);
//
}
}
});
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
/* do
{
Thread.Sleep(1000);
} while (!File.Exists(destinationFilePathWithoutExtension + ".mp4") || new FileInfo(destinationFilePathWithoutExtension + ".mp4").Length < 20000);
*/
do
{
Thread.Sleep(1000);
} while ( GetDuration(destinationFilePathWithoutExtension + ".mp4").TotalMinutes <= 0);
if (ConverttoMP3)
{
if (!System.IO.File.Exists(destinationFilePathWithoutExtension + ".mp3"))
{
StartProcessffmpeg(item, destinationFilePathWithoutExtension);
}
else
{
Finish(item, destinationFilePathWithoutExtension);
}
}
else
{
Finish(item, destinationFilePathWithoutExtension);
}
return promise.Task.Result;
}
private string StartProcessffmpeg(PlaylistItem item, string desFile)
{
string executablePath = _runSettings.FfmpegPath;
string destinationFilePathWithoutExtension = desFile;
var promise = new TaskCompletionSource<string>
);
string arguments = string.Format(" -i \"{0}\" -b:a 192K -vn \"{1}\"", destinationFilePathWithoutExtension + ".mp4", destinationFilePathWithoutExtension + ".mp3");
logger.Info("[RUN CMD] " + executablePath + arguments);
string _filename = executablePath;
Process process = new Process
{
StartInfo =
{
FileName = executablePath,
Arguments = arguments,
CreateNoWindow = !_runSettings.IsDebug,
WindowStyle = _runSettings.IsDebug ? ProcessWindowStyle.Norma
C# Error แบบนี้ แก้ยังไงครับ
ตันฉบับโค้ด
https://markheath.net/post/how-to-get-media-file-duration-in-c
คือ ผมจะ Do while จนกว่า จะมีค่า duration เวลา ดาวน์โหลด ครับ
หรือใครมีวิธีเช็ค การสิ้นสุดการดาวน์โหลด ของ youtube_dl.exe ไม๊ ครับ ว่าจะเช็คยังไง
ผมลองใช้ process.Exited ดักแล้วก็ยังไม่ได้ครับ
Code
[Spoil] คลิกเพื่อดูข้อความที่ซ่อนไว้