mirror of
https://github.com/cxfksword/jellyfin-plugin-danmu.git
synced 2026-02-02 17:59:58 +08:00
feat: support jellyfin 10.11. #96
This commit is contained in:
6
.github/workflows/beta.yaml
vendored
6
.github/workflows/beta.yaml
vendored
@@ -4,7 +4,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 9.0.x
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
project: Jellyfin.Plugin.Danmu/Jellyfin.Plugin.Danmu.csproj
|
project: Jellyfin.Plugin.Danmu/Jellyfin.Plugin.Danmu.csproj
|
||||||
artifact: danmu
|
artifact: danmu
|
||||||
@@ -43,9 +43,9 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
dotnet restore ${{ env.project }} --no-cache
|
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
|
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
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v3
|
||||||
id: dotnet
|
id: dotnet
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 9.0.x
|
||||||
- name: Change default dotnet version
|
- name: Change default dotnet version
|
||||||
run: |
|
run: |
|
||||||
echo '{"sdk":{"version": "${{ steps.dotnet.outputs.dotnet-version }}"}}' > ./global.json
|
echo '{"sdk":{"version": "${{ steps.dotnet.outputs.dotnet-version }}"}}' > ./global.json
|
||||||
|
|||||||
6
.github/workflows/publish.yaml
vendored
6
.github/workflows/publish.yaml
vendored
@@ -5,7 +5,7 @@ on:
|
|||||||
tags: ["*"]
|
tags: ["*"]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 9.0.x
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
project: Jellyfin.Plugin.Danmu/Jellyfin.Plugin.Danmu.csproj
|
project: Jellyfin.Plugin.Danmu/Jellyfin.Plugin.Danmu.csproj
|
||||||
artifact: danmu
|
artifact: danmu
|
||||||
@@ -50,9 +50,9 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
dotnet restore ${{ env.project }} --no-cache
|
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
|
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
|
- name: Generate manifest
|
||||||
run: python3 ./scripts/generate_manifest.py ./artifacts/${{ env.artifact }}_${{steps.vars.outputs.VERSION}}.zip ${GITHUB_REF#refs/*/}
|
run: python3 ./scripts/generate_manifest.py ./artifacts/${{ env.artifact }}_${{steps.vars.outputs.VERSION}}.zip ${GITHUB_REF#refs/*/}
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
|||||||
@@ -137,6 +137,10 @@ public class ScraperConfigItem
|
|||||||
|
|
||||||
public class DanmuDownloadOption
|
public class DanmuDownloadOption
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 弹幕自动匹配下载.
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableAutoDownload { get; set; } = true;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检测弹幕数和视频剧集数需要一致才自动下载弹幕.
|
/// 检测弹幕数和视频剧集数需要一致才自动下载弹幕.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -25,16 +25,17 @@
|
|||||||
|
|
||||||
<fieldset class="verticalSection verticalSection-extrabottompadding">
|
<fieldset class="verticalSection verticalSection-extrabottompadding">
|
||||||
<legend>
|
<legend>
|
||||||
<h3>弹幕源配置</h3>
|
<h3>弹幕下载配置</h3>
|
||||||
</legend>
|
</legend>
|
||||||
<div class="checkboxList paperList checkboxList-paperList" id="Scrapers" name="Scrapers">
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset class="verticalSection verticalSection-extrabottompadding">
|
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||||
<legend>
|
<label class="emby-checkbox-label">
|
||||||
<h3>弹幕匹配下载配置</h3>
|
<input id="EnableAutoDownload" name="EnableAutoDownload" type="checkbox"
|
||||||
</legend>
|
is="emby-checkbox" />
|
||||||
|
<span>弹幕自动匹配下载</span>
|
||||||
|
</label>
|
||||||
|
<div class="fieldDescription">勾选后,有新影片入库会自动匹配下载,不勾选需要自己搜索下载。</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||||
<label class="emby-checkbox-label">
|
<label class="emby-checkbox-label">
|
||||||
@@ -46,6 +47,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</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;">
|
<fieldset id="dandanSection" class="verticalSection verticalSection-extrabottompadding" style="display: none;">
|
||||||
<legend>
|
<legend>
|
||||||
<h3>弹弹play配置</h3>
|
<h3>弹弹play配置</h3>
|
||||||
@@ -143,6 +153,7 @@
|
|||||||
document.querySelector('#AssLineCount').value = config.AssLineCount;
|
document.querySelector('#AssLineCount').value = config.AssLineCount;
|
||||||
document.querySelector('#AssSpeed').value = config.AssSpeed;
|
document.querySelector('#AssSpeed').value = config.AssSpeed;
|
||||||
|
|
||||||
|
document.querySelector('#EnableAutoDownload').checked = config.DownloadOption.EnableAutoDownload;
|
||||||
document.querySelector('#EnableEpisodeCountSame').checked = config.DownloadOption.EnableEpisodeCountSame;
|
document.querySelector('#EnableEpisodeCountSame').checked = config.DownloadOption.EnableEpisodeCountSame;
|
||||||
|
|
||||||
document.querySelector('#WithRelatedDanmu').checked = config.Dandan.WithRelatedDanmu;
|
document.querySelector('#WithRelatedDanmu').checked = config.Dandan.WithRelatedDanmu;
|
||||||
@@ -194,6 +205,7 @@
|
|||||||
|
|
||||||
var download = new Object();
|
var download = new Object();
|
||||||
download.EnableEpisodeCountSame = document.querySelector('#EnableEpisodeCountSame').checked;
|
download.EnableEpisodeCountSame = document.querySelector('#EnableEpisodeCountSame').checked;
|
||||||
|
download.EnableAutoDownload = document.querySelector('#EnableAutoDownload').checked;
|
||||||
config.DownloadOption = download;
|
config.DownloadOption = download;
|
||||||
|
|
||||||
var dandan = new Object();
|
var dandan = new Object();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<RootNamespace>Jellyfin.Plugin.Danmu</RootNamespace>
|
<RootNamespace>Jellyfin.Plugin.Danmu</RootNamespace>
|
||||||
<GenerateDocumentationFile>False</GenerateDocumentationFile>
|
<GenerateDocumentationFile>False</GenerateDocumentationFile>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Jellyfin.Controller" Version="10.9.0" />
|
<PackageReference Include="Jellyfin.Controller" Version="10.*-*" />
|
||||||
<PackageReference Include="Jellyfin.Model" Version="10.9.0" />
|
<PackageReference Include="Jellyfin.Model" Version="10.*-*" />
|
||||||
<PackageReference Include="RateLimiter" Version="2.2.0" />
|
<PackageReference Include="RateLimiter" Version="2.2.0" />
|
||||||
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -282,14 +282,8 @@ public class LibraryManagerEventsHelper : IDisposable
|
|||||||
var mediaId = await scraper.SearchMediaId(currentItem).ConfigureAwait(false);
|
var mediaId = await scraper.SearchMediaId(currentItem).ConfigureAwait(false);
|
||||||
if (string.IsNullOrEmpty(mediaId))
|
if (string.IsNullOrEmpty(mediaId))
|
||||||
{
|
{
|
||||||
_logger.LogInformation("[{0}]元数据匹配失败:{1} ({2}),尝试文件匹配", scraper.Name, item.Name, item.ProductionYear);
|
_logger.LogInformation("[{0}]元数据匹配失败:{1} ({2})", scraper.Name, item.Name, item.ProductionYear);
|
||||||
|
continue;
|
||||||
mediaId = await scraper.SearchMediaIdByFile((Movie)currentItem).ConfigureAwait(false);
|
|
||||||
if (string.IsNullOrEmpty(mediaId))
|
|
||||||
{
|
|
||||||
_logger.LogInformation("[{0}]文件匹配失败:{1}", scraper.Name, currentItem.Path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var media = await scraper.GetMedia(item, mediaId);
|
var media = await scraper.GetMedia(item, mediaId);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library;
|
|||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Jellyfin.Plugin.Danmu.Model;
|
using Jellyfin.Plugin.Danmu.Model;
|
||||||
|
using Jellyfin.Plugin.Danmu.Configuration;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
@@ -20,6 +21,14 @@ namespace Jellyfin.Plugin.Danmu
|
|||||||
private readonly LibraryManagerEventsHelper _libraryManagerEventsHelper;
|
private readonly LibraryManagerEventsHelper _libraryManagerEventsHelper;
|
||||||
private readonly ILogger<PluginStartup> _logger;
|
private readonly ILogger<PluginStartup> _logger;
|
||||||
|
|
||||||
|
public PluginConfiguration Config
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Plugin.Instance?.Configuration ?? new Configuration.PluginConfiguration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PluginStartup"/> class.
|
/// Initializes a new instance of the <see cref="PluginStartup"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -60,6 +69,11 @@ namespace Jellyfin.Plugin.Danmu
|
|||||||
/// <param name="itemChangeEventArgs">The <see cref="ItemChangeEventArgs"/>.</param>
|
/// <param name="itemChangeEventArgs">The <see cref="ItemChangeEventArgs"/>.</param>
|
||||||
private void LibraryManagerItemAdded(object sender, ItemChangeEventArgs itemChangeEventArgs)
|
private void LibraryManagerItemAdded(object sender, ItemChangeEventArgs itemChangeEventArgs)
|
||||||
{
|
{
|
||||||
|
if (!Config.DownloadOption.EnableAutoDownload)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't do anything if it's not a supported media type
|
// 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)
|
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>
|
/// <param name="itemChangeEventArgs">The <see cref="ItemChangeEventArgs"/>.</param>
|
||||||
private void LibraryManagerItemUpdated(object sender, ItemChangeEventArgs itemChangeEventArgs)
|
private void LibraryManagerItemUpdated(object sender, ItemChangeEventArgs itemChangeEventArgs)
|
||||||
{
|
{
|
||||||
|
if (!Config.DownloadOption.EnableAutoDownload)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't do anything if it's not a supported media type
|
// 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)
|
if (itemChangeEventArgs.Item is not Movie and not Episode and not Series and not Season)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Bilibili.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://www.bilibili.com/bangumi/play/ep{0}";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Episode;
|
public bool Supports(IHasProviderIds item) => item is Episode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Bilibili.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => ExternalIdMediaType.Movie;
|
public ExternalIdMediaType? Type => ExternalIdMediaType.Movie;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://www.bilibili.com/bangumi/play/ep{0}";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Movie;
|
public bool Supports(IHasProviderIds item) => item is Movie;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Bilibili.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => ExternalIdMediaType.Season;
|
public ExternalIdMediaType? Type => ExternalIdMediaType.Season;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://www.bilibili.com/bangumi/play/ss{0}";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Season;
|
public bool Supports(IHasProviderIds item) => item is Season;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Dandan.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "#";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Episode;
|
public bool Supports(IHasProviderIds item) => item is Episode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,10 +21,7 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Dandan.ExternalId
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => null;
|
public ExternalIdMediaType? Type => null;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://api.dandanplay.net/api/v2/bangumi/{0}";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Movie;
|
public bool Supports(IHasProviderIds item) => item is Movie;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Dandan.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => null;
|
public ExternalIdMediaType? Type => null;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://api.dandanplay.net/api/v2/bangumi/{0}";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Season;
|
public bool Supports(IHasProviderIds item) => item is Season;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Iqiyi.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://www.iqiyi.com/v_{0}.html";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Episode;
|
public bool Supports(IHasProviderIds item) => item is Episode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Iqiyi.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => null;
|
public ExternalIdMediaType? Type => null;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://www.iqiyi.com/v_{0}.html";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Movie;
|
public bool Supports(IHasProviderIds item) => item is Movie;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Iqiyi.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => null;
|
public ExternalIdMediaType? Type => null;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://www.iqiyi.com/v_{0}.html";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Season;
|
public bool Supports(IHasProviderIds item) => item is Season;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Mgtv.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "#";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Episode;
|
public bool Supports(IHasProviderIds item) => item is Episode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Mgtv.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => null;
|
public ExternalIdMediaType? Type => null;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://www.mgtv.com/h/{0}.html";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Movie;
|
public bool Supports(IHasProviderIds item) => item is Movie;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Mgtv.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => null;
|
public ExternalIdMediaType? Type => null;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://www.mgtv.com/h/{0}.html";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Season;
|
public bool Supports(IHasProviderIds item) => item is Season;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Tencent.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "#";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Episode;
|
public bool Supports(IHasProviderIds item) => item is Episode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,9 +22,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Tencent.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => null;
|
public ExternalIdMediaType? Type => null;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://v.qq.com/x/cover/{0}.html";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Movie;
|
public bool Supports(IHasProviderIds item) => item is Movie;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Tencent.ExternalId
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => null;
|
public ExternalIdMediaType? Type => null;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://v.qq.com/x/cover/{0}.html";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Season;
|
public bool Supports(IHasProviderIds item) => item is Season;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,7 @@ namespace Jellyfin.Plugin.Danmu.Scrapers.Youku.ExternalId
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
public ExternalIdMediaType? Type => ExternalIdMediaType.Episode;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string UrlFormatString => "https://v.youku.com/v_show/id_{0}.html";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Supports(IHasProviderIds item) => item is Episode;
|
public bool Supports(IHasProviderIds item) => item is Episode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -69,7 +69,7 @@ ass格式:
|
|||||||
|
|
||||||
1. Clone or download this repository
|
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.
|
3. Build plugin with following command.
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ dotnet publish --configuration=Release Jellyfin.Plugin.Danmu/Jellyfin.Plugin.Dan
|
|||||||
|
|
||||||
1. Build the plugin
|
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
|
3. Move folder `danmu` to jellyfin `data/plugins` folder
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ def generate_version(filepath, version, changelog):
|
|||||||
return {
|
return {
|
||||||
'version': f"{version}.0",
|
'version': f"{version}.0",
|
||||||
'changelog': changelog,
|
'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',
|
'sourceUrl': f'https://github.com/cxfksword/jellyfin-plugin-danmu/releases/download/v{version}/danmu_{version}.0.zip',
|
||||||
'checksum': md5sum(filepath),
|
'checksum': md5sum(filepath),
|
||||||
'timestamp': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
|
'timestamp': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
|
||||||
|
|||||||
Reference in New Issue
Block a user