mirror of
https://github.com/sphildreth/roadie
synced 2024-11-10 06:44:12 +00:00
Player work
This commit is contained in:
parent
bc5da0f95f
commit
bc21d19cb9
10 changed files with 81 additions and 13 deletions
|
@ -77,7 +77,8 @@ namespace Roadie.Library.Models
|
|||
public int? FileSize { get; set; }
|
||||
|
||||
|
||||
public static TrackList FromDataTrack(Data.Track track,
|
||||
public static TrackList FromDataTrack(string trackPlayUrl,
|
||||
Data.Track track,
|
||||
int releaseMediaNumber,
|
||||
Data.Release release,
|
||||
Data.Artist artist,
|
||||
|
@ -111,7 +112,7 @@ namespace Roadie.Library.Models
|
|||
PlayedCount = track.PlayedCount,
|
||||
Rating = track.Rating,
|
||||
Title = track.Title,
|
||||
TrackPlayUrl = $"{ baseUrl }/play/track/{ track.RoadieId }.mp3",
|
||||
TrackPlayUrl = trackPlayUrl,
|
||||
Thumbnail = trackThumbnail
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Caching.Redis" Version="2.2.0" />
|
||||
<PackageReference Include="MimeMapping" Version="1.0.1.12" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.4" />
|
||||
<PackageReference Include="RestSharp" Version="106.5.4" />
|
||||
<PackageReference Include="RestSharp" Version="106.6.2" />
|
||||
<PackageReference Include="SixLabors.Core" Version="1.0.0-beta0006" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0005" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0005" />
|
||||
|
|
|
@ -61,6 +61,8 @@ namespace Roadie.Api.Services
|
|||
var rowCount = result.Count();
|
||||
BookmarkList[] rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
|
||||
|
||||
var user = this.GetUser(roadieUser.UserId);
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
switch (row.Type)
|
||||
|
@ -101,7 +103,8 @@ namespace Roadie.Api.Services
|
|||
Text = track.Title,
|
||||
Value = track.RoadieId.ToString()
|
||||
};
|
||||
row.Track = TrackList.FromDataTrack(track,
|
||||
row.Track = TrackList.FromDataTrack(this.MakeTrackPlayUrl(user, track.Id, track.RoadieId),
|
||||
track,
|
||||
track.ReleaseMedia.MediaNumber,
|
||||
track.ReleaseMedia.Release,
|
||||
track.ReleaseMedia.Release.Artist,
|
||||
|
@ -111,6 +114,7 @@ namespace Roadie.Api.Services
|
|||
this.MakeReleaseThumbnailImage(track.ReleaseMedia.Release.RoadieId),
|
||||
this.MakeArtistThumbnailImage(track.ReleaseMedia.Release.Artist.RoadieId),
|
||||
this.MakeArtistThumbnailImage(track.TrackArtist == null ? null : (Guid?)track.TrackArtist.RoadieId));
|
||||
row.Track.TrackPlayUrl = this.MakeTrackPlayUrl(user, track.Id, track.RoadieId);
|
||||
row.Thumbnail = this.MakeTrackThumbnailImage(track.RoadieId);
|
||||
row.SortName = track.Title;
|
||||
break;
|
||||
|
|
|
@ -147,6 +147,15 @@ namespace Roadie.Api.Services
|
|||
sw.Stop();
|
||||
if (result?.Data != null && roadieUser != null)
|
||||
{
|
||||
if (result?.Data?.Tracks != null)
|
||||
{
|
||||
var user = this.GetUser(roadieUser.UserId);
|
||||
foreach (var track in result.Data.Tracks)
|
||||
{
|
||||
track.Track.TrackPlayUrl = this.MakeTrackPlayUrl(user, track.Track.DatabaseId, track.Track.Id);
|
||||
}
|
||||
}
|
||||
|
||||
result.Data.UserCanEdit = result.Data.Maintainer.Id == roadieUser.UserId || roadieUser.IsAdmin;
|
||||
var userBookmarkResult = await this.BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Playlist);
|
||||
if (userBookmarkResult.IsSuccess)
|
||||
|
@ -294,7 +303,8 @@ namespace Roadie.Api.Services
|
|||
select new PlaylistTrack
|
||||
{
|
||||
ListNumber = plt.pltr.ListNumber,
|
||||
Track = TrackList.FromDataTrack(plt.t,
|
||||
Track = TrackList.FromDataTrack(null,
|
||||
plt.t,
|
||||
rm.MediaNumber,
|
||||
r,
|
||||
releaseArtist,
|
||||
|
|
|
@ -101,6 +101,15 @@ namespace Roadie.Api.Services
|
|||
}
|
||||
if (result.Data.Medias != null)
|
||||
{
|
||||
var user = this.GetUser(roadieUser.UserId);
|
||||
foreach(var media in result.Data.Medias)
|
||||
{
|
||||
foreach(var track in media.Tracks)
|
||||
{
|
||||
track.TrackPlayUrl = this.MakeTrackPlayUrl(user, track.DatabaseId, track.Id);
|
||||
}
|
||||
}
|
||||
|
||||
var releaseTrackIds = result.Data.Medias.SelectMany(x => x.Tracks).Select(x => x.Id);
|
||||
var releaseUserTracks = (from ut in this.DbContext.UserTracks
|
||||
join t in this.DbContext.Tracks on ut.TrackId equals t.Id
|
||||
|
@ -421,6 +430,7 @@ namespace Roadie.Api.Services
|
|||
where ut.UserId == roadieUser.Id
|
||||
where (from x in releaseTrackIds select x).Contains(ut.TrackId)
|
||||
select ut).ToArray();
|
||||
var user = this.GetUser(roadieUser.UserId);
|
||||
foreach (var release in rows)
|
||||
{
|
||||
var releaseMedias = new List<ReleaseMediaList>();
|
||||
|
@ -432,7 +442,7 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
var t = track.t.Adapt<TrackList>();
|
||||
t.CssClass = string.IsNullOrEmpty(track.t.Hash) ? "Missing" : "Ok";
|
||||
t.TrackPlayUrl = $"{ this.HttpContext.BaseUrl }/play/track/{ track.t.RoadieId}.mp3";
|
||||
t.TrackPlayUrl = this.MakeTrackPlayUrl(user, track.t.Id, track.t.RoadieId);
|
||||
var userRating = artistUserTracks.FirstOrDefault(x => x.TrackId == track.t.Id);
|
||||
if (userRating != null)
|
||||
{
|
||||
|
@ -888,7 +898,6 @@ namespace Roadie.Api.Services
|
|||
t.MediaNumber = rm.MediaNumber;
|
||||
t.CssClass = string.IsNullOrEmpty(track.Hash) ? "Missing" : "Ok";
|
||||
t.TrackArtist = track.TrackArtist != null ? ArtistList.FromDataArtist(track.TrackArtist, this.MakeArtistThumbnailImage(track.TrackArtist.RoadieId)) : null;
|
||||
t.TrackPlayUrl = $"{ this.HttpContext.BaseUrl }/play/track/{ t.Id}.mp3";
|
||||
rmTracks.Add(t);
|
||||
}
|
||||
rm.Tracks = rmTracks;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Hashids.net" Version="1.2.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.3.0" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.9" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using HashidsNet;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Roadie.Library;
|
||||
using Roadie.Library.Caching;
|
||||
|
@ -17,6 +18,8 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
public abstract class ServiceBase
|
||||
{
|
||||
public static string TrackTokenSalt = "B0246908-FBD6-4E12-A96C-AF5B086115B3";
|
||||
|
||||
protected readonly ICacheManager _cacheManager = null;
|
||||
protected readonly IRoadieSettings _configuration = null;
|
||||
protected readonly data.IRoadieDbContext _dbContext = null;
|
||||
|
@ -699,5 +702,31 @@ namespace Roadie.Api.Services
|
|||
this.CacheManager.ClearRegion(release.CacheRegion);
|
||||
}
|
||||
}
|
||||
|
||||
public static string TrackPlayToken(ApplicationUser user, Guid trackId)
|
||||
{
|
||||
var hashids = new Hashids(ServiceBase.TrackTokenSalt);
|
||||
var trackIdPart = BitConverter.ToInt32(trackId.ToByteArray(), 6);
|
||||
if(trackIdPart < 0)
|
||||
{
|
||||
trackIdPart = trackIdPart * -1;
|
||||
}
|
||||
var token = hashids.Encode(user.Id, SafeParser.ToNumber<int>(user.CreatedDate.Value.ToString("DDHHmmss")), trackIdPart);
|
||||
return token;
|
||||
}
|
||||
|
||||
protected string MakeTrackPlayUrl(ApplicationUser user, int trackId, Guid trackRoadieId)
|
||||
{
|
||||
return $"{ this.HttpContext.BaseUrl }/play/track/{user.Id}/{ ServiceBase.TrackPlayToken(user, trackRoadieId)}/{ trackRoadieId }.mp3";
|
||||
}
|
||||
|
||||
public static bool ConfirmTrackPlayToken(ApplicationUser user, Guid trackRoadieId, string token)
|
||||
{
|
||||
if(string.IsNullOrEmpty(token))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return ServiceBase.TrackPlayToken(user, trackRoadieId).Equals(token);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -415,6 +415,7 @@ namespace Roadie.Api.Services
|
|||
resultQuery = resultQuery.Where(x => x.ti.Tags != null && x.ti.Tags.Contains(tagValue));
|
||||
}
|
||||
}
|
||||
var user = this.GetUser(roadieUser.UserId);
|
||||
var result = resultQuery.Select(x =>
|
||||
new TrackList
|
||||
{
|
||||
|
@ -439,7 +440,7 @@ namespace Roadie.Api.Services
|
|||
PlayedCount = x.ti.PlayedCount,
|
||||
Rating = x.ti.Rating,
|
||||
Title = x.ti.Title,
|
||||
TrackPlayUrl = $"{ this.HttpContext.BaseUrl }/play/track/{ x.ti.RoadieId }.mp3",
|
||||
TrackPlayUrl = this.MakeTrackPlayUrl(user, x.ti.Id, x.ti.RoadieId),
|
||||
Thumbnail = this.MakeTrackThumbnailImage(x.ti.RoadieId)
|
||||
});
|
||||
string sortBy = null;
|
||||
|
|
|
@ -65,10 +65,23 @@ namespace Roadie.Api.Controllers
|
|||
return File(System.Text.Encoding.Default.GetBytes(m3u), "audio/mpeg-url");
|
||||
}
|
||||
|
||||
[HttpGet("track/{id}.{mp3?}")]
|
||||
public async Task<IActionResult> StreamTrack(Guid id)
|
||||
/// <summary>
|
||||
/// This was done to use a URL based token as many clients don't support adding Auth Bearer tokens to audio requests.
|
||||
/// </summary>
|
||||
[HttpGet("track/{userId}/{trackPlayToken}/{id}.{mp3?}")]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> StreamTrack(int userId, string trackPlayToken, Guid id)
|
||||
{
|
||||
return await base.StreamTrack(id, this.TrackService, this.PlayActivityService);
|
||||
var user = this.UserManager.Users.FirstOrDefault(x => x.Id == userId);
|
||||
if(user == null)
|
||||
{
|
||||
return StatusCode((int)HttpStatusCode.Forbidden);
|
||||
}
|
||||
if(!ServiceBase.ConfirmTrackPlayToken(user, id, trackPlayToken))
|
||||
{
|
||||
return StatusCode((int)HttpStatusCode.Forbidden);
|
||||
}
|
||||
return await base.StreamTrack(id, this.TrackService, this.PlayActivityService, this.UserModelForUser(user));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.OData" Version="7.1.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="5.0.0" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.RollingFileAlternate" Version="2.0.9" />
|
||||
|
|
Loading…
Reference in a new issue