Skip to content

Commit

Permalink
Fix for playing the same cached media in a repeating playlist not wor…
Browse files Browse the repository at this point in the history
…king.
  • Loading branch information
F0903 committed Mar 31, 2024
1 parent 5eddaf2 commit c10263d
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Melodica/Core/CommandHandlers/SocketCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private async Task OnSlashCommandExecutedAsync(SlashCommandInfo info, IInteracti
Log.ForContext("CmdModule", info.Module)
.ForContext("CmdName", info.Name)
.ForContext("Guild", context.Guild)
.Error("Command threw an exception {Error}", $"{info.Name} => {result.ErrorReason}");
.Error("Command threw an exception {Error}", $"{info.Name} ({result.Error?.ToString()}) => {result.ErrorReason}");

var errorEmbed = await BuildErrorEmbedAsync(result.ErrorReason);
if (context.Interaction.HasResponded)
Expand Down
53 changes: 28 additions & 25 deletions Melodica/Services/Media/PlayableMediaStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,62 +22,65 @@ public class PlayableMediaStream(AsyncParameterizedLazyGetter<Stream, MediaInfo>

private Stream? cachingStream;

private bool cachingFinished;

public override bool CanRead { get; } = true;
public override bool CanSeek => GetData().CanSeek || cachingFinished;
public override bool CanSeek { get; } = false;
public override bool CanWrite { get; } = false;
public override long Length => GetData().Length;
public override long Position { get => GetData().Position; set => GetData().Position = value; }

public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
private void SwitchToCacheStream()
{
if (cachingFinished) // This path will only be used when looping an uncached song.
{
return await cachingStream!.ReadAsync(buffer, cancellationToken);
}
GetData().Close();

if (cachingStream is null) throw new NullReferenceException("Caching stream was null when trying to switch.");
cachedData = cachingStream.WrapTask();

cachingProvider = null;
cachingStream = null;
}

public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
{
var data = await GetDataAsync();
var info = await GetInfoAsync();
var read = await data.ReadAsync(buffer, cancellationToken);

if (cachingProvider is not null)
if (read == 0) // No more input; we are done
{
if (read == 0)
if (cachingProvider is not null)
{
await cachingProvider.TryEditCacheInfo(info.Id, x =>
{
x.IsComplete = true;
x.IsWriting = false;
return x;
});
cachingFinished = true;
return 0;
SwitchToCacheStream();
}
GetData().Seek(0, SeekOrigin.Begin);
return 0;
}

if (cachingProvider is not null)
{
cachingStream ??= await cachingProvider.InitStreamableCache(await GetInfoAsync());
await cachingStream.WriteAsync(buffer[..read], cancellationToken);
if (cachingStream is not null)
await cachingStream.WriteAsync(buffer[..read], cancellationToken);
}

return read;
}

public override int Read(byte[] buffer, int offset, int count) => throw new NotImplementedException("Use async read.");

public override void Flush() => GetData().Flush();

public override async Task FlushAsync(CancellationToken cancellationToken) => await (await GetDataAsync()).FlushAsync(cancellationToken);

public override long Seek(long offset, SeekOrigin origin)
{
if (cachingFinished)
{
return cachingStream!.Seek(offset, origin);
}

return GetData().Seek(offset, origin);
}

public override int Read(byte[] buffer, int offset, int count) => throw new NotImplementedException("Use async read.");
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();

public override void SetLength(long value) => throw new NotSupportedException();

public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();

public override void Close()
Expand Down
1 change: 0 additions & 1 deletion Melodica/Services/Playback/Jukebox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ async Task PlayNextAsync(IAudioChannel channel, OpusEncodeStream output)
do
{
await SendDataAsync(media, output, stopToken);
if (Loop && media.CanSeek) media.Seek(0, SeekOrigin.Begin);
} while (Loop);
}
catch (OperationCanceledException)
Expand Down
1 change: 0 additions & 1 deletion Melodica/Services/Playback/MediaQueue.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Melodica.Services.Media;
using Melodica.Services.Playback.Requests;
using Melodica.Utility;

namespace Melodica.Services.Playback;
Expand Down
5 changes: 1 addition & 4 deletions Melodica/Utility/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using Discord;
using Discord.WebSocket;
using Melodica.Dependencies;

namespace Melodica.Utility;

Expand Down Expand Up @@ -46,7 +43,7 @@ public static (string artist, string newTitle) SeperateArtistName(this ReadOnlyS
var seperatorIndex = songTitle.IndexOf(" - ");
int spaceIndx;
var containsSeperator = seperatorIndex != -1;
var endIndx = containsSeperator ? seperatorIndex - 1 : (spaceIndx = songTitle.IndexOf(' ')) != -1 ? spaceIndx : songTitle.Length;
var endIndx = containsSeperator ? seperatorIndex : (spaceIndx = songTitle.IndexOf(' ')) != -1 ? spaceIndx : songTitle.Length;

var useBackup = endIndx == songTitle.Length;
var artist = useBackup ? backupArtistName : songTitle[0..endIndx].ToString();
Expand Down

0 comments on commit c10263d

Please sign in to comment.