因為想下載youtube播放清單內的所有影片,又找不到有相關免費的下載器可以用
就自己來寫一個
首先必需先到google申請一個youtube的api key ,這個部份網路上有許多教學,這裡就不說明了
再來就是寫一個下載的程式
private static async Task<YoutubePlaylistModel> GetYoutubePlaylist(string pageToken)
{
var client = new HttpClient();
string url = "https://www.googleapis.com/youtube/v3/playlistItems?";
var querystring = HttpUtility.ParseQueryString("");
querystring.Add("part", "snippet,contentDetails");
querystring.Add("playlistId", PLAYLIST_ID);
querystring.Add("maxResults", "50");
querystring.Add("key", YOUTUBE_API_KEY);
if (!string.IsNullOrEmpty(pageToken))
querystring.Add("pageToken", pageToken);
url += querystring.ToString();
var response = await client.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("取得下載清單失敗");
Console.ResetColor();
return null;
}
var data = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<YoutubePlaylistModel>(data);
}
url : 這段是固定的,取得播放清單內的影片資訊
querystring:
"part" => 資料格式要包含哪些東西,我要的資訊需要包含 snippet, contentDetails ,實際可以參考 ( https://developers.google.com/youtube/v3/docs/playlistItems/list )
"playlistId" => 哪一個播放清單,例如我的播放清單網址為:https://www.youtube.com/playlist?list=PLhMsqKJtHaLoXU2ewdjwvUi6OafG16ERn ,playlistId = PLhMsqKJtHaLoXU2ewdjwvUi6OafG16ERn
"maxResults" => 一次要取得幾筆,這裡最大只能下載50筆
"key" => 這是你申請的api key
"pageToken" => 如果你的播放清單有下一頁,在打API時會多一個pageToken的Response,你要下載下一頁的資料就必需把這個代入
目前就是取得播放清單內的資料回來
再來要開始下載影片並轉檔為mp3
下載的部份要加入參考 <PackageReference Include="VideoLibrary" Version="3.0.9" />
private static string DownloadFile(string dir, string url)
{
//url = "https://www.youtube.com/playlist?list=PLsyOSbh5bs14MzRNG0FuuN7OFt914H-Nz";
try
{
Console.WriteLine("下載中...");
var youtube = YouTube.Default;
var vid = youtube.GetVideo(url);
var oriFilePath = Path.Combine(dir, vid.FullName).Replace("\"", "'");
File.WriteAllBytes(oriFilePath, vid.GetBytes());
Console.WriteLine("下載完成...");
return oriFilePath;
}
catch (Exception e)
{
Console.WriteLine($"下載發生錯誤:{e.Message}");
return string.Empty;
}
}
轉檔的部份使用ffmpeg
private static void Translate(string oriFilePath, string desFileName)
{
try
{
Console.WriteLine("轉檔中...");
var sh = "./convert.sh";
var cmd = $"ffmpeg -y -i \"{oriFilePath}\" \"{desFileName}\"";
File.WriteAllText(sh, cmd);
using var p = Process.Start(new ProcessStartInfo
{
FileName = "/bin/sh",
Arguments = sh,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
});
p.WaitForExit();
Console.WriteLine("轉檔完成...");
if (p.ExitCode > 0)
{
throw new Exception($"Failed");
}
File.Delete(oriFilePath);
}
catch (Exception e)
{
Console.WriteLine($"轉檔發生錯誤:{e.Message}");
}
}