Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DISCORD_APP_ID=your_app_id_here
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore

*.env

# User-specific files
*.rsuser
*.suo
Expand Down
40 changes: 40 additions & 0 deletions DiscordPresence.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using DiscordRPC;
using DiscordRPC.Logging;
using System;

class DiscordPresence
{
private static DiscordRpcClient client;

public static void Init(string clientId)
{
client = new DiscordRpcClient(clientId);
client.Logger = new ConsoleLogger() { Level = LogLevel.Warning };
client.Initialize();
}

public static void SetPresence(string image, string texte, string sousTexte)
{
if (client == null)
{
Console.WriteLine("Erreur : Discord RPC non initialisé. Appelle Init(clientId) avant.");
return;
}

client.SetPresence(new RichPresence()
{
Details = texte,
State = sousTexte,
Assets = new Assets()
{
LargeImageKey = image,
LargeImageText = texte
}
});
}

public static void Close()
{
client.Dispose();
}
}
6 changes: 6 additions & 0 deletions Folder.DotSettings.user
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<wpf:ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xml:space="preserve">
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer&gt;
&lt;Assembly Path="/home/kali/RiderProjects/Meio/discord_social_sdk/bin/release/discord_partner_sdk.dll" /&gt;
&lt;/AssemblyExplorer&gt;</s:String></wpf:ResourceDictionary>
50 changes: 50 additions & 0 deletions Meio.Api/Api.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using PrettyLogging.Console;

namespace Meio.Api;

public class Api
{
private static ILoggerFactory? LoggerFactory { get; set; }

public static ILogger<Api>? Logger { get; private set; }

[ModuleInitializer]
public static void Init()
{
// Create and configure PrettyLogger
LoggerFactory = Microsoft.Extensions.Logging.LoggerFactory.Create(builder =>
{
builder.ClearProviders();
builder.AddPrettyConsole(opt =>
{
opt.ShowLogLevel = true;
opt.ShowEventId = false;
opt.ShowManagedThreadId = false;
opt.SingleLine = true;
opt.IncludeScopes = true;
opt.ShowTimestamp = true;
opt.LogLevelCase = LogLevelCase.Upper;
opt.CategoryMode = LoggerCategoryMode.Short;
opt.ColorBehavior = LoggerColorBehavior.Enabled;
opt.UseUtcTimestamp = false;
});

#if DEBUG
builder.SetMinimumLevel(LogLevel.Trace);
#else
builder.SetMinimumLevel(LogLevel.Information);
#endif
});

Logger = LoggerFactory.CreateLogger<Api>();
Logger.LogInformation("Meio API started.");
}

public static void Main()
{
Init();
}
}
18 changes: 18 additions & 0 deletions Meio.Api/Meio.Api.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DotNetEnv" Version="3.1.1"/>
<PackageReference Include="LibVLCSharp" Version="3.9.4"/>
<PackageReference Include="PrettyLogging.Console" Version="1.0.3"/>
<PackageReference Include="TagLibSharp" Version="2.3.0"/>
<PackageReference Include="VideoLAN.LibVLC.Mac" Version="3.1.3.1"/>
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.21"/>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
using System.IO;
using Microsoft.Extensions.Logging;
using TagLib;
using File = TagLib.File;

namespace Meio.app.Services;
namespace Meio.Api.Services;

public class MetadataInfo
{
public string? Title { get; set; }
public string? Title { get; init; }

public string[]? Artists { get; set; }
public string[]? Artists { get; init; }

public string? Album { get; set; }
public string? Album { get; init; }

public uint Year { get; set; }
public uint Year { get; init; }

public string[]? Genres { get; set; }
public string[]? Genres { get; init; }

public byte[]? AlbumArt { get; set; }
public byte[]? AlbumArt { get; init; }
}

public static class AudioMetadataService
Expand All @@ -32,13 +34,13 @@ public static class AudioMetadataService
var file = File.Create(filePath);
var tag = file.Tag;

App.Logger?.LogDebug("Asked for the metadata of {filePath}.", filePath);
App.Logger?.LogTrace("Title: {tagTitle}", tag.Title);
App.Logger?.LogTrace("Artists: {tagArtists}", string.Join(", ", tag.AlbumArtists));
App.Logger?.LogTrace("Album: {tagAlbum}", tag.Album);
App.Logger?.LogTrace("Year: {tagYear}", tag.Year);
App.Logger?.LogTrace("Genre: {tagGenres}", string.Join(", ", tag.Genres));
App.Logger?.LogTrace(tag.Pictures.Length > 0 ? "Got an album art." : "No album art was found.");
Api.Logger?.LogDebug("Current metadata of {filePath}.", filePath);
Api.Logger?.LogTrace("Title: {tagTitle}", tag.Title);
Api.Logger?.LogTrace("Artists: {tagArtists}", string.Join(", ", tag.AlbumArtists));
Api.Logger?.LogTrace("Album: {tagAlbum}", tag.Album);
Api.Logger?.LogTrace("Year: {tagYear}", tag.Year);
Api.Logger?.LogTrace("Genre: {tagGenres}", string.Join(", ", tag.Genres));
Api.Logger?.LogTrace(tag.Pictures.Length > 0 ? "Got an album art." : "No album art was found.");

return new MetadataInfo
{
Expand All @@ -52,12 +54,17 @@ public static class AudioMetadataService
}
catch (CorruptFileException corruptFileException)
{
App.Logger?.LogError(corruptFileException, "Failed to load metadata. File is corrupted.");
Api.Logger?.LogError(corruptFileException, "Failed to load metadata. File is corrupted.");
return null;
}
catch (UnsupportedFormatException unsupportedFormatException)
{
App.Logger?.LogError(unsupportedFormatException, "Failed to load metadata. File format is unsupported.");
Api.Logger?.LogError(unsupportedFormatException, "Failed to load metadata. File format is unsupported.");
return null;
}
catch (FileNotFoundException fileNotFoundException)
{
Api.Logger?.LogError(fileNotFoundException, "Failed to load metadata. File not found.");
return null;
}
}
Expand Down
188 changes: 188 additions & 0 deletions Meio.Api/Services/AudioPlayerService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
using System;
using LibVLCSharp.Shared;
using Microsoft.Extensions.Logging;

// ReSharper disable UnusedMember.Global

namespace Meio.Api.Services;

public class AudioPlayerService : IDisposable
{
// ReSharper disable once InconsistentNaming
private readonly LibVLC _libVLC;
private readonly MediaPlayer _mediaPlayer;

public AudioPlayerService()
{
try
{
_libVLC = new LibVLC();
_mediaPlayer = new MediaPlayer(_libVLC);
Api.Logger!.LogDebug("Initialized AudioPlayerService.");
}
catch (VLCException ex)
{
Api.Logger!.LogCritical("An error occured trying to initialize AudioPlayerService. {Exception}", ex.Message);
Api.Logger!.LogInformation(
"!! READ THIS !!\n If you are on a linux host, please make sure you have installed the libvlc library, you will not be able to read any audio otherwise !!!");
Environment.Exit(-1);
}
}

/// <summary>
/// To be called when done using.
/// </summary>
public void Dispose()
{
_mediaPlayer.Stop(); // Make sure it stops first to avoid potential unwanted behaviour.
_mediaPlayer.Dispose();
Api.Logger!.LogTrace("Disposed media player.");

_libVLC.Dispose();
Api.Logger!.LogTrace("Disposed libVLC.");

GC.SuppressFinalize(this); // Dispose AudioPlayerService.
Api.Logger!.LogDebug("Disposed.");

Environment.Exit(0); // Exit after this.
}

/// <summary>
/// Starts playing the given audio file.
/// </summary>
/// <param name="audioFilePath">Audio file path.</param>
public Media? Play(string audioFilePath)
{
try
{
if (_mediaPlayer.IsPlaying)
{
Api.Logger!.LogError("An audio file is already being played. Please stop it first.");
return null;
}

var media = new Media(_libVLC, audioFilePath);

_mediaPlayer.Play(media);
Api.Logger!.LogInformation("Playing media file {AudioFilePath} .", audioFilePath);

_mediaPlayer.EndReached += (_, _) =>
{
Api.Logger!.LogDebug("Media playback ended.");
// _mediaPlayer.Stop()
};

return media;
}
catch (Exception e)
{
Api.Logger?.LogError("An error occured trying to play the audio file. {e}", e.Message);

return null;
}
}

/// <summary>
/// Starts playing the given audio file.
/// </summary>
/// <param name="audioUri">Audio file Uri.</param>
public Media? Play(Uri audioUri)
{
try
{
if (_mediaPlayer.IsPlaying)
{
Api.Logger!.LogError("An audio file is already being played. Please stop it first.");
return null;
}

var media = new Media(_libVLC, audioUri.AbsolutePath, FromType.FromLocation);

_mediaPlayer.Play(media);
Api.Logger!.LogInformation("Playing media file from url {AudioFilePath}.", audioUri.AbsolutePath);

return media;
}
catch (Exception e)
{
Api.Logger?.LogError("An error occured trying to play the audio file from url. {e}", e.Message);
return null;
}
}

/// <summary>
/// Stops the current reading audio file.
/// </summary>
public void Stop()
{
if (!_mediaPlayer.IsPlaying)
{
Api.Logger!.LogError("Cannot stop the media player. No media is playing.");
}

_mediaPlayer.Stop();
_mediaPlayer.Media?.Dispose();
Api.Logger!.LogDebug("Stopped media player.");
}

/// <summary>
/// Pauses the current reading audio file.
/// </summary>
public void Pause()
{
_mediaPlayer.Pause();
Api.Logger!.LogDebug("Paused media player.");
}

/// <summary>
/// Changes the volume of the current reading audio file.
/// </summary>
/// <param name="newVolume">New volume of the media player.</param>
public void ChangeVolume(int newVolume)
{
try
{
_mediaPlayer.Volume = newVolume;
Api.Logger!.LogTrace("Changed audio volume to {NewAudioVolume}.", newVolume);
}
catch (Exception e)
{
Api.Logger!.LogError("An error occured trying to change audio volume. {Exception}", e.Message);
}
}

/// <summary>
/// Changes the playback speed of the current playing media.
/// </summary>
/// <param name="speed">New playback speed.</param>
public void ChangePlaybackSpeed(float speed)
{
if (!_mediaPlayer.IsPlaying)
{
Api.Logger!.LogError("Cannot change audio rate, no media is playing.");
}
else
{
_mediaPlayer.SetRate(speed);
Api.Logger!.LogTrace("Changed audio rate to {Speed}.", speed);
}
}

/// <summary>
/// Mute the current reading audio file.
/// </summary>
public void Mute()
{
_mediaPlayer.Mute = true;
Api.Logger!.LogDebug("Muted media.");
}

/// <summary>
/// Unmute the current reading audio file.
/// </summary>
public void Unmute()
{
_mediaPlayer.Mute = false;
Api.Logger!.LogDebug("Unuted media.");
}
}
Loading
Loading