feat: support jellyfin 10.11. #96

This commit is contained in:
cxfksword
2025-10-27 23:02:52 +08:00
parent c63f36bf85
commit 649a42ebe0
33 changed files with 366 additions and 80 deletions

View File

@@ -4,7 +4,7 @@ on:
workflow_dispatch:
env:
dotnet-version: 8.0.x
dotnet-version: 9.0.x
python-version: 3.8
project: Jellyfin.Plugin.Danmu/Jellyfin.Plugin.Danmu.csproj
artifact: danmu
@@ -43,9 +43,9 @@ jobs:
- name: Build
run: |
dotnet restore ${{ env.project }} --no-cache
dotnet publish --nologo --no-restore --configuration=Release --framework=net8.0 ${{ env.project }}
dotnet publish --nologo --no-restore --configuration=Release --framework=net9.0 ${{ env.project }}
mkdir -p artifacts
cp ./Jellyfin.Plugin.Danmu/bin/Release/net8.0/Jellyfin.Plugin.Danmu.dll ./artifacts/
cp ./Jellyfin.Plugin.Danmu/bin/Release/net9.0/Jellyfin.Plugin.Danmu.dll ./artifacts/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:

View File

@@ -14,7 +14,7 @@ jobs:
- uses: actions/setup-dotnet@v3
id: dotnet
with:
dotnet-version: 8.0.x
dotnet-version: 9.0.x
- name: Change default dotnet version
run: |
echo '{"sdk":{"version": "${{ steps.dotnet.outputs.dotnet-version }}"}}' > ./global.json

View File

@@ -5,7 +5,7 @@ on:
tags: ["*"]
env:
dotnet-version: 8.0.x
dotnet-version: 9.0.x
python-version: 3.8
project: Jellyfin.Plugin.Danmu/Jellyfin.Plugin.Danmu.csproj
artifact: danmu
@@ -50,9 +50,9 @@ jobs:
- name: Build
run: |
dotnet restore ${{ env.project }} --no-cache
dotnet publish --nologo --no-restore --configuration=Release --framework=net8.0 -p:Version=${{steps.vars.outputs.VERSION}} ${{ env.project }}
dotnet publish --nologo --no-restore --configuration=Release --framework=net9.0 -p:Version=${{steps.vars.outputs.VERSION}} ${{ env.project }}
mkdir -p artifacts
zip -j ./artifacts/${{ env.artifact }}_${{steps.vars.outputs.VERSION}}.zip ./Jellyfin.Plugin.Danmu/bin/Release/net8.0/Jellyfin.Plugin.Danmu.dll
zip -j ./artifacts/${{ env.artifact }}_${{steps.vars.outputs.VERSION}}.zip ./Jellyfin.Plugin.Danmu/bin/Release/net9.0/Jellyfin.Plugin.Danmu.dll
- name: Generate manifest
run: python3 ./scripts/generate_manifest.py ./artifacts/${{ env.artifact }}_${{steps.vars.outputs.VERSION}}.zip ${GITHUB_REF#refs/*/}
env:

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>

View File

@@ -137,6 +137,10 @@ public class ScraperConfigItem
public class DanmuDownloadOption
{
/// <summary>
/// 弹幕自动匹配下载.
/// </summary>
public bool EnableAutoDownload { get; set; } = true;
/// <summary>
/// 检测弹幕数和视频剧集数需要一致才自动下载弹幕.
/// </summary>

View File

@@ -25,16 +25,17 @@
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend>
<h3>弹幕配置</h3>
<h3>弹幕下载配置</h3>
</legend>
<div class="checkboxList paperList checkboxList-paperList" id="Scrapers" name="Scrapers">
</div>
</fieldset>
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend>
<h3>弹幕匹配下载配置</h3>
</legend>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="EnableAutoDownload" name="EnableAutoDownload" type="checkbox"
is="emby-checkbox" />
<span>弹幕自动匹配下载</span>
</label>
<div class="fieldDescription">勾选后,有新影片入库会自动匹配下载,不勾选需要自己搜索下载。</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
@@ -46,6 +47,15 @@
</div>
</fieldset>
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend>
<h3>弹幕源配置</h3>
</legend>
<div class="checkboxList paperList checkboxList-paperList" id="Scrapers" name="Scrapers">
</div>
</fieldset>
<fieldset id="dandanSection" class="verticalSection verticalSection-extrabottompadding" style="display: none;">
<legend>
<h3>弹弹play配置</h3>
@@ -143,6 +153,7 @@
document.querySelector('#AssLineCount').value = config.AssLineCount;
document.querySelector('#AssSpeed').value = config.AssSpeed;
document.querySelector('#EnableAutoDownload').checked = config.DownloadOption.EnableAutoDownload;
document.querySelector('#EnableEpisodeCountSame').checked = config.DownloadOption.EnableEpisodeCountSame;
document.querySelector('#WithRelatedDanmu').checked = config.Dandan.WithRelatedDanmu;
@@ -194,6 +205,7 @@
var download = new Object();
download.EnableEpisodeCountSame = document.querySelector('#EnableEpisodeCountSame').checked;
download.EnableAutoDownload = document.querySelector('#EnableAutoDownload').checked;
config.DownloadOption = download;
var dandan = new Object();

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Jellyfin.Plugin.Danmu</RootNamespace>
<GenerateDocumentationFile>False</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
@@ -21,8 +21,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Jellyfin.Controller" Version="10.9.0" />
<PackageReference Include="Jellyfin.Model" Version="10.9.0" />
<PackageReference Include="Jellyfin.Controller" Version="10.*-*" />
<PackageReference Include="Jellyfin.Model" Version="10.*-*" />
<PackageReference Include="RateLimiter" Version="2.2.0" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
</ItemGroup>

View File

@@ -282,14 +282,8 @@ public class LibraryManagerEventsHelper : IDisposable
var mediaId = await scraper.SearchMediaId(currentItem).ConfigureAwait(false);
if (string.IsNullOrEmpty(mediaId))
{
_logger.LogInformation("[{0}]元数据匹配失败:{1} ({2}),尝试文件匹配", scraper.Name, item.Name, item.ProductionYear);
mediaId = await scraper.SearchMediaIdByFile((Movie)currentItem).ConfigureAwait(false);
if (string.IsNullOrEmpty(mediaId))
{
_logger.LogInformation("[{0}]文件匹配失败:{1}", scraper.Name, currentItem.Path);
continue;
}
_logger.LogInformation("[{0}]元数据匹配失败:{1} ({2})", scraper.Name, item.Name, item.ProductionYear);
continue;
}
var media = await scraper.GetMedia(item, mediaId);

View File

@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller;
using Microsoft.Extensions.Logging;
using Jellyfin.Plugin.Danmu.Model;
using Jellyfin.Plugin.Danmu.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
@@ -20,6 +21,14 @@ namespace Jellyfin.Plugin.Danmu
private readonly LibraryManagerEventsHelper _libraryManagerEventsHelper;
private readonly ILogger<PluginStartup> _logger;
public PluginConfiguration Config
{
get
{
return Plugin.Instance?.Configuration ?? new Configuration.PluginConfiguration();
}
}
/// <summary>
/// Initializes a new instance of the <see cref="PluginStartup"/> class.
/// </summary>
@@ -60,6 +69,11 @@ namespace Jellyfin.Plugin.Danmu
/// <param name="itemChangeEventArgs">The <see cref="ItemChangeEventArgs"/>.</param>
private void LibraryManagerItemAdded(object sender, ItemChangeEventArgs itemChangeEventArgs)
{
if (!Config.DownloadOption.EnableAutoDownload)
{
return;
}
// Don't do anything if it's not a supported media type
if (itemChangeEventArgs.Item is not Movie and not Episode and not Series and not Season)
{
@@ -83,6 +97,11 @@ namespace Jellyfin.Plugin.Danmu
/// <param name="itemChangeEventArgs">The <see cref="ItemChangeEventArgs"/>.</param>
private void LibraryManagerItemUpdated(object sender, ItemChangeEventArgs itemChangeEventArgs)
{
if (!Config.DownloadOption.EnableAutoDownload)
{
return;
}
// Don't do anything if it's not a supported media type
if (itemChangeEventArgs.Item is not Movie and not Episode and not Series and not Season)
{

View File

@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Bilibili.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
/// <inheritdoc />
public string UrlFormatString => "https://www.bilibili.com/bangumi/play/ep{0}";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Episode;
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
namespace Jellyfin.Plugin.Danmu.Scrapers.Bilibili.ExternalId;
/// <summary>
/// External URLs for Danmu.
/// </summary>
public class ExternalUrlProvider : IExternalUrlProvider
{
/// <inheritdoc/>
public string Name => Bilibili.ScraperProviderName;
/// <inheritdoc/>
public IEnumerable<string> GetExternalUrls(BaseItem item)
{
switch (item)
{
case Season season:
if (item.TryGetProviderId(Bilibili.ScraperProviderId, out var externalId))
{
if (externalId.StartsWith("bv", StringComparison.OrdinalIgnoreCase) || externalId.StartsWith("av", StringComparison.OrdinalIgnoreCase))
{
yield return $"https://www.bilibili.com/{externalId}";
}
else
{
yield return $"https://www.bilibili.com/bangumi/play/ss{externalId}";
}
}
break;
case Episode episode:
if (item.TryGetProviderId(Bilibili.ScraperProviderId, out externalId))
{
yield return $"https://www.bilibili.com/bangumi/play/ep{externalId}";
}
break;
case Movie:
if (item.TryGetProviderId(Bilibili.ScraperProviderId, out externalId))
{
yield return $"https://www.bilibili.com/bangumi/play/ep{externalId}";
}
break;
}
}
}

View File

@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Bilibili.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => ExternalIdMediaType.Movie;
/// <inheritdoc />
public string UrlFormatString => "https://www.bilibili.com/bangumi/play/ep{0}";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Movie;
}

View File

@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Bilibili.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => ExternalIdMediaType.Season;
/// <inheritdoc />
public string UrlFormatString => "https://www.bilibili.com/bangumi/play/ss{0}";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Season;
}

View File

@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Dandan.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
/// <inheritdoc />
public string UrlFormatString => "#";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Episode;
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
namespace Jellyfin.Plugin.Danmu.Scrapers.Dandan.ExternalId;
/// <summary>
/// External URLs for Danmu.
/// </summary>
public class ExternalUrlProvider : IExternalUrlProvider
{
/// <inheritdoc/>
public string Name => Dandan.ScraperProviderName;
/// <inheritdoc/>
public IEnumerable<string> GetExternalUrls(BaseItem item)
{
switch (item)
{
case Season season:
if (item.TryGetProviderId(Dandan.ScraperProviderId, out var externalId))
{
yield return $"https://api.dandanplay.net/api/v2/bangumi/{externalId}";
}
break;
case Episode episode:
if (item.TryGetProviderId(Dandan.ScraperProviderId, out externalId))
{
yield return "#";
}
break;
case Movie:
if (item.TryGetProviderId(Dandan.ScraperProviderId, out externalId))
{
yield return $"https://api.dandanplay.net/api/v2/bangumi/{externalId}";
}
break;
}
}
}

View File

@@ -21,10 +21,7 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Dandan.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => null;
/// <inheritdoc />
public string UrlFormatString => "https://api.dandanplay.net/api/v2/bangumi/{0}";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Movie;
}

View File

@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Dandan.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => null;
/// <inheritdoc />
public string UrlFormatString => "https://api.dandanplay.net/api/v2/bangumi/{0}";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Season;
}

View File

@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Iqiyi.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
/// <inheritdoc />
public string UrlFormatString => "https://www.iqiyi.com/v_{0}.html";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Episode;
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
namespace Jellyfin.Plugin.Danmu.Scrapers.Iqiyi.ExternalId;
/// <summary>
/// External URLs for Danmu.
/// </summary>
public class ExternalUrlProvider : IExternalUrlProvider
{
/// <inheritdoc/>
public string Name => Iqiyi.ScraperProviderName;
/// <inheritdoc/>
public IEnumerable<string> GetExternalUrls(BaseItem item)
{
switch (item)
{
case Season season:
if (item.TryGetProviderId(Iqiyi.ScraperProviderId, out var externalId))
{
yield return $"https://www.iqiyi.com/v_{externalId}.html";
}
break;
case Episode episode:
if (item.TryGetProviderId(Iqiyi.ScraperProviderId, out externalId))
{
yield return $"https://www.iqiyi.com/v_{externalId}.html";
}
break;
case Movie:
if (item.TryGetProviderId(Iqiyi.ScraperProviderId, out externalId))
{
yield return $"https://www.iqiyi.com/v_{externalId}.html";
}
break;
}
}
}

View File

@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Iqiyi.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => null;
/// <inheritdoc />
public string UrlFormatString => "https://www.iqiyi.com/v_{0}.html";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Movie;
}

View File

@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Iqiyi.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => null;
/// <inheritdoc />
public string UrlFormatString => "https://www.iqiyi.com/v_{0}.html";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Season;
}

View File

@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Mgtv.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
/// <inheritdoc />
public string UrlFormatString => "#";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Episode;
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
namespace Jellyfin.Plugin.Danmu.Scrapers.Mgtv.ExternalId;
/// <summary>
/// External URLs for Danmu.
/// </summary>
public class ExternalUrlProvider : IExternalUrlProvider
{
/// <inheritdoc/>
public string Name => Mgtv.ScraperProviderName;
/// <inheritdoc/>
public IEnumerable<string> GetExternalUrls(BaseItem item)
{
switch (item)
{
case Season season:
if (item.TryGetProviderId(Mgtv.ScraperProviderId, out var externalId))
{
yield return $"https://www.mgtv.com/h/{externalId}.html";
}
break;
case Episode episode:
if (item.TryGetProviderId(Mgtv.ScraperProviderId, out externalId))
{
if (episode.Season?.TryGetProviderId(Mgtv.ScraperProviderId, out var seasonExternalId) == true)
{
yield return $"https://www.mgtv.com/b/{seasonExternalId}/{externalId}.html";
}
else
{
yield return "#";
}
}
break;
case Movie:
if (item.TryGetProviderId(Mgtv.ScraperProviderId, out externalId))
{
yield return $"https://www.mgtv.com/h/{externalId}.html";
}
break;
}
}
}

View File

@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Mgtv.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => null;
/// <inheritdoc />
public string UrlFormatString => "https://www.mgtv.com/h/{0}.html";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Movie;
}

View File

@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Mgtv.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => null;
/// <inheritdoc />
public string UrlFormatString => "https://www.mgtv.com/h/{0}.html";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Season;
}

View File

@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Tencent.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
/// <inheritdoc />
public string UrlFormatString => "#";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Episode;
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
namespace Jellyfin.Plugin.Danmu.Scrapers.Tencent.ExternalId;
/// <summary>
/// External URLs for Danmu.
/// </summary>
public class ExternalUrlProvider : IExternalUrlProvider
{
/// <inheritdoc/>
public string Name => Tencent.ScraperProviderName;
/// <inheritdoc/>
public IEnumerable<string> GetExternalUrls(BaseItem item)
{
switch (item)
{
case Season season:
if (item.TryGetProviderId(Tencent.ScraperProviderId, out var externalId))
{
yield return $"https://v.qq.com/x/cover/{externalId}.html";
}
break;
case Episode episode:
if (item.TryGetProviderId(Tencent.ScraperProviderId, out externalId))
{
if (episode.Season?.TryGetProviderId(Tencent.ScraperProviderId, out var seasonExternalId) == true)
{
yield return $"https://v.qq.com/x/cover/{seasonExternalId}/{externalId}.html";
}
else
{
yield return "#";
}
}
break;
case Movie:
if (item.TryGetProviderId(Tencent.ScraperProviderId, out externalId))
{
yield return $"https://v.qq.com/x/cover/{externalId}.html";
}
break;
}
}
}

View File

@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Tencent.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => null;
/// <inheritdoc />
public string UrlFormatString => "https://v.qq.com/x/cover/{0}.html";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Movie;
}

View File

@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Tencent.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => null;
/// <inheritdoc />
public string UrlFormatString => "https://v.qq.com/x/cover/{0}.html";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Season;
}

View File

@@ -21,10 +21,7 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Youku.ExternalId
/// <inheritdoc />
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
/// <inheritdoc />
public string UrlFormatString => "https://v.youku.com/v_show/id_{0}.html";
/// <inheritdoc />
public bool Supports(IHasProviderIds item) => item is Episode;
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Web;
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
namespace Jellyfin.Plugin.Danmu.Scrapers.Youku.ExternalId;
/// <summary>
/// External URLs for Danmu.
/// </summary>
public class ExternalUrlProvider : IExternalUrlProvider
{
/// <inheritdoc/>
public string Name => Youku.ScraperProviderName;
/// <inheritdoc/>
public IEnumerable<string> GetExternalUrls(BaseItem item)
{
switch (item)
{
case Season season:
if (item.TryGetProviderId(Youku.ScraperProviderId, out var externalId))
{
yield return $"https://v.youku.com/v_nextstage/id_{externalId}.html";
}
break;
case Episode episode:
if (item.TryGetProviderId(Youku.ScraperProviderId, out externalId))
{
var decodeExternalId = HttpUtility.UrlDecode(externalId).Replace("||", "==");
yield return $"https://v.youku.com/v_show/id_{decodeExternalId}.html";
}
break;
case Movie:
if (item.TryGetProviderId(Youku.ScraperProviderId, out externalId))
{
yield return $"https://v.youku.com/v_nextstage/id_{externalId}.html";
}
break;
}
}
}

View File

@@ -69,7 +69,7 @@ ass格式
1. Clone or download this repository
2. Ensure you have .NET Core SDK 8.0 setup and installed
2. Ensure you have .NET Core SDK 9.0 setup and installed
3. Build plugin with following command.
@@ -83,7 +83,7 @@ dotnet publish --configuration=Release Jellyfin.Plugin.Danmu/Jellyfin.Plugin.Dan
1. Build the plugin
2. Create a folder, like `danmu` and copy `./Jellyfin.Plugin.Danmu/bin/Release/net8.0/Jellyfin.Plugin.Danmu.dll` into it
2. Create a folder, like `danmu` and copy `./Jellyfin.Plugin.Danmu/bin/Release/net9.0/Jellyfin.Plugin.Danmu.dll` into it
3. Move folder `danmu` to jellyfin `data/plugins` folder

View File

@@ -26,7 +26,7 @@ def generate_version(filepath, version, changelog):
return {
'version': f"{version}.0",
'changelog': changelog,
'targetAbi': '10.9.0.0',
'targetAbi': '10.11.0.0',
'sourceUrl': f'https://github.com/cxfksword/jellyfin-plugin-danmu/releases/download/v{version}/danmu_{version}.0.zip',
'checksum': md5sum(filepath),
'timestamp': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')