From ed33e5d76d5d7ad1a6f40711790aef78486a9f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=BCller?= Date: Sat, 26 Mar 2022 11:23:40 +0100 Subject: [PATCH] add /api/player/play endpoint fix not being able to play track with a playlist reference ``&list=`` attached --- TomatenMusic/Controllers/PlayerController.cs | 31 +++++++++++++++++ .../Models/EventArgs/TrackPlayArgs.cs | 22 +++++++++++++ TomatenMusic/Models/TrackPlayRequest.cs | 10 ++++++ TomatenMusic/Services/EventBus.cs | 7 +++- .../Services/TomatenMusicDataService.cs | 4 ++- TomatenMusic/Services/TomatenMusicService.cs | 33 ++++++++++++++++++- TomatenMusicCore/Commands/PlayCommandGroup.cs | 4 +-- .../Music/Entitites/YoutubePlaylist.cs | 6 ++-- TomatenMusicCore/Music/GuildPlayer.cs | 2 +- TomatenMusicCore/Music/MusicActionResponse.cs | 4 +-- TomatenMusicCore/Music/PlayerQueue.cs | 2 +- TomatenMusicCore/Services/TrackProvider.cs | 26 ++++++++++++++- TomatenMusicCore/TomatenMusicCore.csproj | 14 ++++---- 13 files changed, 145 insertions(+), 20 deletions(-) create mode 100644 TomatenMusic/Models/EventArgs/TrackPlayArgs.cs create mode 100644 TomatenMusic/Models/TrackPlayRequest.cs diff --git a/TomatenMusic/Controllers/PlayerController.cs b/TomatenMusic/Controllers/PlayerController.cs index 95ac508..49d900b 100644 --- a/TomatenMusic/Controllers/PlayerController.cs +++ b/TomatenMusic/Controllers/PlayerController.cs @@ -1,6 +1,7 @@ using DSharpPlus.Entities; using Microsoft.AspNetCore.Mvc; using TomatenMusic; +using TomatenMusic.Music; using TomatenMusic_Api; using TomatenMusic_Api.Auth.Helpers; using TomatenMusic_Api.Models; @@ -112,4 +113,34 @@ public class PlayerController : ControllerBase return Ok(); } + + [HttpPost("play")] + public async Task PostPlay(TrackPlayRequest request) + { + try + { + await _tomatenMusicDataService.GetGuildAsync(request.GuildId); + } + catch (Exception ex) + { + return NotFound("That Guild was not found"); + } + + if (!await _tomatenMusicDataService.IsConnectedAsync(request.GuildId) == true) + return BadRequest("The Bot is not connected."); + + MusicActionResponse response; + + try + { + response = await _tomatenMusicDataService.TrackProvider.SearchAsync(request.TrackUri); + }catch (Exception ex) + { + return NotFound(ex.Message + "\n" + ex.StackTrace); + } + + _eventBus.OnPlayRequestEvent(new TrackPlayArgs(response, request.GuildId, TimeSpan.FromSeconds(request.StartTimeSeconds), request.Now)); + + return Ok(); + } } diff --git a/TomatenMusic/Models/EventArgs/TrackPlayArgs.cs b/TomatenMusic/Models/EventArgs/TrackPlayArgs.cs new file mode 100644 index 0000000..cd4b43e --- /dev/null +++ b/TomatenMusic/Models/EventArgs/TrackPlayArgs.cs @@ -0,0 +1,22 @@ +using Emzi0767.Utilities; +using Lavalink4NET.Player; +using TomatenMusic.Music; + +namespace TomatenMusic_Api.Models.EventArgs +{ + public class TrackPlayArgs : AsyncEventArgs + { + public MusicActionResponse Response { get; set; } + public ulong GuildId { get; set; } + public TimeSpan StartTime { get; set; } + public bool Now { get; set; } + + public TrackPlayArgs(MusicActionResponse response, ulong guildId, TimeSpan startTime, bool now) + { + Response = response; + GuildId = guildId; + StartTime = startTime; + Now = now; + } + } +} diff --git a/TomatenMusic/Models/TrackPlayRequest.cs b/TomatenMusic/Models/TrackPlayRequest.cs new file mode 100644 index 0000000..598f3f2 --- /dev/null +++ b/TomatenMusic/Models/TrackPlayRequest.cs @@ -0,0 +1,10 @@ +namespace TomatenMusic_Api.Models +{ + public class TrackPlayRequest + { + public ulong GuildId { get; set; } + public string TrackUri { get; set; } + public bool Now { get; set; } + public int StartTimeSeconds { get; set; } + } +} diff --git a/TomatenMusic/Services/EventBus.cs b/TomatenMusic/Services/EventBus.cs index fd0fbac..c58224d 100644 --- a/TomatenMusic/Services/EventBus.cs +++ b/TomatenMusic/Services/EventBus.cs @@ -12,7 +12,7 @@ public class InProcessEventBus public event AsyncEventHandler? OnDisconnectRequest; - + public event AsyncEventHandler OnPlayRequest; public void OnConnectRequestEvent(ChannelConnectArgs e) { _ = OnConnectRequest?.Invoke(this, e); @@ -22,5 +22,10 @@ public class InProcessEventBus { _ = OnDisconnectRequest?.Invoke(this, e); } + + public void OnPlayRequestEvent(TrackPlayArgs e) + { + _ = OnPlayRequest?.Invoke(this, e); + } } diff --git a/TomatenMusic/Services/TomatenMusicDataService.cs b/TomatenMusic/Services/TomatenMusicDataService.cs index 0389856..53fc3db 100644 --- a/TomatenMusic/Services/TomatenMusicDataService.cs +++ b/TomatenMusic/Services/TomatenMusicDataService.cs @@ -11,12 +11,14 @@ namespace TomatenMusic_Api public class TomatenMusicDataService : IHostedService { private ILogger _logger; - public IServiceProvider _serviceProvider { get; set; } = TomatenMusicBot.ServiceProvider; + private IServiceProvider _serviceProvider { get; set; } = TomatenMusicBot.ServiceProvider; public IAudioService _audioService { get; set; } + public TrackProvider TrackProvider { get; set; } public TomatenMusicDataService(ILogger logger) { _logger = logger; _audioService = _serviceProvider.GetRequiredService(); + TrackProvider = _serviceProvider.GetRequiredService(); } public async Task GetConnectionInfoAsync(ulong guild_id) diff --git a/TomatenMusic/Services/TomatenMusicService.cs b/TomatenMusic/Services/TomatenMusicService.cs index 2204e76..a8febdd 100644 --- a/TomatenMusic/Services/TomatenMusicService.cs +++ b/TomatenMusic/Services/TomatenMusicService.cs @@ -26,9 +26,40 @@ namespace TomatenMusic_Api { _inProcessEventBus.OnConnectRequest += _inProcessEventBus_OnConnectRequest; _inProcessEventBus.OnDisconnectRequest += _inProcessEventBus_OnDisconnectRequest; + _inProcessEventBus.OnPlayRequest += _inProcessEventBus_OnPlayRequest; } - private async Task _inProcessEventBus_OnDisconnectRequest(InProcessEventBus sender, ChannelDisconnectArgs e) + private async Task _inProcessEventBus_OnPlayRequest(InProcessEventBus sender, TrackPlayArgs e) + { + GuildPlayer player = _audioService.GetPlayer(e.GuildId); + + if (e.Response.Tracks != null && e.Response.Tracks.Any()) + { + if (e.Now) + await player.PlayTracksNowAsync(e.Response.Tracks); + else + await player.PlayTracksAsync(e.Response.Tracks); + + return; + } + + if (e.Response.IsPlaylist) + { + if (e.Now) + await player.PlayPlaylistNowAsync(e.Response.Playlist); + else + await player.PlayPlaylistAsync(e.Response.Playlist); + }else + { + if (e.Now) + await player.PlayNowAsync(e.Response.Track, e.StartTime); + else + await player.PlayAsync(e.Response.Track, e.StartTime); + } + + } + + private async Task _inProcessEventBus_OnDisconnectRequest(InProcessEventBus sender, ChannelDisconnectArgs e) { GuildPlayer player = _audioService.GetPlayer(e.GuildId); player.DisconnectAsync(); diff --git a/TomatenMusicCore/Commands/PlayCommandGroup.cs b/TomatenMusicCore/Commands/PlayCommandGroup.cs index 07b79ab..cb79222 100644 --- a/TomatenMusicCore/Commands/PlayCommandGroup.cs +++ b/TomatenMusicCore/Commands/PlayCommandGroup.cs @@ -79,7 +79,7 @@ namespace TomatenMusic.Commands try { - if (response.isPlaylist) + if (response.IsPlaylist) { ILavalinkPlaylist playlist = response.Playlist; await player.PlayPlaylistNowAsync(playlist); @@ -232,7 +232,7 @@ namespace TomatenMusic.Commands try { - if (response.isPlaylist) + if (response.IsPlaylist) { ILavalinkPlaylist playlist = response.Playlist; await player.PlayPlaylistAsync(playlist); diff --git a/TomatenMusicCore/Music/Entitites/YoutubePlaylist.cs b/TomatenMusicCore/Music/Entitites/YoutubePlaylist.cs index 5699ab2..3ae2615 100644 --- a/TomatenMusicCore/Music/Entitites/YoutubePlaylist.cs +++ b/TomatenMusicCore/Music/Entitites/YoutubePlaylist.cs @@ -28,12 +28,12 @@ namespace TomatenMusic.Music.Entitites public Playlist YoutubeItem { get; set; } public Uri AuthorThumbnail { get; set; } - public YoutubePlaylist(string name, IEnumerable tracks, Uri uri) + public YoutubePlaylist(string name, IEnumerable tracks, string id) { - Identifier = uri.ToString().Replace("https://www.youtube.com/playlist?list=", "").Replace("https://youtube.com/playlist?list=", ""); + Identifier = id; Name = name; Tracks = tracks; - Url = uri; + Url = new Uri($"https://youtube.com/playlist?list={id}"); TrackCount = tracks.Count(); } diff --git a/TomatenMusicCore/Music/GuildPlayer.cs b/TomatenMusicCore/Music/GuildPlayer.cs index a572f5b..7bef9de 100644 --- a/TomatenMusicCore/Music/GuildPlayer.cs +++ b/TomatenMusicCore/Music/GuildPlayer.cs @@ -73,7 +73,7 @@ namespace TomatenMusic.Music QueuePrompt.UpdateFor(GuildId); } - public async Task PlayTracksAsync(List tracks) + public async Task PlayTracksAsync(IEnumerable tracks) { EnsureNotDestroyed(); EnsureConnected(); diff --git a/TomatenMusicCore/Music/MusicActionResponse.cs b/TomatenMusicCore/Music/MusicActionResponse.cs index e4f9eef..87f8dbf 100644 --- a/TomatenMusicCore/Music/MusicActionResponse.cs +++ b/TomatenMusicCore/Music/MusicActionResponse.cs @@ -11,12 +11,12 @@ namespace TomatenMusic.Music public ILavalinkPlaylist Playlist { get; } public LavalinkTrack Track { get; } public IEnumerable Tracks { get; } - public bool isPlaylist { get; } + public bool IsPlaylist { get; } public MusicActionResponse(LavalinkTrack track = null, ILavalinkPlaylist playlist = null, IEnumerable tracks = null) { Playlist = playlist; Track = track; - isPlaylist = playlist != null; + IsPlaylist = playlist != null; Tracks = tracks; } } diff --git a/TomatenMusicCore/Music/PlayerQueue.cs b/TomatenMusicCore/Music/PlayerQueue.cs index 7bc84f5..bee1e55 100644 --- a/TomatenMusicCore/Music/PlayerQueue.cs +++ b/TomatenMusicCore/Music/PlayerQueue.cs @@ -59,7 +59,7 @@ namespace TomatenMusic.Music } - public Task QueueTracksAsync(List tracks) + public Task QueueTracksAsync(IEnumerable tracks) { return Task.Run(() => { diff --git a/TomatenMusicCore/Services/TrackProvider.cs b/TomatenMusicCore/Services/TrackProvider.cs index 1c47d38..6158b88 100644 --- a/TomatenMusicCore/Services/TrackProvider.cs +++ b/TomatenMusicCore/Services/TrackProvider.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Web; using TomatenMusic.Music.Entitites; using TomatenMusic.Services; @@ -57,7 +58,8 @@ namespace TomatenMusic.Music if (loadResult.LoadType == TrackLoadType.PlaylistLoaded && !isSearch) return new MusicActionResponse( - playlist: await _youtubeService.PopulatePlaylistAsync(new YoutubePlaylist(loadResult.PlaylistInfo.Name, await FullTrackContext.PopulateTracksAsync(loadResult.Tracks), uri))); + playlist: await _youtubeService.PopulatePlaylistAsync( + new YoutubePlaylist(loadResult.PlaylistInfo.Name, await FullTrackContext.PopulateTracksAsync(loadResult.Tracks), ParseListId(query)))); else return new MusicActionResponse(await FullTrackContext.PopulateAsync(loadResult.Tracks.First())); @@ -79,5 +81,27 @@ namespace TomatenMusic.Music } + public string ParseListId(string url) + { + var uri = new Uri(url, UriKind.Absolute); + + // you can check host here => uri.Host <= "www.youtube.com" + + var query = HttpUtility.ParseQueryString(uri.Query); + + var videoId = string.Empty; + + if (query.AllKeys.Contains("list")) + { + videoId = query["list"]; + } + else + { + videoId = uri.Segments.Last(); + } + + return videoId; + } + } } diff --git a/TomatenMusicCore/TomatenMusicCore.csproj b/TomatenMusicCore/TomatenMusicCore.csproj index 2a8bc65..620cb46 100644 --- a/TomatenMusicCore/TomatenMusicCore.csproj +++ b/TomatenMusicCore/TomatenMusicCore.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -11,17 +11,17 @@ - - - - + + + + - + - +