
#使用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
{
>#使用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。
