mirror of
https://github.com/91270/MeiamSubtitles.git
synced 2026-05-12 19:17:10 +08:00
添加项目文件。
This commit is contained in:
8
Emby.MeiamSub.DevTool/Emby.MeiamSub.DevTool.csproj
Normal file
8
Emby.MeiamSub.DevTool/Emby.MeiamSub.DevTool.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
45
Emby.MeiamSub.DevTool/Program.cs
Normal file
45
Emby.MeiamSub.DevTool/Program.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Emby.Subtitle.DevTool
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine(getCid($"X:\\Download\\冰路营救 (2021)\\冰路营救 (2021) 1080p AC3.mkv"));
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
private static string getCid(string filePath)
|
||||
{
|
||||
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||
var reader = new BinaryReader(stream);
|
||||
var fileSize = new FileInfo(filePath).Length;
|
||||
var SHA1 = new SHA1CryptoServiceProvider();
|
||||
var buffer = new byte[0xf000];
|
||||
if (fileSize < 0xf000)
|
||||
{
|
||||
reader.Read(buffer, 0, (int)fileSize);
|
||||
buffer = SHA1.ComputeHash(buffer, 0, (int)fileSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Read(buffer, 0, 0x5000);
|
||||
stream.Seek(fileSize / 3, SeekOrigin.Begin);
|
||||
reader.Read(buffer, 0x5000, 0x5000);
|
||||
stream.Seek(fileSize - 0x5000, SeekOrigin.Begin);
|
||||
reader.Read(buffer, 0xa000, 0x5000);
|
||||
|
||||
buffer = SHA1.ComputeHash(buffer, 0, 0xf000);
|
||||
}
|
||||
var result = "";
|
||||
foreach (var i in buffer)
|
||||
{
|
||||
result += String.Format("{0:X2}", i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Emby.MeiamSub.Thunder/Emby.MeiamSub.Thunder.csproj
Normal file
20
Emby.MeiamSub.Thunder/Emby.MeiamSub.Thunder.csproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Thumb.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Thumb.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MediaBrowser.Common" Version="4.6.0.50" />
|
||||
<PackageReference Include="MediaBrowser.Server.Core" Version="4.6.0.50" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
15
Emby.MeiamSub.Thunder/Model/DownloadSubInfo.cs
Normal file
15
Emby.MeiamSub.Thunder/Model/DownloadSubInfo.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Emby.MeiamSub.Thunder.Model
|
||||
{
|
||||
public class DownloadSubInfo
|
||||
{
|
||||
public string Url { get; set; }
|
||||
public string Format { get; set; }
|
||||
public string Language { get; set; }
|
||||
public string TwoLetterISOLanguageName { get; set; }
|
||||
public bool? IsForced { get; set; }
|
||||
}
|
||||
}
|
||||
44
Emby.MeiamSub.Thunder/Model/SubtitleResponseRoot.cs
Normal file
44
Emby.MeiamSub.Thunder/Model/SubtitleResponseRoot.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Emby.MeiamSub.Thunder.Model
|
||||
{
|
||||
public class SublistItem
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string scid { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string sname { get; set; }
|
||||
/// <summary>
|
||||
/// 未知语言
|
||||
/// </summary>
|
||||
public string language { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string rate { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string surl { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int svote { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int roffset { get; set; }
|
||||
}
|
||||
|
||||
public class SubtitleResponseRoot
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<SublistItem> sublist { get; set; }
|
||||
}
|
||||
}
|
||||
24
Emby.MeiamSub.Thunder/Plugin.cs
Normal file
24
Emby.MeiamSub.Thunder/Plugin.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Emby.MeiamSub.Thunder
|
||||
{
|
||||
public class Plugin : BasePlugin, IHasThumbImage
|
||||
{
|
||||
public override Guid Id => new Guid("E4CE9DA9-EF00-417C-96F2-861C512D45EB");
|
||||
|
||||
public override string Name => "ThunderSubtitle";
|
||||
|
||||
public override string Description => "Download subtitles from Thunder XMP";
|
||||
|
||||
public ImageFormat ThumbImageFormat => ImageFormat.Gif;
|
||||
|
||||
public Stream GetThumbImage()
|
||||
{
|
||||
var type = GetType();
|
||||
return type.Assembly.GetManifestResourceStream(type.Namespace + ".Thumb.png");
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Emby.MeiamSub.Thunder/Thumb.png
Normal file
BIN
Emby.MeiamSub.Thunder/Thumb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
196
Emby.MeiamSub.Thunder/ThunderProvider.cs
Normal file
196
Emby.MeiamSub.Thunder/ThunderProvider.cs
Normal file
@@ -0,0 +1,196 @@
|
||||
using Emby.MeiamSub.Thunder.Model;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Controller.Subtitles;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Emby.MeiamSub.Thunder
|
||||
{
|
||||
public class ThunderProvider : ISubtitleProvider, IHasOrder
|
||||
{
|
||||
public const string ASS = "ass";
|
||||
public const string SSA = "ssa";
|
||||
public const string SRT = "srt";
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public int Order => 1;
|
||||
public string Name => "ThunderSubtitle";
|
||||
|
||||
public IEnumerable<VideoContentType> SupportedMediaTypes => new List<VideoContentType>() { VideoContentType.Movie, VideoContentType.Episode };
|
||||
|
||||
public ThunderProvider(ILogger logger, IJsonSerializer jsonSerializer,IHttpClient httpClient)
|
||||
{
|
||||
_logger = logger;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RemoteSubtitleInfo>> Search(SubtitleSearchRequest request, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.Debug($"ThunderSubtitle Search | Request -> { _jsonSerializer.SerializeToString(request) }");
|
||||
|
||||
var subtitles = await SearchSubtitlesAsync(request);
|
||||
|
||||
return subtitles;
|
||||
}
|
||||
|
||||
|
||||
private async Task<IEnumerable<RemoteSubtitleInfo>> SearchSubtitlesAsync(SubtitleSearchRequest request)
|
||||
{
|
||||
var cid = GetCidByFile(request.MediaPath);
|
||||
|
||||
var response = await _httpClient.GetResponse(new HttpRequestOptions
|
||||
{
|
||||
Url = $"http://sub.xmp.sandai.net:8000/subxl/{cid}.json"
|
||||
});
|
||||
|
||||
_logger.Debug($"ThunderSubtitle Search | Response -> { _jsonSerializer.SerializeToString(response) }");
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
var subtitleResponse = _jsonSerializer.DeserializeFromStream<SubtitleResponseRoot>(response.Content);
|
||||
|
||||
if (subtitleResponse != null)
|
||||
{
|
||||
var subtitles = subtitleResponse.sublist.Where(m => !string.IsNullOrEmpty(m.sname));
|
||||
|
||||
if (subtitles.Count() > 0)
|
||||
{
|
||||
return subtitles.Select(m => new RemoteSubtitleInfo()
|
||||
{
|
||||
Id = Base64Encode(_jsonSerializer.SerializeToString(new DownloadSubInfo
|
||||
{
|
||||
Url = m.surl,
|
||||
Format = ExtractFormat(m.sname),
|
||||
Language = request.Language,
|
||||
TwoLetterISOLanguageName = request.TwoLetterISOLanguageName,
|
||||
IsForced = request.IsForced
|
||||
})),
|
||||
Name = Path.GetFileName(HttpUtility.UrlDecode(m.sname)),
|
||||
Author = "Meiam ",
|
||||
CommunityRating = Convert.ToSingle(m.rate),
|
||||
ProviderName = "ThunderSubtitle",
|
||||
Format = ExtractFormat(m.sname),
|
||||
Comment = $"Rate : { m.rate }"
|
||||
}).OrderByDescending(m => m.CommunityRating);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Array.Empty<RemoteSubtitleInfo>();
|
||||
}
|
||||
|
||||
public async Task<SubtitleResponse> GetSubtitles(string id, CancellationToken cancellationToken)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
_logger.Debug($"ThunderSubtitle DownloadSub | Request -> {id}");
|
||||
});
|
||||
|
||||
return await DownloadSubAsync(id);
|
||||
}
|
||||
|
||||
private async Task<SubtitleResponse> DownloadSubAsync(string info)
|
||||
{
|
||||
var downloadSub = _jsonSerializer.DeserializeFromString<DownloadSubInfo>(Base64Decode(info));
|
||||
|
||||
_logger.Debug($"ThunderSubtitle DownloadSub | Url -> { downloadSub.Url } | Format -> { downloadSub.Format } | Language -> { downloadSub.Language } ");
|
||||
|
||||
var response = await _httpClient.GetResponse(new HttpRequestOptions
|
||||
{
|
||||
Url = downloadSub.Url
|
||||
});
|
||||
|
||||
_logger.Debug($"ThunderSubtitle DownloadSub | Response -> { response.StatusCode }");
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
|
||||
return new SubtitleResponse()
|
||||
{
|
||||
Language = downloadSub.Language,
|
||||
IsForced = false,
|
||||
Format = downloadSub.Format,
|
||||
Stream = response.Content,
|
||||
};
|
||||
}
|
||||
|
||||
return new SubtitleResponse();
|
||||
|
||||
}
|
||||
|
||||
protected string ExtractFormat(string text)
|
||||
{
|
||||
|
||||
string result = null;
|
||||
|
||||
if (text != null)
|
||||
{
|
||||
text = text.ToLower();
|
||||
if (text.Contains(ASS)) result = ASS;
|
||||
else if (text.Contains(SSA)) result = SSA;
|
||||
else if (text.Contains(SRT)) result = SRT;
|
||||
else result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string Base64Encode(string plainText)
|
||||
{
|
||||
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
|
||||
return Convert.ToBase64String(plainTextBytes);
|
||||
}
|
||||
|
||||
public static string Base64Decode(string base64EncodedData)
|
||||
{
|
||||
var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
|
||||
return Encoding.UTF8.GetString(base64EncodedBytes);
|
||||
}
|
||||
|
||||
|
||||
private string GetCidByFile(string filePath)
|
||||
{
|
||||
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||
var reader = new BinaryReader(stream);
|
||||
var fileSize = new FileInfo(filePath).Length;
|
||||
var SHA1 = new SHA1CryptoServiceProvider();
|
||||
var buffer = new byte[0xf000];
|
||||
if (fileSize < 0xf000)
|
||||
{
|
||||
reader.Read(buffer, 0, (int)fileSize);
|
||||
buffer = SHA1.ComputeHash(buffer, 0, (int)fileSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Read(buffer, 0, 0x5000);
|
||||
stream.Seek(fileSize / 3, SeekOrigin.Begin);
|
||||
reader.Read(buffer, 0x5000, 0x5000);
|
||||
stream.Seek(fileSize - 0x5000, SeekOrigin.Begin);
|
||||
reader.Read(buffer, 0xa000, 0x5000);
|
||||
|
||||
buffer = SHA1.ComputeHash(buffer, 0, 0xf000);
|
||||
}
|
||||
var result = "";
|
||||
foreach (var i in buffer)
|
||||
{
|
||||
result += string.Format("{0:X2}", i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Emby.MeiamSub.sln
Normal file
31
Emby.MeiamSub.sln
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31424.327
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.MeiamSub.Thunder", "Emby.MeiamSub.Thunder\Emby.MeiamSub.Thunder.csproj", "{96F3F427-0EC3-4610-81C3-2C92D773EDC8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emby.MeiamSub.DevTool", "Emby.MeiamSub.DevTool\Emby.MeiamSub.DevTool.csproj", "{6B0C23EA-EC24-4FB0-948E-094E84AEBF21}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{96F3F427-0EC3-4610-81C3-2C92D773EDC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{96F3F427-0EC3-4610-81C3-2C92D773EDC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{96F3F427-0EC3-4610-81C3-2C92D773EDC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{96F3F427-0EC3-4610-81C3-2C92D773EDC8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6B0C23EA-EC24-4FB0-948E-094E84AEBF21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6B0C23EA-EC24-4FB0-948E-094E84AEBF21}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6B0C23EA-EC24-4FB0-948E-094E84AEBF21}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6B0C23EA-EC24-4FB0-948E-094E84AEBF21}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {AC5A2964-C7C8-419B-A8DD-63424233E6AA}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Reference in New Issue
Block a user