示例#1
0
        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
            });
        }
示例#2
0
 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()
     });
 }
示例#3
0
 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");
     }
 }
示例#4
0
        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);
        }
示例#5
0
        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(),
            });
        }
示例#6
0
        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);
        }
示例#7
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);
        }
示例#8
0
 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);
 }
示例#9
0
        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));
            }
        }
示例#10
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));
        }
示例#11
0
        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());
        }