Add Lyrics API Endpoint
This commit is contained in:
parent
faadbbce00
commit
5f5347aee3
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -281,3 +281,5 @@ apiclient/generated
|
|||
|
||||
# Omnisharp crash logs
|
||||
mono_crash.*.json
|
||||
|
||||
!LrcParser.dll
|
|
@ -1,14 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Api.Models.UserDtos;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
using Kfstorm.LrcParser;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
|
@ -381,5 +385,50 @@ namespace Jellyfin.Api.Controllers
|
|||
|
||||
return _userDataRepository.GetUserDataDto(item, user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an item's lyrics.
|
||||
/// </summary>
|
||||
/// <param name="userId">User id.</param>
|
||||
/// <param name="itemId">Item id.</param>
|
||||
/// <response code="200">Lyrics returned.</response>
|
||||
/// <response code="404">Something went wrong. No Lyrics will be returned.</response>
|
||||
/// <returns>An <see cref="OkResult"/> containing the intros to play.</returns>
|
||||
[HttpGet("Users/{userId}/Items/{itemId}/Lyrics")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<QueryResult<BaseItemDto>> GetLyrics([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
|
||||
{
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
List<Lyrics> lyricsList = new List<Lyrics>
|
||||
{
|
||||
new Lyrics { Error = "User Not Found" }
|
||||
};
|
||||
return NotFound(new { Results = lyricsList.ToArray() });
|
||||
}
|
||||
|
||||
var item = itemId.Equals(default)
|
||||
? _libraryManager.GetUserRootFolder()
|
||||
: _libraryManager.GetItemById(itemId);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
List<Lyrics> lyricsList = new List<Lyrics>
|
||||
{
|
||||
new Lyrics { Error = "Requested Item Not Found" }
|
||||
};
|
||||
return NotFound(new { Results = lyricsList.ToArray() });
|
||||
}
|
||||
|
||||
List<Lyrics> result = ItemHelper.GetLyricData(item);
|
||||
if (string.IsNullOrEmpty(result.ElementAt(0).Error))
|
||||
{
|
||||
return Ok(new { Results = result });
|
||||
}
|
||||
|
||||
return NotFound(new { Results = result.ToArray() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
87
Jellyfin.Api/Helpers/ItemHelper.cs
Normal file
87
Jellyfin.Api/Helpers/ItemHelper.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Models.UserDtos;
|
||||
using Kfstorm.LrcParser;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Devices;
|
||||
using MediaBrowser.Controller.Dlna;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Jellyfin.Api.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Item helper.
|
||||
/// </summary>
|
||||
public static class ItemHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens lyrics file, converts to a List of Lyrics, and returns it.
|
||||
/// </summary>
|
||||
/// <param name="item">Requested Item.</param>
|
||||
/// <returns>Collection of Lyrics.</returns>
|
||||
internal static List<Lyrics> GetLyricData(BaseItem item)
|
||||
{
|
||||
List<Lyrics> lyricsList = new List<Lyrics>();
|
||||
|
||||
string lrcFilePath = @Path.ChangeExtension(item.Path, "lrc");
|
||||
|
||||
// LRC File not found, fallback to TXT file
|
||||
if (!System.IO.File.Exists(lrcFilePath))
|
||||
{
|
||||
string txtFilePath = @Path.ChangeExtension(item.Path, "txt");
|
||||
if (!System.IO.File.Exists(txtFilePath))
|
||||
{
|
||||
lyricsList.Add(new Lyrics { Error = "Lyric File Not Found" });
|
||||
return lyricsList;
|
||||
}
|
||||
|
||||
var lyricTextData = System.IO.File.ReadAllText(txtFilePath);
|
||||
string[] lyricTextLines = lyricTextData.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach (var lyricLine in lyricTextLines)
|
||||
{
|
||||
lyricsList.Add(new Lyrics { Text = lyricLine });
|
||||
}
|
||||
|
||||
return lyricsList;
|
||||
}
|
||||
|
||||
// Process LRC File
|
||||
ILrcFile lyricData;
|
||||
string lrcFileContent = System.IO.File.ReadAllText(lrcFilePath);
|
||||
try
|
||||
{
|
||||
lrcFileContent = lrcFileContent.Replace('<', '[');
|
||||
lrcFileContent = lrcFileContent.Replace('>', ']');
|
||||
lyricData = Kfstorm.LrcParser.LrcFile.FromText(lrcFileContent);
|
||||
}
|
||||
catch
|
||||
{
|
||||
lyricsList.Add(new Lyrics { Error = "No Lyrics Data" });
|
||||
return lyricsList;
|
||||
}
|
||||
|
||||
if (lyricData == null)
|
||||
{
|
||||
lyricsList.Add(new Lyrics { Error = "No Lyrics Data" });
|
||||
return lyricsList;
|
||||
}
|
||||
|
||||
foreach (var lyricLine in lyricData.Lyrics)
|
||||
{
|
||||
double ticks = lyricLine.Timestamp.TotalSeconds * 10000000;
|
||||
lyricsList.Add(new Lyrics { Start = Math.Ceiling(ticks), Text = lyricLine.Content });
|
||||
}
|
||||
|
||||
return lyricsList;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,4 +46,16 @@
|
|||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="LrcParser">
|
||||
<HintPath>Libraries\LrcParser.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Libraries\LrcParser.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
BIN
Jellyfin.Api/Libraries/LrcParser.dll
Normal file
BIN
Jellyfin.Api/Libraries/LrcParser.dll
Normal file
Binary file not shown.
23
Jellyfin.Api/Models/UserDtos/Lyrics.cs
Normal file
23
Jellyfin.Api/Models/UserDtos/Lyrics.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
namespace Jellyfin.Api.Models.UserDtos
|
||||
{
|
||||
/// <summary>
|
||||
/// Lyric dto.
|
||||
/// </summary>
|
||||
public class Lyrics
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the start.
|
||||
/// </summary>
|
||||
public double? Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the test.
|
||||
/// </summary>
|
||||
public string? Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the error.
|
||||
/// </summary>
|
||||
public string? Error { get; set; }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user