public static DeviceStatusDTO ToDTO(this DeviceStatus ds, DeviceRuntime dr) { //(PlaylistItemRuntime major, PlaylistItemRuntime minor) findItem(PlaylistPosition pos) //{ // PlaylistItemRuntime maj = dr.Playlist.Items[pos.Major - 1]; // PlaylistItemRuntime min = null; // if (maj.Type == PlaylistRuntimeItemType.MultipleItems && pos.Minor > 0) // { // min = maj.SubItems.ToArray()[pos.Minor - 1]; // } // return (maj, min); //} //(PlaylistItemRuntime majorPli, PlaylistItemRuntime minorPli) = dr.CurrentPosition.IsUnset() ? (null, null) : findItem(dr.CurrentPosition); var ct = ds.CurrentTime.TotalMilliseconds; var tt = ds.TotalTime.TotalMilliseconds; var rt = tt - ct; return(new DeviceStatusDTO { Key = ds.Key, PlaylistPosition = dr.CurrentPosition, //Title = majorPli?.Type == PlaylistRuntimeItemType.SingleItem ? majorPli.Title : minorPli?.Title, //CoverArtUrl = majorPli?.CoverArtUrl, CurrentTime = ct, TotalTime = tt, RemainingTime = rt, FormattedCurrentTime = ct.FormatDuration(), FormattedTotalTime = tt.FormatDuration(), FormattedRemainingTime = rt.FormatDuration(), //AudioProperties = majorPli?.Type == PlaylistRuntimeItemType.SingleItem ? majorPli?.AudioProperties : minorPli?.AudioProperties, State = ds.State, Volume = ds.Volume, CommandSequence = dr.CommandSequenceNumber }); }
public static PlaylistRuntime ToRuntime(this Playlist list, MusicDb db, DeviceRuntime dr) { return(new PlaylistRuntime { Id = list.Id, Name = list.Name, Type = list.Type, Items = list.Items .Select(x => x.ToRuntime(db, dr)) .Where(x => x != null) .OrderBy(x => x.Sequence).ToList() }); }
private async Task AddDeviceToRuntime(Device device) { if (this.keepAlive != null) { using (var scope = new ScopedDbContext <MusicDb>(serviceProvider)) { DeviceRuntime dr = null; lock (this.devices) { //if (!this.devices.ContainsKey(device.KeyName)) if (GetDeviceRuntime(device.KeyName) == null) { dr = new DeviceRuntime { Key = device.KeyName, Type = device.Type, DisplayName = device.DisplayName, MaxSampleRate = device.MaxSampleRate, PlayerUrl = device.PlayerUrl, CommandSequenceNumber = 0, Status = new DeviceStatus { Key = device.KeyName, State = PlayerStates.Idle } }; dr.Playlist = device.Playlist.ToRuntime(scope.Db, dr); this.devices.Add(dr.Key, dr); log.Information($"{device.KeyName}, {device.DisplayName}, {device.Type}, url = {device.PlayerUrl } added to run time"); } else { log.Warning($"Device {device.DisplayName} already present in run time"); } } //LogDevices(); if (dr != null) { await PlayerReset(dr.Key); } } this.keepAlive.SetPlayerUrls(this.GetPlayerUrls()); } else { log.Warning($"not ready to add a device - keepAlive not yet started"); } }
private PlaylistItemRuntime GetPlaylistItemAtSequence(DeviceRuntime dr, PlaylistPosition position) { //var pli = dr.Playlist.Items.SingleOrDefault(x => x.Sequence == index); var pli = dr.Playlist.Items.SingleOrDefault(x => x.Sequence == position.Major); if (pli != null && pli.Type == PlaylistRuntimeItemType.MultipleItems) { if (position.Minor == 0) { log.Error($"Cannot request a position with Minor == 0 when the playlist item is of type PlaylistRuntimeItemType.MultipleItems"); return(null); } else { pli = pli.SubItems.SingleOrDefault(x => x.Sequence == position.Minor); } } return(pli); }
public static PlaylistItemRuntime ToRuntime(this Track track, DeviceRuntime dr, int majorSequence) { var mf = track.GetBestMusicFile(dr);// getBestMusicFile(track); return(new PlaylistItemRuntime { Id = 0,// pli.Id, Type = PlaylistRuntimeItemType.SingleItem, Position = new PlaylistPosition(majorSequence, track.Number), //Title = track.Title, Titles = new string[] { track.Work.Artist.Name, track.Performance?.Composition.Name ?? track.Work.Name, track.Title }, Sequence = track.Number, NotPlayableOnCurrentDevice = mf == null, ItemId = track.Id, MusicFileId = mf?.Id ?? 0, AudioProperties = mf?.GetAudioProperties(), SampleRate = mf?.SampleRate ?? 0, TotalTime = mf?.Duration ?? 0.0, FormattedTotalTime = mf?.Duration.FormatDuration(), }); }
private async Task <int> ExecuteCommand(DeviceRuntime dr, PlayerCommand playerCommand /*, Action<DeviceRuntime> afterExecute = null*/) { PlayerClient GetPlayerClient(DeviceRuntime deviceRuntime) { return(new PlayerClient(deviceRuntime.PlayerUrl, lf.CreateLogger <PlayerClient>())); } try { if (dr != null) { dr.CommandSequenceNumber = (dr.CommandSequenceNumber + 1) % 1024; dr.MostRecentCommand = playerCommand; playerCommand.CommandSequenceNumber = dr.CommandSequenceNumber; if (dr.Type != AudioDeviceType.Browser) { using (var deviceClient = GetPlayerClient(dr)) { await deviceClient.Execute(playerCommand); //afterExecute?.Invoke(dr); } } else { await this.playHub.Clients.Group("WebAudio").SendCommand(playerCommand); //var hm = this.playHub.Clients.Client(dr.ConnectionId); //await hm.SendCommand(playerCommand); } log.Debug($"{dr.DisplayName}: command {playerCommand.Command}, command sequence {playerCommand.CommandSequenceNumber}"); return(playerCommand.CommandSequenceNumber); } } catch (Exception xe) { log.Error(xe); } return(0); }
public static PlaylistItemRuntime ToRuntime(this PlaylistItem pli, MusicDb db, DeviceRuntime dr) { PlaylistItemRuntime plir = null; switch (pli.Type) { default: case PlaylistItemType.MusicFile: var playable = dr.MaxSampleRate == 0 || pli.MusicFile.SampleRate == 0 || pli.MusicFile.SampleRate <= dr.MaxSampleRate; plir = new PlaylistItemRuntime { Id = pli.Id, Type = PlaylistRuntimeItemType.SingleItem, Position = new PlaylistPosition(pli.Sequence, 0), //Title = pli.Title, Titles = new string[] { pli.MusicFile.Track.Performance?.Composition.Artist.Name ?? pli.MusicFile.Track.Work.Artist.Name, pli.MusicFile.Track.Performance?.Composition.Name ?? pli.MusicFile.Track.Work.Name, pli.MusicFile.Track.Title }, Sequence = pli.Sequence, NotPlayableOnCurrentDevice = !playable, ItemId = pli.ItemId, MusicFileId = pli.MusicFile.Id, AudioProperties = pli.MusicFile.GetAudioProperties(), SampleRate = pli.MusicFile.SampleRate ?? 0, TotalTime = pli.MusicFile.Duration ?? 0.0, FormattedTotalTime = pli.MusicFile.Duration?.FormatDuration() ?? "00:00", CoverArtUrl = $"lib/get/work/coverart/{pli.MusicFile.Track.Work.Id}" }; break; case PlaylistItemType.Track: var mf = pli.Track.GetBestMusicFile(dr); plir = new PlaylistItemRuntime { Id = pli.Id, Type = PlaylistRuntimeItemType.SingleItem, Position = new PlaylistPosition(pli.Sequence, 0), //Title = pli.Title, Titles = new string[] { pli.Track.Performance?.Composition.Artist.Name ?? pli.Track.Work.Artist.Name, pli.Track.Performance?.Composition.Name ?? pli.Track.Work.Name, pli.Track.Title }, Sequence = pli.Sequence, NotPlayableOnCurrentDevice = mf == null, ItemId = pli.ItemId, MusicFileId = mf?.Id ?? 0, AudioProperties = mf?.GetAudioProperties(), SampleRate = mf?.SampleRate ?? 0, TotalTime = mf?.Duration ?? 0.0, FormattedTotalTime = mf?.Duration?.FormatDuration() ?? "00:00", CoverArtUrl = $"lib/get/work/coverart/{pli.Track.Work.Id}" }; break; case PlaylistItemType.Work: var work = db.Works.Find(pli.Work.Id); var tracks = work.Tracks; plir = new PlaylistItemRuntime { Id = pli.Id, Type = PlaylistRuntimeItemType.MultipleItems, Position = new PlaylistPosition(pli.Sequence, 0), //Title = pli.Title, Titles = new string[] { pli.Title }, Sequence = pli.Sequence, ItemId = pli.ItemId, CoverArtUrl = $"lib/get/work/coverart/{pli.Work.Id}", // ***NB*** the ToArray() at the end of the next line is very important, as // otherwise the OrderBy...Select will be deferred and may execute *after* the db has been disposed!! SubItems = tracks.OrderBy(t => t.Number).Select(t => t.ToRuntime(dr, pli.Sequence)).ToArray() }; plir.TotalTime = plir.SubItems.Sum(x => x.TotalTime); plir.FormattedTotalTime = plir.TotalTime.FormatDuration(); break; case PlaylistItemType.Performance: var performance = db.Performances.Find(pli.Performance.Id); var movements = performance.Movements; plir = new PlaylistItemRuntime { Id = pli.Id, Type = PlaylistRuntimeItemType.MultipleItems, Position = new PlaylistPosition(pli.Sequence, 0), //Title = pli.Title, Titles = new string[] { pli.Title }, Sequence = pli.Sequence, ItemId = pli.ItemId, CoverArtUrl = $"lib/get/work/coverart/{movements.First().Work.Id}", //SubItems = movements.OrderBy(t => t.Number).Select(t => t.ToRuntime(pli.Sequence)).ToArray() SubItems = movements.OrderBy(t => t.Number).AsMovementsToRuntime(dr, pli.Sequence) //**NB* this version of ToRuntime, rewrites the sequence (as movements cannot usse the track number }; plir.TotalTime = plir.SubItems.Sum(x => x.TotalTime); plir.FormattedTotalTime = plir.TotalTime.FormatDuration(); //return plir2; break; } Debug.Assert(plir != null); return(plir); }
private (PlaylistItemRuntime item, PlaylistPosition position) GetNextPlaylistItem(DeviceRuntime dr, bool reverse) { try { if (!dr.CurrentPosition.IsUnset()) { var majorPli = dr.Playlist.Items.Single(x => x.Sequence == dr.CurrentPosition.Major); if (majorPli.Type == PlaylistRuntimeItemType.MultipleItems) { (var item, var position) = GetNextMinorItem(dr, reverse); if (item != null) { // we have a minor item return(item, position); } } } return(GetNextMajorItem(dr, reverse)); } catch (Exception xe) { log.Error(xe); } return(null, null); }
private (PlaylistItemRuntime item, PlaylistPosition position) GetNextMajorItem(DeviceRuntime dr, bool reverse) { var sequence = dr.CurrentPosition.Major + (reverse ? -1 : 1); var majorPli = dr.Playlist.Items.SingleOrDefault(x => x.Sequence == sequence); if (majorPli != null) { if (majorPli.Type == PlaylistRuntimeItemType.MultipleItems) { // next major item contains minor items var nextMinorPli = majorPli.SubItems.Single(x => x.Sequence == 1); return(nextMinorPli, new PlaylistPosition(sequence, 1)); } else { return(majorPli, new PlaylistPosition(sequence, 0)); } } else { return(null, new PlaylistPosition(sequence, 0)); } }
private (PlaylistItemRuntime item, PlaylistPosition position) GetNextMinorItem(DeviceRuntime dr, bool reverse) { var sequence = dr.CurrentPosition.Minor + (reverse ? -1 : 1); var majorPli = dr.Playlist.Items.Single(x => x.Sequence == dr.CurrentPosition.Major); var nextMinorPli = majorPli.SubItems.SingleOrDefault(x => x.Sequence == sequence); return(nextMinorPli, new PlaylistPosition(dr.CurrentPosition.Major, sequence)); }
public static PlaylistItemRuntime[] AsMovementsToRuntime(this IEnumerable <Track> trackList, DeviceRuntime dr, int majorSequence) { var result = new List <PlaylistItemRuntime>(); var index = 0; foreach (var track in trackList) { var dto = track.ToRuntime(dr, majorSequence); dto.Sequence = ++index; dto.Position = new PlaylistPosition(majorSequence, dto.Sequence); dto.Titles = new string[] { track.Performance.Composition.Artist.Name, track.Performance.Composition.Name, track.Performance.Performers, track.Title }; result.Add(dto); } return(result.ToArray()); }