C#/.Net 多线程下载m3u8视频

C#/.Net 多线程下载m3u8视频

  • 下载网络文件方法
  • 下载m3u8

.HttpGet() 是我自己封装的HTTP请求方法

下载网络文件方法

/// 
/// 下载网络文件
/// 
/// 文件地址
/// 保存路径
public static void DownloadFile(this string url, string savePath)
{
    
    WebClient wc = new WebClient();
	//从路径中取得文件名称
    var name = Path.GetFileName(url);
    if (name.Contains("?"))
    {
        name = name.Split("?")[0];
    }
    if (savePath.Last() != '/')
    {
        savePath += "/";
    }
	// 创建文件夹
    Directory.CreateDirectory(savePath);

    if(string.IsNullOrEmpty(name)) {
        return;
    }

    wc.DownloadFile(url, savePath + name);
}

下载m3u8

//ts保存路径
string tspath = "C:/Users/Administrator/Desktop/ts/";
//mp4保存路径
string mp4path = "C:/Users/Administrator/Desktop/mp4/";

// m3u8链接
string m3u8url = "https://v6.nfm3u8.com/20220802/dg9qcubn/hls/index.m3u8";

// 获取清单
string m3u8_content = m3u8url.HttpGet();

// 按换行符转换成数组,筛选掉空行和不是链接的行
List<string> m3u8_list = m3u8_content.Split("\n").Where(x => !x.StartsWith("#") && !string.IsNullOrEmpty(x.Trim())).ToList();

//下载线程数,多线程下载必须做限制,不然太夸张会导致崩溃
//10个线程刚刚好
int s = 0;
int progress = 0;//下载进度


foreach (string ts_url in m3u8_list) {
    //多线程下载
    Task.Run(() =>
    {
        s++;
        ts_url.DownloadFile(tspath);
        progress++;
        s--;
    });


    //等待空闲线程
    while (true)
    {
        //每0.1秒创建1个新的线程
        Task.Delay(100).Wait();
        //如果当前线程数量小于10个,跳出等待,开始下载下一条
        if (s < 10)
        {
            break;
        }
    }

}


//等待全部ts下载完成
while (true)
{
    if (progress < m3u8_list.Count)
    {
        Task.Delay(300).Wait();
    }
    else
    {
        break;
    }
}



//按顺序将ts合并成mp4
using (FileStream fs = new FileStream($"{mp4path}video.mp4", FileMode.Create))
{
    foreach (var _u in m3u8_list)
    {
        var name = Path.GetFileName(_u);
        using (FileStream fs1 = new FileStream(tspath+name, FileMode.Open))
        {
            fs1.CopyTo(fs);
        }
    }
}

//删除ts缓存
Task.Delay(500).Wait();
foreach (string filePath in Directory.GetFiles(tspath))
{
    File.Delete(filePath);
}

Console.WriteLine("下载完成:"+ $"{mp4path}video.mp4");

Console.ReadLine();

你可能感兴趣的:(c#,.net,.netcore)