136 lines
4.3 KiB
C#
Raw Permalink Normal View History

2022-03-29 22:12:22 +02:00
using Lavalink4NET;
using Lavalink4NET.Rest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using TomatenMusic.Music.Entitites;
using TomatenMusic.Services;
using TomatenMusicCore.Music;
using TomatenMusicCore.Music.Entities;
namespace TomatenMusic.Music
{
public class TrackProvider
{
public ISpotifyService _spotifyService { get; set; }
public IAudioService _audioService { get; set; }
public YoutubeService _youtubeService { get; set; }
public TrackProvider(ISpotifyService spotify, IAudioService audioService, YoutubeService youtubeService)
{
_audioService = audioService;
_spotifyService = spotify;
_youtubeService = youtubeService;
}
public async Task<MusicActionResponse> SearchAsync(string query, bool withSearchResults = false)
{
Uri uri;
TrackLoadResponsePayload loadResult;
bool isSearch = true;
if (query.StartsWith("https://open.spotify.com"))
{
return await _spotifyService.ConvertURL(query);
}
if (Uri.TryCreate(query, UriKind.Absolute, out uri))
{
loadResult = await _audioService.LoadTracksAsync(uri.ToString());
isSearch = false;
}
else
loadResult = await _audioService.LoadTracksAsync(query, SearchMode.YouTube);
if (uri != null && uri.AbsolutePath.Contains("."))
return await SearchAsync(uri);
if (loadResult.LoadType == TrackLoadType.LoadFailed) throw new ArgumentException("Track loading failed");
if (loadResult.LoadType == TrackLoadType.NoMatches) throw new FileNotFoundException("Query resulted in no Matches");
if (ParseTimestamp(query) != null)
loadResult.Tracks[0] = loadResult.Tracks[0].WithPosition((TimeSpan)ParseTimestamp(query));
if (withSearchResults && loadResult.LoadType == TrackLoadType.SearchResult)
{
return new MusicActionResponse(tracks: await FullTrackContext.PopulateTracksAsync(new TrackList(loadResult.Tracks)));
}
if (loadResult.LoadType == TrackLoadType.PlaylistLoaded && !isSearch)
return new MusicActionResponse(
playlist: await _youtubeService.PopulatePlaylistAsync(
new YoutubePlaylist(loadResult.PlaylistInfo.Name, await FullTrackContext.PopulateTracksAsync(new TrackList(loadResult.Tracks)), ParseListId(query))));
else
return new MusicActionResponse(await FullTrackContext.PopulateAsync(new TomatenMusicTrack(loadResult.Tracks.First())));
}
public async Task<MusicActionResponse> SearchAsync(Uri fileUri)
{
var loadResult = new TomatenMusicTrack(await _audioService.GetTrackAsync(fileUri.ToString()));
loadResult.Context = new FullTrackContext
{
IsFile = true
};
if (loadResult == null)
throw new FileNotFoundException("The file was not found");
return new MusicActionResponse(loadResult);
}
public string ParseListId(string url)
{
var uri = new Uri(url, UriKind.Absolute);
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;
}
public TimeSpan? ParseTimestamp(string url)
{
Uri uri;
try
{
uri = new Uri(url, UriKind.Absolute);
}catch (UriFormatException)
{
return null;
}
var query = HttpUtility.ParseQueryString(uri.Query);
int seconds;
if (query.AllKeys.Contains("t"))
{
seconds = int.Parse(query["t"]);
}
else
return null;
return TimeSpan.FromSeconds(seconds);
}
}
}