Player work

This commit is contained in:
Steven Hildreth 2019-01-01 20:03:17 -06:00
parent bc5da0f95f
commit bc21d19cb9
10 changed files with 81 additions and 13 deletions

View file

@ -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
};

View file

@ -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" />

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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" />

View file

@ -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);
}
}
}

View file

@ -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;

View file

@ -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));
}
}
}

View file

@ -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" />