Skip to content

Commit

Permalink
Merge pull request #148 from KMen1/dev
Browse files Browse the repository at this point in the history
Add Lyrics.Java support
  • Loading branch information
angelobreuer authored Mar 9, 2024
2 parents 1955e6b + a3fd91b commit 583767c
Show file tree
Hide file tree
Showing 36 changed files with 1,159 additions and 3 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
[![Lavalink4NET Support Server Banner](https://discordapp.com/api/guilds/894533462428635146/embed.png?style=banner3)](https://discord.gg/cD4qTmnqRg)

### Features

- ⚖️ **Node Clustering / Load Balancing**<br>Distribute load across nodes for efficient and reliable audio playback (for large scale bots).

- ✳️ **Extensible**<br>Customize and enhance features using plugins to match your bot's needs.
Expand Down Expand Up @@ -42,7 +43,7 @@
- 📊 **Statistics tracking support**<br>Lavalink4NET supports tracking and evaluation of node statistics. In clustering, node statistics can be used to evaluate the best node for efficient resource usage.

-**Compatible with [DSharpPlus](https://github.com/DSharpPlus/DSharpPlus), [Discord.Net](https://github.com/discord-net/Discord.Net), [Remora](https://github.com/Remora/Remora.Discord), and [NetCord](https://github.com/KubaZ2/NetCord).**<br>Lavalink4NET has an adaptive client API, meaning it can support any discord client. Currently, DSharpPlus, Discord.Net, Remora and NetCord are supported out-of-the-box.

### Documentation

> [!IMPORTANT]
Expand Down Expand Up @@ -74,6 +75,8 @@ Lavalink4NET offers high flexibility and extensibility by providing an isolated

- [**Lavalink4NET.Integrations.TextToSpeech**](https://www.nuget.org/packages/Lavalink4NET.Integrations.TextToSpeech/)&nbsp;&nbsp;&nbsp;![NuGet](https://img.shields.io/nuget/vpre/Lavalink4NET.Integrations.TextToSpeech.svg?style=flat-square)<br>Enable text-to-speech functionality in Lavalink4NET. Convert written text into spoken words, allowing your application to generate and play audio from text inputs. Requires the installation of the corresponding plugin on the Lavalink node.

- [**Lavalink4NET.Integrations.LyricsJava**](https://www.nuget.org/packages/Lavalink4NET.Integrations.LyricsJava/)&nbsp;&nbsp;&nbsp;![NuGet](https://img.shields.io/nuget/vpre/Lavalink4NET.Integrations.LyricsJava.svg?style=flat-square)<br>Fetch timed lyrics from youtube or non-timed lyrics from genius. Automatically fetches lyrics for the current track. Requires the installation of the corresponding plugin on the Lavalink node.

#### _Services_

- [**Lavalink4NET.Lyrics**](https://www.nuget.org/packages/Lavalink4NET.Lyrics/)&nbsp;&nbsp;&nbsp;![NuGet](https://img.shields.io/nuget/vpre/Lavalink4NET.Lyrics.svg?style=flat-square)<br>Fetch and display song lyrics from lyrics.ovh with this lyrics service integrated with Lavalink4NET. Enhance the music experience for your users.
Expand All @@ -84,7 +87,7 @@ Lavalink4NET offers high flexibility and extensibility by providing an isolated

#### _Core Components_

- [**Lavalink4NET**](https://www.nuget.org/packages/Lavalink4NET/)&nbsp;&nbsp;&nbsp;![NuGet](https://img.shields.io/nuget/vpre/Lavalink4NET.svg?style=flat-square)<br>This core library is used to implement client wrappers. It is not intended for end users. Please use Lavalink4NET.Discord.Net, Lavalink4NET.DSharpPlus, Lavalink4NET.Remora.Discord or Lavalink4NET.NetCord instead.
- [**Lavalink4NET**](https://www.nuget.org/packages/Lavalink4NET/)&nbsp;&nbsp;&nbsp;![NuGet](https://img.shields.io/nuget/vpre/Lavalink4NET.svg?style=flat-square)<br>This core library is used to implement client wrappers. It is not intended for end users. Please use Lavalink4NET.Discord.Net, Lavalink4NET.DSharpPlus, Lavalink4NET.Remora.Discord or Lavalink4NET.NetCord instead.

- [**Lavalink4NET.Abstractions**](https://www.nuget.org/packages/Lavalink4NET.Abstractions/)&nbsp;&nbsp;&nbsp;![NuGet](https://img.shields.io/nuget/vpre/Lavalink4NET.Abstractions.svg?style=flat-square)<br>General abstractions and common primitives for the Lavalink4NET client library.

Expand All @@ -93,6 +96,7 @@ Lavalink4NET offers high flexibility and extensibility by providing an isolated
- [**Lavalink4NET.Rest**](https://www.nuget.org/packages/Lavalink4NET.Rest/)&nbsp;&nbsp;&nbsp;![NuGet](https://img.shields.io/nuget/vpre/Lavalink4NET.Rest.svg?style=flat-square)<br>Easily interact with the Lavalink REST API using this REST API client primitives library. Build custom functionalities or integrate Lavalink4NET with other services.

### Prerequisites

- At least one lavalink node
- At least .NET 6

Expand Down Expand Up @@ -124,7 +128,7 @@ var playerOptions = new LavalinkPlayerOptions
};

await audioService.Players
.JoinAsync(<guild id>, <voice channel id>, playerOptions, stoppingToken)
.JoinAsync(<guild id>, <voice channel id>, playerOptions, stoppingToken)
.ConfigureAwait(false);
```

Expand Down
78 changes: 78 additions & 0 deletions docs/docs/integrations/lyricsjava.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Lyrics.Java

The Lyrics.Java plugin for Lavalink allows you to fetch lyrics from YouTube or genius. The plugin will automatically fetch lyrics for the current track.

Lavalink4NET provides an integration for the Lyrics.Java plugin with the [`Lavalink4NET.Integrations.LyricsJava`](https://www.nuget.org/packages/Lavalink4NET.Integrations.LyricsJava) package.

## Installation

For using Lyrics.Java, you need to install the [`Lavalink4NET.Integrations.LyricsJava`](https://www.nuget.org/packages/Lavalink4NET.Integrations.LyricsJava) package.

:::caution
You need to have the [LyricsJava](https://github.com/DuncteBot/java-timed-lyrics) plugin installed on your Lavalink server.
:::

## Usage

First, you need to integrate the LyricsJava plugin with Lavalink4NET. You can do this by calling `UseLyricsJava` on either the host or the audio service:

```csharp
var app = builder.Build();

app.UseLyricsJava();

app.Run();
```

That's it! The LyricsJava plugin is now integrated with Lavalink4NET.

### Getting lyrics for the current track

For getting the lyrics of the current track, you can use the `GetCurrentTrackLyricsAsync` method. This method will return the lyrics of the current track. The method requires the session id and the guild id both of which you can get from player properties.

```csharp
var player = await audioService.Players
.GetPlayerAsync(guildId)
.ConfigureAwait(false);

var lyrics = await audioService.Tracks
.GetCurrentTrackLyricsAsync(player)
.ConfigureAwait(false);
```

### Getting lyrics from youtube

For getting the lyrics of a youtube video, you can use the `GetYoutubeLyricsAsync` method. This method will return the lyrics of the youtube video. The method requires a youtube video id, which can be acquired by using the `SearchAsync` method if using a different provider (e.g. Spotify).

```csharp
var results = await AudioService.Tracks
.SearchLyricsAsync("Queen - Bohemian Rhapsody")
.ConfigureAwait(false);

var videoId = results.First().VideoId;

var lyrics = await AudioService.Tracks
.GetYouTubeLyricsAsync(videoId) // Youtube Video Id (e.g. dQw4w9WgXcQ)
.ConfigureAwait(false);
```

### Getting lyrics from genius

For getting the lyrics of a song from genius, you can use the `GetGeniusLyricsAsync` method. This method will return the lyrics of the song. The method requires the song name and the artist name.

```csharp
var lyrics = await AudioService.Tracks
.GetGeniusLyricsAsync("Queen - Bohemian Rhapsody")
.ConfigureAwait(false);
```

## Player listener

Similar to the inactivity tracking service, the LyricsJava integration also implements a player listener for receiving event notifications. The player listener can be used to receive notifications for when the lyrics of the current track has been loaded.

```csharp
public interface ILavaLyricsPlayerListener : ILavalinkPlayerListener
{
ValueTask NotifyLyricsLoadedAsync(Lyrics lyrics, CancellationToken cancellationToken = default);
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
namespace Lavalink4NET.Rest.Tests;

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.TestHost;
using Microsoft.AspNetCore.WebSockets;

[ExcludeFromCodeCoverage]
internal sealed class HttpClientFactory : IHttpClientFactory, IAsyncDisposable
{
private int _state; // 0 = build, 1 = run, 2 = disposed
private readonly WebApplication _application;

public HttpClientFactory()
{
var builder = WebApplication.CreateBuilder();
builder.WebHost.UseTestServer();
builder.Services.AddWebSockets(x => { });

_application = builder.Build();
}

public void Start()
{
var state = Interlocked.CompareExchange(ref _state, 1, 0);
ObjectDisposedException.ThrowIf(state is 2, this);

if (state is 1)
{
throw new InvalidOperationException("The application is already running.");
}

Debug.Assert(state is 0);
_ = _application.RunAsync();
}

public WebApplication Application
{
get
{
ObjectDisposedException.ThrowIf(_state is 2, this);

if (_state is not 0)
{
throw new InvalidOperationException("The application can not be accessed after starting it.");
}

return _application;
}
}

public HttpClient CreateClient(string name)
{
ObjectDisposedException.ThrowIf(_state is 2, this);

if (_state is not 1)
{
throw new InvalidOperationException("The application must be started before creating a client.");
}

return _application.GetTestServer().CreateClient();
}

public ValueTask DisposeAsync()
{
var state = Interlocked.CompareExchange(ref _state, 2, 1);

if (state is not 1)
{
return default;
}

return _application.DisposeAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="7.0.7" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Lavalink4NET.Integrations.LyricsJava\Lavalink4NET.Integrations.LyricsJava.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit 583767c

Please sign in to comment.