使用C#获取B站视频音频与用户信息

.netcore

#使用C#获取B站视频音频与用户信息 [TOC]

tn2>在平时学习和开发中,我们有时候希望从 B站视频链接 中提取出音频文件,同时获取到视频的基本信息,例如 标题、UP主昵称和头像。本文将介绍如何使用 C# (.NET 8) 调用 B 站的官方接口来实现这一功能。

B 站视频 ID

tn2>B 站的视频有两种 ID:

  • BV 号 :比如 BV1M4411J7CG
  • AV 号 :比如 av91991951

tn2>在网页链接中通常是 BV 号,我们直接取出即可。

获取工具类

csharp 复制代码
public static class BlibliHelper
{
    /// <summary>
    /// 获取标题和名称
    /// </summary>
    /// <param name="bvid">BV号</param>
    /// <returns></returns>
    public static async Task<(string, string)> GetLinkTitleAndUserName(string bvid)
    {

        using var http = new HttpClient();
        http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
        http.DefaultRequestHeaders.Add("Referer", "https://www.bilibili.com");

        // 调用视频详情接口
        string viewUrl = $"https://api.bilibili.com/x/web-interface/view?bvid={bvid}";
        string viewJson = await http.GetStringAsync(viewUrl);
        using var doc = JsonDocument.Parse(viewJson);
        var data = doc.RootElement.GetProperty("data");
        string title = data.GetProperty("title").GetString();
        string upName = data.GetProperty("owner").GetProperty("name").GetString();
        string upFace = data.GetProperty("owner").GetProperty("face").GetString();
        return (title, upName);
    }
    /// <summary>
    /// 获取音乐文件
    /// </summary>
    /// <param name="bvid">BV号</param>
    /// <param name="filepath">注意这里是m4s文件还需要转换,少数是mp4</param>
    /// <returns></returns>
    public static async Task<bool> GetM4sOrMp4(string bvid, string filepath)
    {
        try
        {
            using var http = new HttpClient();
            http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
            http.DefaultRequestHeaders.Add("Referer", "https://www.bilibili.com");

            // 1) 先查 CID
            var viewJson = await http.GetStringAsync($"https://api.bilibili.com/x/web-interface/view?bvid={bvid}");
            using var viewDoc = JsonDocument.Parse(viewJson);
            var data = viewDoc.RootElement.GetProperty("data");
            long cid = data.TryGetProperty("pages", out var pages) && pages.GetArrayLength() > 0
                ? pages[0].GetProperty("cid").GetInt64()
                : data.GetProperty("cid").GetInt64();

            // 2) 请求播放信息 ------ 强制 DASH;如服务端仍返回 durl,则走兜底
            var playUrl = $"https://api.bilibili.com/x/player/playurl?bvid={bvid}&cid={cid}&qn=0&fnval=4048&fnver=0&fourk=1";
            var playJson = await http.GetStringAsync(playUrl);
            using var playDoc = JsonDocument.Parse(playJson);
            var pdata = playDoc.RootElement.GetProperty("data");

            string outFile = filepath;

            if (pdata.TryGetProperty("dash", out var dash))
            {
                // 取最佳音轨(按 id 或带宽挑最大者)
                var best = dash.GetProperty("audio").EnumerateArray()
                               .Select(e => new
                               {
                                   Elem = e,
                                   Id = e.TryGetProperty("id", out var idEl) ? idEl.GetInt32() : 0,
                                   Bw = e.TryGetProperty("bandwidth", out var bwEl) ? bwEl.GetInt32() : 0
                               })
                               .OrderByDescending(x => x.Id).ThenByDescending(x => x.Bw)
                               .First().Elem;

                var audioUrl = best.GetProperty("baseUrl").GetString();
                Console.WriteLine("DASH 音频: " + audioUrl);

                var bytes = await http.GetByteArrayAsync(audioUrl);
                //outFile = $"audio_{cid}.m4s";
                await File.WriteAllBytesAsync(outFile, bytes);
                Console.WriteLine($"已保存音频分片:{outFile}(m4s,可用 FFmpeg 转封装为 m4a)");
            }
            else if (pdata.TryGetProperty("durl", out var durl))
            {
                // 兜底:合轨 MP4,直接下载整段;如只要音频,后续用 FFmpeg 抽取
                var url = durl[0].GetProperty("url").GetString();
                Console.WriteLine("合轨直链: " + url);

                var bytes = await http.GetByteArrayAsync(url);
                //outFile = $"video_{cid}.mp4";
                await File.WriteAllBytesAsync(outFile, bytes);
                Console.WriteLine($"已保存合轨文件:{outFile}(如需仅音频,请用 FFmpeg 抽音轨)");
            }
            else
            {![.netcore](https://img.tnblog.net/arcimg/hb/c857299a86d84ee7b26d181a31e58234.jpg ".netcore")
>#使用C#获取B站视频音频与用户信息
[TOC]

>在平时学习和开发中,我们有时候希望从 B站视频链接 中提取出音频文件,同时获取到视频的基本信息,例如 标题、UP主昵称和头像。本文将介绍如何使用 C# (.NET 8) 调用 B 站的官方接口来实现这一功能。

B 站视频 ID
------------

>B 站的视频有两种 ID:

* **BV 号**:比如 `BV1M4411J7CG`
* **AV 号**:比如 `av91991951`

>在网页链接中通常是 **BV 号**,我们直接取出即可。


获取工具类
------------

```csharp
public static class BlibliHelper
{
    /// <summary>
    /// 获取标题和名称
    /// </summary>
    /// <param name="bvid">BV号</param>
    /// <returns></returns>
    public static async Task<(string, string)> GetLinkTitleAndUserName(string bvid)
    {

        using var http = new HttpClient();
        http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
        http.DefaultRequestHeaders.Add("Referer", "https://www.bilibili.com");

        // 调用视频详情接口
        string viewUrl = $"https://api.bilibili.com/x/web-interface/view?bvid={bvid}";
        string viewJson = await http.GetStringAsync(viewUrl);
        using var doc = JsonDocument.Parse(viewJson);
        var data = doc.RootElement.GetProperty("data");
        string title = data.GetProperty("title").GetString();
        string upName = data.GetProperty("owner").GetProperty("name").GetString();
        string upFace = data.GetProperty("owner").GetProperty("face").GetString();
        return (title, upName);
    }
    /// <summary>
    /// 获取音乐文件
    /// </summary>
    /// <param name="bvid">BV号</param>
    /// <param name="filepath">注意这里是m4s文件还需要转换,少数是mp4</param>
    /// <returns></returns>
    public static async Task<bool> GetM4sOrMp4(string bvid, string filepath)
    {
        try
        {
            using var http = new HttpClient();
            http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
            http.DefaultRequestHeaders.Add("Referer", "https://www.bilibili.com");

            // 1) 先查 CID
            var viewJson = await http.GetStringAsync($"https://api.bilibili.com/x/web-interface/view?bvid={bvid}");
            using var viewDoc = JsonDocument.Parse(viewJson);
            var data = viewDoc.RootElement.GetProperty("data");
            long cid = data.TryGetProperty("pages", out var pages) && pages.GetArrayLength() > 0
                ? pages[0].GetProperty("cid").GetInt64()
                : data.GetProperty("cid").GetInt64();

            // 2) 请求播放信息 ------ 强制 DASH;如服务端仍返回 durl,则走兜底
            var playUrl = $"https://api.bilibili.com/x/player/playurl?bvid={bvid}&cid={cid}&qn=0&fnval=4048&fnver=0&fourk=1";
            var playJson = await http.GetStringAsync(playUrl);
            using var playDoc = JsonDocument.Parse(playJson);
            var pdata = playDoc.RootElement.GetProperty("data");

            string outFile = filepath;

            if (pdata.TryGetProperty("dash", out var dash))
            {
                // 取最佳音轨(按 id 或带宽挑最大者)
                var best = dash.GetProperty("audio").EnumerateArray()
                               .Select(e => new
                               {
                                   Elem = e,
                                   Id = e.TryGetProperty("id", out var idEl) ? idEl.GetInt32() : 0,
                                   Bw = e.TryGetProperty("bandwidth", out var bwEl) ? bwEl.GetInt32() : 0
                               })
                               .OrderByDescending(x => x.Id).ThenByDescending(x => x.Bw)
                               .First().Elem;

                var audioUrl = best.GetProperty("baseUrl").GetString();
                Console.WriteLine("DASH 音频: " + audioUrl);

                var bytes = await http.GetByteArrayAsync(audioUrl);
                //outFile = $"audio_{cid}.m4s";
                await File.WriteAllBytesAsync(outFile, bytes);
                Console.WriteLine($"已保存音频分片:{outFile}(m4s,可用 FFmpeg 转封装为 m4a)");
            }
            else if (pdata.TryGetProperty("durl", out var durl))
            {
                // 兜底:合轨 MP4,直接下载整段;如只要音频,后续用 FFmpeg 抽取
                var url = durl[0].GetProperty("url").GetString();
                Console.WriteLine("合轨直链: " + url);

                var bytes = await http.GetByteArrayAsync(url);
                //outFile = $"video_{cid}.mp4";
                await File.WriteAllBytesAsync(outFile, bytes);
                Console.WriteLine($"已保存合轨文件:{outFile}(如需仅音频,请用 FFmpeg 抽音轨)");
            }
            else
            {
                throw new InvalidOperationException("返回既无 dash 也无 durl,可能需要登录 Cookie 或接口参数调整。");
            }
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());

        }
        return false;
    }
}

注意这里的音频获取的格式是m4s。如果需要转换的话还需要FFmpeg。

kotlin 复制代码
            throw new InvalidOperationException("返回既无 dash 也无 durl,可能需要登录 Cookie 或接口参数调整。");
        }
        return true;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());

    }
    return false;
}

}

ini 复制代码
tn2>注意这里的音频获取的格式是`m4s`。如果需要转换的话还需要FFmpeg。

![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/1870103f264740f990f3858349ef3601~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5bCY5Y-25b-D566A:q75.awebp?rk3s=f64ab15b&x-expires=1756458198&x-signature=bK45qCASVuuEbkJ5e5DwzLDSARw%3D)
相关推荐
张飞洪5 小时前
C# 13 与 .NET 9 跨平台开发实战:基于.NET 9 与 EF Core 9 的现代网站与服务开发
开发语言·c#·.net
许泽宇的技术分享5 小时前
从零到一构建企业级GraphRAG系统:GraphRag.Net深度技术解析
.net
追逐时光者1 天前
2025 年全面的 C#/.NET/.NET Core 学习路线集合,学习不迷路!
后端·.net
SchuylerEX1 天前
第六章 JavaScript 互操(2).NET调用JS
前端·c#·.net·blazor·ui框架
百锦再1 天前
一文精通 Swagger 在 .NET 中的全方位配置与应用
后端·ui·.net·接口·配置·swagger·访问
Nita.1 天前
.NET 中的延迟初始化:Lazy<T> 与LazyInitializer
c#·.net
时光追逐者2 天前
C#/.NET/.NET Core技术前沿周刊 | 第 50 期(2025年8.11-8.17)
c#·.net·.netcore·.net core
SEO-狼术2 天前
Pcloudy 7.6 adds QuantumRun
.net