mirror of
https://github.com/cxfksword/jellyfin-plugin-danmu.git
synced 2026-02-03 02:04:47 +08:00
@@ -23,11 +23,7 @@ using System.Web;
|
||||
using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Jellyfin.Plugin.Danmu.Providers;
|
||||
using Bilibili.Community.Service.Dm.V1;
|
||||
using System.IO;
|
||||
using Danmaku2Ass;
|
||||
using Jellyfin.Plugin.Danmu.Core.Danmaku2Ass;
|
||||
|
||||
|
||||
namespace Jellyfin.Plugin.Danmu.Api
|
||||
{
|
||||
public class BilibiliApi : IDisposable
|
||||
@@ -268,98 +264,6 @@ namespace Jellyfin.Plugin.Danmu.Api
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载实时弹幕,返回弹幕列表
|
||||
/// </summary>
|
||||
/// <param name="avid">稿件avID</param>
|
||||
/// <param name="cid">视频CID</param>
|
||||
public async Task<byte[]> GetDanmuProtoAsync(long avid, long cid, CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><i>");
|
||||
try
|
||||
{
|
||||
var segmentIndex = 1; // 分包,每6分钟一包
|
||||
while (true)
|
||||
{
|
||||
var url = $"https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid={cid}&pid={avid}&segment_index={segmentIndex}";
|
||||
|
||||
var bytes = await httpClient.GetByteArrayAsync(url, cancellationToken).ConfigureAwait(false);
|
||||
var danmuReply = DmSegMobileReply.Parser.ParseFrom(bytes);
|
||||
if (danmuReply == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
foreach (var dm in danmuReply.Elems)
|
||||
{
|
||||
// <d p="944.95400,5,25,16707842,1657598634,0,ece5c9d1,1094775706690331648,11">今天的风儿甚是喧嚣</d>
|
||||
// time, mode, size, color, create, pool, sender, id, weight(屏蔽等级)
|
||||
var str = string.Format("<d p=\"{0:0.#####},{1},{2},{3},{4},{5},{6},{7},{8}\">{9}</d>", (double)dm.Progress / 1000, dm.Mode, dm.Fontsize, dm.Color, dm.Ctime, dm.Pool, dm.MidHash, dm.IdStr, dm.Weight, dm.Content);
|
||||
sb.AppendFormat("<d p=\"{0},{1},{2},{3},{4},{5},{6},{7},{8}\">{9}</d>", (double)dm.Progress / 1000, dm.Mode, dm.Fontsize, dm.Color, dm.Ctime, dm.Pool, dm.MidHash, dm.IdStr, dm.Weight, dm.Content);
|
||||
}
|
||||
|
||||
segmentIndex += 1;
|
||||
}
|
||||
} catch(Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
sb.Append("</i>");
|
||||
return Encoding.UTF8.GetBytes(sb.ToString());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 下载历史弹幕,返回弹幕列表
|
||||
/// </summary>
|
||||
/// <param name="cid">视频CID</param>
|
||||
/// <param name="date">弹幕日期,格式:YYYY-MM-DD</param>
|
||||
public async Task<byte[]> GetDanmuHistoryProtoAsync(long cid, string date, CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><i>");
|
||||
try
|
||||
{
|
||||
var segmentIndex = 1; // 分包,每6分钟一包
|
||||
while (true)
|
||||
{
|
||||
var url = $"http://api.bilibili.com/x/v2/dm/web/history/seg.so?type=1&oid={cid}&date={date}";
|
||||
|
||||
var bytes = await httpClient.GetByteArrayAsync(url, cancellationToken).ConfigureAwait(false);
|
||||
var danmuReply = DmSegMobileReply.Parser.ParseFrom(bytes);
|
||||
if (danmuReply == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
foreach (var dm in danmuReply.Elems)
|
||||
{
|
||||
// <d p="944.95400,5,25,16707842,1657598634,0,ece5c9d1,1094775706690331648,11">今天的风儿甚是喧嚣</d>
|
||||
// time, mode, size, color, create, pool, sender, id, weight(屏蔽等级)
|
||||
var str = string.Format("<d p=\"{0:0.#####},{1},{2},{3},{4},{5},{6},{7},{8}\">{9}</d>", (double)dm.Progress / 1000, dm.Mode, dm.Fontsize, dm.Color, dm.Ctime, dm.Pool, dm.MidHash, dm.IdStr, dm.Weight, dm.Content);
|
||||
sb.AppendFormat("<d p=\"{0},{1},{2},{3},{4},{5},{6},{7},{8}\">{9}</d>", (double)dm.Progress / 1000, dm.Mode, dm.Fontsize, dm.Color, dm.Ctime, dm.Pool, dm.MidHash, dm.IdStr, dm.Weight, dm.Content);
|
||||
}
|
||||
|
||||
segmentIndex += 1;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
sb.Append("</i>");
|
||||
return Encoding.UTF8.GetBytes(sb.ToString());
|
||||
}
|
||||
|
||||
public async Task<String> CheckDanmuHistoryListAsync(long cid, string month, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = $"http://api.bilibili.com/x/v2/dm/history/index?type=1&oid={cid}&month={month}";
|
||||
return await httpClient.GetStringAsync(url, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task EnsureSessionCookie(CancellationToken cancellationToken)
|
||||
{
|
||||
var url = "https://www.bilibili.com";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Google.Protobuf" Version="3.21.9" />
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.8.0" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.8.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -264,7 +264,9 @@ public class LibraryManagerEventsHelper : IDisposable
|
||||
}
|
||||
|
||||
// 下载弹幕xml文件
|
||||
await this.DownloadDanmu(item, epId).ConfigureAwait(false);
|
||||
var bytes = await _api.GetDanmuContentAsync(epId, CancellationToken.None).ConfigureAwait(false);
|
||||
var danmuPath = Path.Combine(item.ContainingFolderPath, item.FileNameWithoutExtension + ".xml");
|
||||
await File.WriteAllBytesAsync(danmuPath, bytes, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
// 延迟200毫秒,避免请求太频繁
|
||||
Thread.Sleep(200);
|
||||
@@ -824,7 +826,7 @@ public class LibraryManagerEventsHelper : IDisposable
|
||||
}
|
||||
|
||||
var assPath = Path.Combine(item.ContainingFolderPath, item.FileNameWithoutExtension + ".danmu.ass");
|
||||
Danmaku2Ass.Bilibili.GetInstance().Create(Encoding.UTF8.GetString(bytes), assConfig, assPath);
|
||||
Bilibili.GetInstance().Create(Encoding.UTF8.GetString(bytes), assConfig, assPath);
|
||||
}
|
||||
|
||||
this._logger.LogInformation("弹幕下载成功:name={0}", item.Name);
|
||||
|
||||
Reference in New Issue
Block a user