Skip to content

Commit

Permalink
Bunch of fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
F0903 committed Mar 23, 2024
1 parent a681c07 commit e3c722b
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 45 deletions.
1 change: 1 addition & 0 deletions Melodica/Services/Caching/MediaFileCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace Melodica.Services.Caching;

//TODO: Also support storing cache for media info without actual data.
public sealed class MediaFileCache : IMediaCache
{
public MediaFileCache(string dirName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ static async Task<PlayableMediaStream> DownloadPlaylistAsync(MediaInfo info)
PlayableMediaStream? current = null;
foreach (var track in playlist.Tracks)
{
//TODO: Convert to lazy getter?
var trackInfo = TrackToMediaInfo(track);
var media = await CreatePlayableMediaAsync(trackInfo, info);
if (first is null)
Expand Down
35 changes: 27 additions & 8 deletions Melodica/Services/Downloaders/Spotify/AsyncSpotifyDownloader.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using Melodica.Config;
using Melodica.Services.Caching;
using Melodica.Services.Downloaders.Exceptions;
using Melodica.Services.Downloaders.YouTube;
using Melodica.Services.Media;
using Melodica.Utility;
using SpotifyAPI.Web;
Expand Down Expand Up @@ -146,15 +146,32 @@ static async Task<MediaInfo> GetPlaylistInfoAsync(ReadOnlyMemory<char> url)
static async ValueTask<PlayableMediaStream> DownloadFromProviderAsync(MediaInfo info)
{
if (await cache.TryGetAsync(info.Id) is var cachedMedia && cachedMedia is not null)
{
return cachedMedia;
}

var extInfo = await downloader.GetInfoAsync($"{info.Artist} {info.Title}".AsMemory());
var extMedia = await downloader.DownloadAsync(extInfo);
static async Task<Stream> DataGetter(MediaInfo info)
{
try
{
if (downloader is AsyncYoutubeDownloader yt)
{
var extInfo = await downloader.GetInfoAsync($"{info.Artist} {info.Title}".AsMemory());
return await yt.GetMediaHttpStreamAsync(extInfo);
}
throw new NotSupportedException("Only YouTube fallback downloader is supported for this operation with Spotify.");
}
catch (Exception ex)
{
throw new MediaUnavailableException("Video was unavailable.", ex);
}
}

extMedia.SetInfo(info with { Id = extInfo.Id, Url = extInfo.Url });
return extMedia;
var media = new PlayableMediaStream(
(Func<MediaInfo, Task<Stream>>)DataGetter,
(Func<Task<MediaInfo>>)(() => info.WrapTask()),
null,
cache
);
return media;
}

static async ValueTask<PlayableMediaStream> DownloadSpotifyAlbumAsync(FullAlbum album)
Expand Down Expand Up @@ -194,13 +211,15 @@ static async ValueTask<PlayableMediaStream> DownloadSpotifyPlaylistAsync(FullPla
{
var info = FullTrackToMediaInfo(track);
var media = await DownloadFromProviderAsync(info);

if (first is null)
{
first = media;
current = first;
continue;
}
current!.Next = media;
current = current.Next;
}

return first!;
Expand Down
17 changes: 10 additions & 7 deletions Melodica/Services/Downloaders/YouTube/AsyncYoutubeDownloader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using AngleSharp.Text;
using Melodica.Services.Caching;
using Melodica.Services.Downloaders.Exceptions;
Expand Down Expand Up @@ -145,7 +143,14 @@ static async Task<PlayableMediaStream> DownloadLivestream(MediaInfo info)
return media;
}

static async Task<PlayableMediaStream> GetPlayableMediaFromInfoAsync(MediaInfo info)
internal async Task<Stream> GetMediaHttpStreamAsync(MediaInfo info)
{
var manifest = await yt.Videos.Streams.GetManifestAsync(info.Id);
var streamInfo = manifest.GetAudioOnlyStreams().GetWithHighestBitrate() ?? throw new NullReferenceException("Could not get stream from YouTube.");
return await yt.Videos.Streams.GetAsync(streamInfo);
}

async Task<PlayableMediaStream> GetPlayableMediaFromInfoAsync(MediaInfo info)
{
if (await cache.TryGetAsync(info.Id) is var cachedMedia && cachedMedia is not null)
{
Expand All @@ -155,9 +160,7 @@ static async Task<PlayableMediaStream> GetPlayableMediaFromInfoAsync(MediaInfo i
Stream stream;
try
{
var manifest = await yt.Videos.Streams.GetManifestAsync(info.Id);
var streamInfo = manifest.GetAudioOnlyStreams().GetWithHighestBitrate() ?? throw new NullReferenceException("Could not get stream from YouTube.");
stream = await yt.Videos.Streams.GetAsync(streamInfo);
stream = await GetMediaHttpStreamAsync(info);
}
catch (Exception ex) when (IsUnavailable(ex))
{
Expand Down
17 changes: 6 additions & 11 deletions Melodica/Services/Playback/Jukebox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,12 @@ await mediaProcessor.ProcessMediaAsync(
token
);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
Log.Error(ex, $"Got exception when trying to write audio:\n{ex.Message}");
}
finally
{
Log.Debug("Finished sending data... Flushing...");
await output.WriteSilentFramesAsync();
await output.FlushAsync(token);
durationTimer.Reset();
}
catch (OperationCanceledException) { }

Log.Debug("Finished sending data... Flushing...");
await output.WriteSilentFramesAsync();
await output.FlushAsync(token);
durationTimer.Reset();
}

async Task DisconnectAsync()
Expand Down
33 changes: 14 additions & 19 deletions Melodica/Services/Playback/JukeboxCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public async Task Queue()
[SlashCommand("next", "Sets the next song to play.")]
public async Task Next(string query)
{
if(!Jukebox.Playing)
if (!Jukebox.Playing)
{
await RespondAsync("No song is playing! Did you mean to use /play ?", ephemeral: true);
return;
Expand Down Expand Up @@ -210,30 +210,25 @@ public async Task Play(string query, ManualProviderOptions? provider = null)
return;
}

if (Jukebox.Playing)

if (Jukebox.Playing) await DeferAsync(true);
else await DeferAsync();

try
{
try
JukeboxInterface player = new(Context.Interaction);
var result = await Jukebox.PlayAsync(request, voice, player);
if (result == Jukebox.PlayResult.Queued)
{
var info = await request.GetInfoAsync();
var embed = EmbedUtils.CreateMediaEmbed(info, null);
await RespondAsync("The following media will be queued:", embed: embed, ephemeral: true);
}
catch (Exception ex)
{
await RespondAsync($"Error occured getting media info: {ex}");
return;
await ModifyOriginalResponseAsync(x =>
{
x.Content = "The following media was queued:";
x.Embed = embed;
});
}
}
else
{
await DeferAsync(); // Command can take a long time.
}

try
{
JukeboxInterface player = new(Context.Interaction);
await Jukebox.PlayAsync(request, voice, player);
}
catch (EmptyChannelException)
{
await ModifyOriginalResponseAsync(x => x.Content = "All users have left the channel. Disconnecting...");
Expand Down

0 comments on commit e3c722b

Please sign in to comment.