public bool Previous() { bool result = false; Lock(); if (iPresetIndex != -1) { int index = iPresetIndex - 1; while (index > -1) { MrItem preset = Preset((uint)index); if (preset.Id != 0) { SetPreset(preset); result = true; break; } else { index--; } } } Unlock(); return(result); }
public bool Next() { bool result = false; Lock(); if (iPresetIndex != -1) { int index = iPresetIndex + 1; while (index < kMaxPresets) { MrItem preset = Preset((uint)index); if (preset.Id != 0) { SetPreset(preset); result = true; break; } else { index++; } } } Unlock(); return(result); }
public ModelSourceMediaRendererUpnpAv(Source aSource) { DidlLite didl = new DidlLite(); audioItem itemAudio = new audioItem(); itemAudio.Title = "Unknown"; didl.Add(itemAudio); kUnknownPlaylistItem = new MrItem(0, null, didl); iSource = aSource; iInstanceId = 0; iTrackId = 0; try { iServiceConnectionManager = new ServiceConnectionManager(iSource.Device, iSource.House.EventServer); } catch (ServiceException) { throw new ModelSourceException(301, "Service failure"); } iActionGetProtocolInfo = iServiceConnectionManager.CreateAsyncActionGetProtocolInfo(); iActionGetProtocolInfo.EventResponse += EventResponseGetProtocolInfo; try { iServiceAVTransport = new ServiceAVTransport(iSource.Device, iSource.House.EventServer); } catch (ServiceException) { throw new ModelSourceException(301, "Service failure"); } iActionPlay = iServiceAVTransport.CreateAsyncActionPlay(); iActionPause = iServiceAVTransport.CreateAsyncActionPause(); iActionStop = iServiceAVTransport.CreateAsyncActionStop(); iActionSeek = iServiceAVTransport.CreateAsyncActionSeek(); iActionNext = iServiceAVTransport.CreateAsyncActionNext(); iActionPrevious = iServiceAVTransport.CreateAsyncActionPrevious(); iActionSetAVTransportURI = iServiceAVTransport.CreateAsyncActionSetAVTransportURI(); iActionGetPositionInfo = iServiceAVTransport.CreateAsyncActionGetPositionInfo(); iActionGetTransportSettings = iServiceAVTransport.CreateAsyncActionGetTransportSettings(); iActionSetPlayMode = iServiceAVTransport.CreateAsyncActionSetPlayMode(); iActionGetPositionInfo.EventResponse += EventResponseGetPositionInfo; iActionGetTransportSettings.EventResponse += EventResponseGetTransportSettings; iActionSetAVTransportURI.EventResponse += EventResponseSetAVTransportURI; iTimer = new Linn.Timer(); // Sets the timer interval to 1 second. iTimer.Interval = 1000; iTimer.Elapsed += TimerElapsed; iTimer.AutoReset = false; iMutex = new Mutex(false); iPlaylist = new List <MrItem>(); }
public MrItem Preset(uint aIndex) { Lock(); MrItem item = iIdArray.AtIndex(aIndex); Unlock(); return(item); }
public override void PlaylistDelete(IList <MrItem> aPlaylistItems) { try { Lock(); bool deletedPlaying = false; foreach (MrItem i in aPlaylistItems) { iPlaylist.Remove(i); if (iMaster) { if (i == iTrackPlaylistItem) { deletedPlaying = true; } } } if (deletedPlaying) { if (iTrackIndex < iPlaylist.Count) { if (iTransportState == ETransportState.eStopped) { MrItem track = iPlaylist[iTrackIndex]; iExpectedTrack = track; //SetCurrent(track); iActionSetAVTransportURI.SetAVTransportURIBegin(iInstanceId, iTrackPlaylistItem.Uri, iTrackPlaylistItem.DidlLite.Xml); } else { SeekTrack((uint)iTrackIndex); } } else { iExpectedTrack = null; SetCurrent(null); iTrackIndex = -1; iActionSetAVTransportURI.SetAVTransportURIBegin(iInstanceId, string.Empty, string.Empty); } } } finally { Unlock(); } if (EventPlaylistChanged != null) { EventPlaylistChanged(this, EventArgs.Empty); } }
private void SetCurrent(MrItem aItem) { lock (this) { iTrackPlaylistItem = aItem; iTrack = null; if (aItem != null) { iTrack = new Channel(aItem.Uri, aItem.DidlLite); } } }
public bool SetPreset(MrItem aPreset) { /*Lock(); * int index = iIdArray.Index(aPreset.Id); * Unlock();*/ if (aPreset.DidlLite[0].Res.Count > 0) { string uri = aPreset.DidlLite[0].Res[0].Uri; iActionSetId.SetIdBegin(aPreset.Id, uri); return(true); } return(false); }
public void AddToCache(uint aNewId, MrItem aMrItem) { Lock(); if (!iCacheMetadata.ContainsKey(aNewId)) { iCacheMetadata.Add(aNewId, aMrItem); RemoveStaleCacheItems(); iCacheUsage.Remove(aNewId); iCacheUsage.Add(aNewId); } Unlock(); }
public override MrItem PlaylistItem(uint aIndex) { MrItem result = kUnknownPlaylistItem; try { Lock(); if (aIndex < iPlaylist.Count) { result = iPlaylist[(int)aIndex]; } } finally { Unlock(); } return(result); }
private void UpdateTrack() { bool locked = false; try { Lock(); locked = true; uint trackId = iServicePlaylist.Id; iTrackIndex = iIdArray.Index(trackId); MrItem item = iIdArray.AtIndex((uint)iTrackIndex); if (iTrackPlaylistItem == null || item != iTrackPlaylistItem) { Trace.WriteLine(Trace.kMediaRenderer, "ModelSourceMediaRendererDs.UpdateTrack: iTrackIndex=" + iTrackIndex + ", iPlaylistIds.Count=" + iIdArray.IdArray.Count + ", trackId=" + trackId); iTrackPlaylistItem = item; Unlock(); locked = false; if (EventTrackChanged != null) { EventTrackChanged(this, EventArgs.Empty); } } else { Unlock(); locked = false; } } finally { if (locked) { Unlock(); } } }
public override void PlaylistMove(uint aInsertAfterId, IList <MrItem> aPlaylistItems) { try { Lock(); int index = 0; if (aInsertAfterId > 0) { for (int i = 0; i < iPlaylist.Count; ++i) { if (iPlaylist[i].Id == aInsertAfterId) { index = i + 1; break; } } } for (int i = 0; i < aPlaylistItems.Count; ++i) { MrItem item = aPlaylistItems[i]; iPlaylist.Insert(index + i, new MrItem(++iTrackId, item.Uri, item.DidlLite)); } foreach (MrItem i in aPlaylistItems) { iPlaylist.Remove(i); } } finally { Unlock(); } if (EventPlaylistChanged != null) { EventPlaylistChanged(this, EventArgs.Empty); } }
public void Insert(string aAfterTrackMetadataId, DidlLite aDidlLite) { Lock(); uint id = 0; uint count = Count; for (uint i = 0; i < count; ++i) { MrItem item = Track(i); if (item.DidlLite[0].Id == aAfterTrackMetadataId) { id = iIdArray.IdArray[(int)i]; break; } } Unlock(); Insert(id, aDidlLite); }
public void Delete(string aTrackMetadataId) { Lock(); uint id = 0; uint count = Count; for (uint i = 0; i < count; ++i) { MrItem item = Track(i); if (item.DidlLite[0].Id == aTrackMetadataId) { id = iIdArray.IdArray[(int)i]; break; } } Unlock(); Delete(id); }
private void EventStateLastChangeResponse(object sender, EventArgs e) { try { string lastChange = iServiceAVTransport.LastChange; if (lastChange != null) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(lastChange); XmlNamespaceManager xmlNsMan = new XmlNamespaceManager(xmlDoc.NameTable); xmlNsMan.AddNamespace("ns", "urn:schemas-upnp-org:metadata-1-0/AVT/"); XmlNodeList eventList = xmlDoc.DocumentElement.SelectNodes("/ns:Event/ns:InstanceID", xmlNsMan); foreach (XmlNode n in eventList) { XmlNodeList valList = n.SelectNodes("@val", xmlNsMan); foreach (XmlAttribute v in valList) { if (uint.Parse(v.Value) == iInstanceId) { XmlNode state = n.SelectSingleNode("ns:CurrentTrackURI", xmlNsMan); string trackUri = string.Empty; if (state != null) { XmlNode val = state.SelectSingleNode("@val", xmlNsMan); if (val != null) { trackUri = val.Value; } } if (iExpectedTrack != null && trackUri == iExpectedTrack.Uri) { iMaster = true; } else if (iTrackPlaylistItem == null || trackUri != iTrackPlaylistItem.Uri) { iMaster = false; } state = n.SelectSingleNode("ns:CurrentTrackMetaData", xmlNsMan); if (state != null) { XmlNode val = state.SelectSingleNode("@val", xmlNsMan); if (val != null) { MrItem trackPlaylistItem = null; try { if (!iMaster) { DidlLite didl = new DidlLite(val.Value); if (didl.Count == 0) { item item = new item(); item.Title = trackUri; didl.Add(item); } // hack for sonos devices artwork (which specifies a relative path) if (didl[0].AlbumArtUri.Count > 0 && didl[0].AlbumArtUri[0] != string.Empty) { string albumArt = didl[0].AlbumArtUri[0]; if (albumArt.StartsWith("/getaa?", StringComparison.OrdinalIgnoreCase)) { try { Uri uri = new Uri(Device.Location); string newUri = string.Format("{0}://{1}{2}", uri.Scheme, uri.Authority, albumArt); didl[0].AlbumArtUri[0] = newUri; } catch { } } } trackPlaylistItem = new MrItem(++iTrackId, trackUri, didl); Trace.WriteLine(Trace.kMediaRenderer, "ModelSourceMediaRendererUpnpAv.EventStateLastChangeResponse: uri=" + trackPlaylistItem.Uri + ", metadata=" + trackPlaylistItem.DidlLite.Xml); } } catch (XmlException) { DidlLite didl = new DidlLite(); item item = new item(); item.Title = trackUri; didl.Add(item); trackPlaylistItem = new MrItem(++iTrackId, trackUri, didl); Trace.WriteLine(Trace.kMediaRenderer, "ModelSourceMediaRendererUpnpAv.EventStateLastChangeResponse: uri=" + trackUri + ", metadata="); } Trace.WriteLine(Trace.kTopology, "iMaster=" + iMaster + ", trackUri=" + trackUri + ", iTrackPlaylistItem.Uri=" + ((iTrackPlaylistItem == null) ? "" : iTrackPlaylistItem.Uri) + ", iExpectedUri=" + ((iExpectedTrack == null) ? "" : iExpectedTrack.Uri)); bool changed = false; if (iExpectedTrack != null && trackUri == iExpectedTrack.Uri) { SetCurrent(iExpectedTrack); iTrackIndex = iPlaylist.IndexOf(iExpectedTrack); iExpectedTrack = null; changed = true; } else if (iTrackPlaylistItem == null || trackUri != iTrackPlaylistItem.Uri) { SetCurrent(trackPlaylistItem); iTrackIndex = -1; iExpectedTrack = null; changed = true; } if (changed) { if (EventTrackChanged != null) { EventTrackChanged(this, EventArgs.Empty); } if (iEventTrackChanged != null) { iEventTrackChanged(this, EventArgs.Empty); } if (EventMetaTextChanged != null) { EventMetaTextChanged(this, EventArgs.Empty); } if (EventDetailsChanged != null) { EventDetailsChanged(this, EventArgs.Empty); } } } } state = n.SelectSingleNode("ns:TransportState", xmlNsMan); if (state != null) { XmlNode val = state.SelectSingleNode("@val", xmlNsMan); if (val != null) { ETransportState transportState = ETransportState.eUnknown; if (val.Value == "PLAYING") { transportState = ETransportState.ePlaying; } else if (val.Value == "PAUSED_PLAYBACK") { transportState = ETransportState.ePaused; } else if (val.Value == "STOPPED") { transportState = ETransportState.eStopped; } else if (val.Value == "TRANSITIONING") { transportState = ETransportState.eBuffering; } else { transportState = ETransportState.eUnknown; } Trace.WriteLine(Trace.kMediaRenderer, "ModelSourceMediaRendererUpnpAv.EventStateLastChangeResponse: transportState=" + transportState); if (transportState != iTransportState) { iTransportState = transportState; if (iTransportState == ETransportState.eStopped) { if (iMaster) { if (!iExpectEventStop) { Next(); } } iExpectEventStop = false; } if (EventTransportStateChanged != null) { EventTransportStateChanged(this, EventArgs.Empty); } } } } /*state = n.SelectSingleNode("ns:CurrentTrack", xmlNsMan); * if (state != null) * { * XmlNode val = state.SelectSingleNode("@val", xmlNsMan); * if (val != null) * { * int trackIndex = int.Parse(val.Value) - 1; * * Trace.WriteLine(Trace.kMediaRenderer, "ModelSourceMediaRendererUpnpAv.EventStateLastChangeResponse: trackIndex=" + trackIndex); * * if (trackIndex != iTrackIndex) * { * iTrackIndex = trackIndex; * * if (EventTrackChanged != null) * { * EventTrackChanged(this, EventArgs.Empty); * } * } * } * }*/ state = n.SelectSingleNode("ns:CurrentTrackDuration", xmlNsMan); if (state != null) { XmlNode val = state.SelectSingleNode("@val", xmlNsMan); if (val != null) { try { Time duration = new Time(val.Value); Assert.CheckDebug(duration.SecondsTotal >= 0); uint trackDuration = (duration.SecondsTotal >= 0) ? (uint)duration.SecondsTotal : 0; Trace.WriteLine(Trace.kMediaRenderer, "ModelSourceMediaRendererUpnpAv.EventStateLastChangeResponse: trackDuration=" + duration.ToPrettyString()); iTrackDuration = trackDuration; if (EventDurationChanged != null) { EventDurationChanged(this, EventArgs.Empty); } } catch (Time.TimeInvalid) { if (val.Value != kNotImplemented) { UserLog.WriteLine("ModelSourceMediaRendererUpnpAv.EventStateLastChangeResponse: Invalid element CurrentTrackDuration: " + val.Value); } } } } } } } } } catch (Exception ex) { string lastChange = iServiceAVTransport.LastChange != null ? iServiceAVTransport.LastChange : ""; Trace.WriteLine(Trace.kMediaRenderer, "ModelSourceMediaRendererUpnpAv.EventStateLastChangeResponse: " + ex.Message + "\nLastChange: " + lastChange); UserLog.WriteLine("ModelSourceMediaRendererUpnpAv.EventStateLastChangeResponse: " + ex.Message + "\nLastChange: " + lastChange); return; } }