使用C#获取B站视频音频与用户信息 电脑版发表于:2025/8/22 16:51  >#使用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 { throw new InvalidOperationException("返回既无 dash 也无 durl,可能需要登录 Cookie 或接口参数调整。"); } return true; } catch (Exception ex) { Console.WriteLine(ex.ToString()); } return false; } } ``` tn2>注意这里的音频获取的格式是`m4s`。如果需要转换的话还需要FFmpeg。 