使用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)
相关推荐
唐青枫3 小时前
内存为什么越来越高?C#.NET GC 详解:分代回收、LOH、终结器与性能优化实战
c#·.net
日落飞雪4 小时前
重塑 .NET 国际化工作流:时光恒Net多语言生成系统,让出海更简单
.net
日落飞雪4 小时前
从 .NET 11 到 ARM64:时光恒Net 系统 v1.06 进化全纪实,定义自动化翻译新高度!
.net·wpf开发·net国际化·net本地化·net多语言
rockey62718 小时前
AScript之eval函数详解
c#·.net·script·eval·expression·动态脚本
周杰伦fans2 天前
AutoCAD .NET 二次开发:深入理解 EntityJig 的工作原理与正确实现
开发语言·.net
William_cl2 天前
【C#/.NET 进阶】ASP.NET 架构与最佳实践:DI 依赖注入(IoC 核心)从入门到避坑
c#·asp.net·.net
武藤一雄2 天前
WPF:MessageBox系统消息框
前端·microsoft·c#·.net·wpf
武藤一雄2 天前
WPF进阶:万字详解WPF如何性能优化
windows·性能优化·c#·.net·wpf·.netcore·鲁棒性
唐青枫3 天前
别再层层传参了!C#.NET AsyncLocal 异步上下文透传实战
c#·.net
小邓的技术笔记3 天前
.NET 10 使用 Microsoft.AspNetCore.OpenApi 实现 API 版本管理
.net