From: <do...@us...> - 2008-10-29 12:48:42
|
Revision: 2278 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=2278&view=rev Author: dot-i Date: 2008-10-29 12:48:34 +0000 (Wed, 29 Oct 2008) Log Message: ----------- Updated to 1.3.0.0 plugin and recorder/tuner. Modified Paths: -------------- trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/ForTheRecord.RecorderTuners.MediaPortalTvServer.csproj trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/MediaPortalRecorderTunerService.cs trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/RecordingThread.cs trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/SyncEpgThread.cs trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/Utility.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ActiveRecordings.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ForTheRecord.UI.MediaPortal.csproj trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ForTheRecordHome.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/PostBuild.cmd trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/SetupForm.Designer.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/SetupForm.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvFullScreen.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvGuide.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvGuideBase.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvGuideDialog.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvProgramInfo.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvRecorded.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/UpcomingPrograms.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/Utility.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/WindowId.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR_Home.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR_ProgramInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR_RecordedTv.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR_TvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR_Upcoming.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR_Home.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR_ProgramInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR_RecordedTv.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR_TvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR_Upcoming.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR_Home.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR_ProgramInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR_RecordedTv.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR_TvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR_Upcoming.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR_Home.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR_ProgramInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR_RecordedTv.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR_TvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR_Upcoming.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/EditSchedule/EditScheduleController.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/ForTheRecord.UI.Process.csproj trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/Properties/AssemblyInfo.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/SortableBindingList.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/TvGuide/TvGuideController.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/TvGuide/TvGuideModel.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/TvGuide/TvGuideUpcomingProgram.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/UpcomingProgramView.cs trunk/plugins/ForTheRecord/ReferencedAssemblies/ForTheRecord.Entities.dll trunk/plugins/ForTheRecord/ReferencedAssemblies/ForTheRecord.RecorderTuners.Common.dll trunk/plugins/ForTheRecord/ReferencedAssemblies/ForTheRecord.ServiceAgents.dll trunk/plugins/ForTheRecord/ReferencedAssemblies/ForTheRecord.ServiceContracts.dll Added Paths: ----------- trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ChannelNavigator.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TVZapOSD.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TextId.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/Translator.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvCropManager.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvCropSettings.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvGuideSearch.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvMiniGuide.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/TvOSD.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/language/ trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/language/fortherecord_da.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/language/fortherecord_de.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/language/fortherecord_en.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/language/fortherecord_nl.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/ trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/4TR_Active.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/4TR_Home.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/4TR_ProgramInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/4TR_RecordedTv.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/4TR_RecordedTvInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/4TR_TvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/4TR_TvGuideSearch.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/4TR_Upcoming.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/ trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_Alert.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_AlertCancelled.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_AlertSeries.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_AlertSeriesCancelled.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_Recording.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_RecordingCancelled.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_RecordingCancelledHistory.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_RecordingInConflict.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_RecordingSeries.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_RecordingSeriesCancelled.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_RecordingSeriesCancelledHistory.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_RecordingSeriesInConflict.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_RecordingSeriesWithWarning.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_RecordingWithWarning.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_Suggestion.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_SuggestionCancelled.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_SuggestionSeries.png trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Blue3/Media/4TR_SuggestionSeriesCancelled.png trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/CurrentAndNextProgramView.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/CurrentAndNextProgramsList.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/RecorderTunersCache.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/ScheduleNamesCache.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/SearchGuide/ trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/SearchGuide/SearchGuideController.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/SearchGuide/SearchGuideModel.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/TvChannelProgramView.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/TvChannelProgramsList.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/TvGuide/ChannelPrograms.cs trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/UpcomingGuideProgramsDictionary.cs Removed Paths: ------------- trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/Resources/ trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR_FullScreen.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR__FullScreen.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR__Home.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR__ProgramInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR__RecordedTv.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR__TvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR__dialogTvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo/4TR_dialogTvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR_FullScreen.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR__FullScreen.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR__Home.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR__ProgramInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR__RecordedTv.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR__TvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR__dialogTvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/BlueTwo wide/4TR_dialogTvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR_FullScreen.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR__FullScreen.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR__Home.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR__ProgramInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR__RecordedTv.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR__TvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR__dialogTvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Indigo/4TR_dialogTvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR_FullScreen.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR__FullScreen.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR__Home.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR__ProgramInfo.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR__RecordedTv.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR__TvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR__dialogTvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/skin/Monochrome/4TR_dialogTvGuide.xml trunk/plugins/ForTheRecord/ForTheRecord.UI.Process/RecorderTuners.cs Modified: trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/ForTheRecord.RecorderTuners.MediaPortalTvServer.csproj =================================================================== --- trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/ForTheRecord.RecorderTuners.MediaPortalTvServer.csproj 2008-10-27 12:45:24 UTC (rev 2277) +++ trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/ForTheRecord.RecorderTuners.MediaPortalTvServer.csproj 2008-10-29 12:48:34 UTC (rev 2278) @@ -9,14 +9,10 @@ <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>ForTheRecord.RecorderTuners.MediaPortalTvServer</RootNamespace> <AssemblyName>ForTheRecord.RecorderTuners.MediaPortalTvServer</AssemblyName> - <SccProjectName> - </SccProjectName> - <SccLocalPath> - </SccLocalPath> - <SccAuxPath> - </SccAuxPath> - <SccProvider> - </SccProvider> + <SccProjectName>SAK</SccProjectName> + <SccLocalPath>SAK</SccLocalPath> + <SccAuxPath>SAK</SccAuxPath> + <SccProvider>SAK</SccProvider> <FileUpgradeFlags> </FileUpgradeFlags> <OldToolsVersion>2.0</OldToolsVersion> @@ -42,19 +38,19 @@ <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> - <Reference Include="ForTheRecord.Entities, Version=1.2.1.0, Culture=neutral, PublicKeyToken=a9a5dfc20b8d6175, processorArchitecture=MSIL"> + <Reference Include="ForTheRecord.Entities, Version=1.3.0.0, Culture=neutral, PublicKeyToken=a9a5dfc20b8d6175, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\ReferencedAssemblies\ForTheRecord.Entities.dll</HintPath> </Reference> - <Reference Include="ForTheRecord.RecorderTuners.Common, Version=1.2.1.0, Culture=neutral, PublicKeyToken=a9a5dfc20b8d6175, processorArchitecture=MSIL"> + <Reference Include="ForTheRecord.RecorderTuners.Common, Version=1.3.0.0, Culture=neutral, PublicKeyToken=a9a5dfc20b8d6175, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\ReferencedAssemblies\ForTheRecord.RecorderTuners.Common.dll</HintPath> </Reference> - <Reference Include="ForTheRecord.ServiceAgents, Version=1.2.1.0, Culture=neutral, PublicKeyToken=a9a5dfc20b8d6175, processorArchitecture=MSIL"> + <Reference Include="ForTheRecord.ServiceAgents, Version=1.3.0.0, Culture=neutral, PublicKeyToken=a9a5dfc20b8d6175, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\ReferencedAssemblies\ForTheRecord.ServiceAgents.dll</HintPath> </Reference> - <Reference Include="ForTheRecord.ServiceContracts, Version=1.2.1.0, Culture=neutral, PublicKeyToken=a9a5dfc20b8d6175, processorArchitecture=MSIL"> + <Reference Include="ForTheRecord.ServiceContracts, Version=1.3.0.0, Culture=neutral, PublicKeyToken=a9a5dfc20b8d6175, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\ReferencedAssemblies\ForTheRecord.ServiceContracts.dll</HintPath> </Reference> Modified: trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/MediaPortalRecorderTunerService.cs =================================================================== --- trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/MediaPortalRecorderTunerService.cs 2008-10-27 12:45:24 UTC (rev 2277) +++ trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/MediaPortalRecorderTunerService.cs 2008-10-29 12:48:34 UTC (rev 2278) @@ -49,6 +49,12 @@ InstanceContextMode = InstanceContextMode.Single)] public class MediaPortalRecorderTunerService : ThreadedRecorderTunerService<RecordingThread> { + private const string _ftrLiveUserName = "FTRLive"; + + private object _tvStreamsLock = new object(); + private Dictionary<string, LiveTvStream> _tvStreams = new Dictionary<string, LiveTvStream>(); + private Dictionary<string, User> _tvStreamUsers = new Dictionary<string, User>(); + protected override string Name { get { return "MediaPortal TV Server"; } @@ -60,14 +66,13 @@ { // // Find the channel in MediaPortal (match by DisplayName) and get all the - // channel's tuning details and the cards it is mapped to. + // cards this channel is mapped to. // Channel channel; - IList tuningDetails; - List<Card> availableCards = GetCardsForChannel(tvChannelName, out channel, out tuningDetails); + List<Card> availableCards = GetCardsForChannel(tvChannelName, out channel); - // Sort the cards by priority. - availableCards.Sort(delegate(Card c1, Card c2) { return -c1.Priority.CompareTo(c2.Priority); }); + // Sort the cards by reverse(!) priority. + availableCards.Sort(delegate(Card c1, Card c2) { return c1.Priority.CompareTo(c2.Priority); }); // // Now remove all card that were previously allocated. @@ -77,7 +82,9 @@ Card cardToRemove = null; foreach (Card card in availableCards) { - if (GetCardId(card) == allocation.CardId) + TuningDetail tuning = Utility.FindTuningDetailOnCard(channel, card.IdCard); + if (GetCardId(card) == allocation.CardId + && tuning != null) { // // This card was already allocated before, but we may be able to reuse the card. @@ -88,28 +95,17 @@ if (channel.FreeToAir || CountNumTimesAllocated(alreadyAllocated, allocation.CardId) < card.DecryptLimit) { - // Get the previously allocated channel's tuning details and let's check if the + // Get the previously allocated channel and its tuning details and let's check if the // channel we want is on the same transponder as that channel. - IList allocatedTuningDetails; - Channel allocatedChannel = GetChannelAndTuningByDisplayName(allocation.TvChannelName, out allocatedTuningDetails); - if (allocatedChannel != null) + Channel allocatedChannel = GetChannelByDisplayName(allocation.TvChannelName); + Card allocatedCard = GetCardByCardId(allocation.CardId); + if (allocatedChannel != null + && allocatedCard != null) { - foreach(TuningDetail tuning in tuningDetails) + if (Utility.IsSameTransponder(allocatedCard.IdCard, tuning, allocatedChannel)) { - foreach(TuningDetail allocatedTuning in allocatedTuningDetails) - { - if (tuning.ChannelType >= 1 && tuning.ChannelType <= 4 // ATSC or DVB-x channel? - && tuning.ChannelType == allocatedTuning.ChannelType - && tuning.Frequency == allocatedTuning.Frequency - && tuning.Symbolrate == allocatedTuning.Symbolrate - && tuning.Polarisation == allocatedTuning.Polarisation - && tuning.Bandwidth == allocatedTuning.Bandwidth - && tuning.Modulation == allocatedTuning.Modulation) - { - // Same transponder, so we can re-use the card. - return allocation.CardId; - } - } + // Same transponder, so we can re-use the card. + return allocation.CardId; } } } @@ -127,9 +123,13 @@ // If there's still at least one card available, return the card // with the highest priority. // - if (availableCards.Count > 0) + foreach (Card card in availableCards) { - return GetCardId(availableCards[0]); + TuningDetail tuning = Utility.FindTuningDetailOnCard(channel, card.IdCard); + if (tuning != null) + { + return GetCardId(card); + } } } catch (Exception ex) @@ -149,8 +149,6 @@ Channel channel = GetChannelByDisplayName(channelAllocation.TvChannelName); if (channel != null) { - Log(TraceEventType.Information, "{0} - Starting recording thread for card {1}, channel {2}: {3}", - this.Name, recordOnCard.IdCard, channel.DisplayName, recordingProgram.CreateProgramTitle()); result = this.RecordingThreads.StartNewThread(new RecordingThread(this.RecorderTunerId, tvSchedulerHostName, tvSchedulerTcpPort, channelAllocation, startTime, stopTime, recordingProgram, recordOnCard, channel)); @@ -189,6 +187,241 @@ return shares.ToArray(); } + public override LiveTvResult TuneLiveTvStream(Guid tvChannelId, string tvChannelName, ref LiveTvStream liveTvStream) + { + try + { + Channel channel; + List<Card> availableCards = GetCardsForChannel(tvChannelName, out channel); + + // Sort the cards by priority. + availableCards.Sort(delegate(Card c1, Card c2) { return -c1.Priority.CompareTo(c2.Priority); }); + + if (liveTvStream != null + && _tvStreamUsers.ContainsKey(liveTvStream.RtspUrl)) + { + User tve3User = _tvStreamUsers[liveTvStream.RtspUrl]; + foreach (Card card in availableCards) + { + if (card.IdCard == tve3User.CardId) + { + if (CardFreeOrUsingSameTransponder(card.IdCard, channel, tve3User)) + { + LiveTvResult result = StartTimeShifting(card, channel, ref tve3User, ref liveTvStream); + if (result != LiveTvResult.NoFreeCardFound) + { + return result; + } + } + } + } + } + + if (liveTvStream != null) + { + StopLiveTvStream(liveTvStream); + liveTvStream = null; + } + + foreach (Card card in availableCards) + { + if (CardFreeOrUsingSameTransponder(card.IdCard, channel, null)) + { + string userName = String.Format(CultureInfo.InvariantCulture, "{0}{1}", _ftrLiveUserName, Guid.NewGuid()); + + User tve3User = new User(userName, true, card.IdCard); + tve3User.IdChannel = channel.IdChannel; + tve3User.SubChannel = -1; + + LiveTvResult result = StartTimeShifting(card, channel, ref tve3User, ref liveTvStream); + if (result != LiveTvResult.NoFreeCardFound) + { + return result; + } + } + } + } + catch (Exception ex) + { + Log(TraceEventType.Error, ex.Message); + } + + return LiveTvResult.NoFreeCardFound; + } + + private bool CardFreeOrUsingSameTransponder(int cardId, Channel channel, User userToIgnore) + { + User[] cardUsers = TvServerPlugin.TvController.GetUsersForCard(cardId); + if (cardUsers != null) + { + TuningDetail tuning = Utility.FindTuningDetailOnCard(channel, cardId); + foreach (User cardUser in cardUsers) + { + if (userToIgnore == null + || cardUser.Name != userToIgnore.Name) + { + if (!Utility.IsSameTransponder(cardId, tuning, cardUser.IdChannel)) + { + return false; + } + } + } + } + return true; + } + + private LiveTvResult StartTimeShifting(Card card, Channel channel, ref User tve3User, ref LiveTvStream liveTvStream) + { + IChannel tuningChannel = Utility.FindTuningChannelOnCard(channel, card.IdCard); + if (tuningChannel != null) + { + if (TvServerPlugin.TvController.Tune(ref tve3User, tuningChannel, channel.IdChannel) == TvResult.Succeeded) + { + string fileName = Path.Combine(card.TimeShiftFolder, + String.Format(CultureInfo.InvariantCulture, @"live{0}-{1}.ts", tve3User.CardId, tve3User.SubChannel)); + + switch (TvServerPlugin.TvController.StartTimeShifting(ref tve3User, ref fileName)) + { + case TvResult.Succeeded: + if (liveTvStream == null) + { + lock (_tvStreamsLock) + { + liveTvStream = new LiveTvStream(TvServerPlugin.TvController.GetStreamingUrl(tve3User)); + _tvStreams.Add(liveTvStream.RtspUrl, liveTvStream); + _tvStreamUsers.Add(liveTvStream.RtspUrl, tve3User); + } + } + return LiveTvResult.Succeeded; + + case TvResult.AllCardsBusy: + return LiveTvResult.NoFreeCardFound; + + default: + return LiveTvResult.UnknownError; + } + } + else + { + return LiveTvResult.ChannelTuneFailed; + } + } + else + { + return LiveTvResult.ChannelTuneFailed; + } + } + + public override void StopLiveTvStream(LiveTvStream liveTvStream) + { + lock (_tvStreamsLock) + { + try + { + if (_tvStreams.ContainsKey(liveTvStream.RtspUrl)) + { + User tve3User = _tvStreamUsers[liveTvStream.RtspUrl]; + if (TvServerPlugin.TvController.IsTimeShifting(ref tve3User)) + { + if (!TvServerPlugin.TvController.StopTimeShifting(ref tve3User)) + { + Log(TraceEventType.Error, "Failed to stop TV stream '{0}'", liveTvStream.RtspUrl); + } + } + _tvStreams.Remove(liveTvStream.RtspUrl); + _tvStreamUsers.Remove(liveTvStream.RtspUrl); + } + } + catch (Exception ex) + { + Log(TraceEventType.Error, ex.Message); + } + } + } + + public override LiveTvStream[] GetLiveTvStreams() + { + List<LiveTvStream> liveTvStreams = new List<LiveTvStream>(); + lock (_tvStreamsLock) + { + try + { + // Get cards in reverse priority. + List<Card> cards = Utility.GetAllCards(); + cards.Sort(delegate(Card c1, Card c2) { return c1.Priority.CompareTo(c2.Priority); }); + + // Get the list of live streams from TV Server + Dictionary<string, User> mpStreams = new Dictionary<string, User>(); + foreach (Card card in cards) + { + User[] cardUsers = TvServerPlugin.TvController.GetUsersForCard(card.IdCard); + if (cardUsers != null) + { + foreach (User user in cardUsers) + { + if (user.Name.StartsWith(_ftrLiveUserName)) + { + User tve3User = user; + if (TvServerPlugin.TvController.IsTimeShifting(ref tve3User)) + { + mpStreams.Add(TvServerPlugin.TvController.GetStreamingUrl(tve3User), tve3User); + } + } + } + } + } + + // Now loop our own list and check if all those streams are indeed still up. + List<string> keysToRemove = new List<string>(); + + foreach (LiveTvStream tvStream in _tvStreams.Values) + { + if (mpStreams.ContainsKey(tvStream.RtspUrl)) + { + liveTvStreams.Add(tvStream); + } + else + { + keysToRemove.Add(tvStream.RtspUrl); + } + } + + // Remove streams that no longer exist. + foreach(string keyToRemove in keysToRemove) + { + _tvStreams.Remove(keyToRemove); + } + + // Check if there are any live streams within MP that we don't know about. + // If so, stop those streams (they may be left-overs from client crashes). + foreach (string rtspUrl in mpStreams.Keys) + { + if (!_tvStreams.ContainsKey(rtspUrl)) + { + User tve3User = mpStreams[rtspUrl]; + TvServerPlugin.TvController.StopTimeShifting(ref tve3User, TvStoppedReason.KickedByAdmin); + } + } + } + catch (Exception ex) + { + Log(TraceEventType.Error, ex.Message); + } + } + return liveTvStreams.ToArray(); + } + + public override void KeepLiveTvStreamAlive(LiveTvStream liveTvStream) + { + lock (_tvStreamsLock) + { + if (_tvStreams.ContainsKey(liveTvStream.RtspUrl)) + { + _tvStreams[liveTvStream.RtspUrl].StreamLastAliveTime = liveTvStream.StreamLastAliveTime; + } + } + } + protected override void OnWriteLog(TraceEventType severity, string message) { if (severity == TraceEventType.Error) @@ -203,13 +436,12 @@ #region Private Methods - private List<Card> GetCardsForChannel(string tvChannelName, out Channel channel, out IList tuningDetails) + private List<Card> GetCardsForChannel(string tvChannelName, out Channel channel) { List<Card> availableCards = new List<Card>(); - channel = GetChannelAndTuningByDisplayName(tvChannelName, out tuningDetails); - if (channel != null - && tuningDetails.Count > 0) + channel = GetChannelByDisplayName(tvChannelName); + if (channel != null) { // // Now build a list of all available cards by getting a list of all the cards that @@ -258,18 +490,6 @@ return null; } - private Channel GetChannelAndTuningByDisplayName(string displayName, out IList tuningDetails) - { - Channel channel = GetChannelByDisplayName(displayName); - if (channel != null) - { - tuningDetails = channel.ReferringTuningDetail(); - return channel; - } - tuningDetails = new List<TuningDetail>(); - return null; - } - private Channel GetChannelByDisplayName(string displayName) { SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof(Channel)); Modified: trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/RecordingThread.cs =================================================================== --- trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/RecordingThread.cs 2008-10-27 12:45:24 UTC (rev 2277) +++ trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/RecordingThread.cs 2008-10-29 12:48:34 UTC (rev 2278) @@ -173,6 +173,8 @@ private bool EnsureCardFree(ref string errorMessage) { + TuningDetail tuning = Utility.FindTuningDetailOnCard(_channel, _recordOnCard.IdCard); + User[] cardUsers = TvServerPlugin.TvController.GetUsersForCard(_recordOnCard.IdCard); foreach (User cardUser in cardUsers) { @@ -189,10 +191,13 @@ } else if (TvServerPlugin.TvController.IsTimeShifting(ref tmpUser)) { - if (!TvServerPlugin.TvController.StopTimeShifting(ref tmpUser, TvStoppedReason.RecordingStarted)) + if (!Utility.IsSameTransponder(_recordOnCard.IdCard, tuning, tmpUser.IdChannel)) { - errorMessage = "Failed to stop timeshifting on channel " + _channel.DisplayName; - return false; + if (!TvServerPlugin.TvController.StopTimeShifting(ref tmpUser, TvStoppedReason.RecordingStarted)) + { + errorMessage = "Failed to stop timeshifting on channel " + _channel.DisplayName; + return false; + } } } } Modified: trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/SyncEpgThread.cs =================================================================== --- trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/SyncEpgThread.cs 2008-10-27 12:45:24 UTC (rev 2277) +++ trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/SyncEpgThread.cs 2008-10-29 12:48:34 UTC (rev 2278) @@ -152,73 +152,95 @@ TvBusinessLayer layer = new TvBusinessLayer(); bool epgSyncAutoCreateChannels = Convert.ToBoolean(layer.GetSetting(SettingName.EpgSyncAutoCreateChannels, false.ToString()).Value); - IList mpChannels = Channel.ListAll(); - foreach (Channel channel in mpChannels) + _tvGuideAgent.StartGuideImport(); + try { - // only execute for tv channels - if (channel.IsTv) + bool aborted = false; + + IList mpChannels = Channel.ListAll(); + foreach (Channel channel in mpChannels) { - TvChannel tvChannel = _tvSchedulerAgent.GetChannelByDisplayName(channel.DisplayName); - if (tvChannel == null - && epgSyncAutoCreateChannels) + // only execute for tv channels + if (channel.IsTv) { - Guid tvChannelId = _tvSchedulerAgent.EnsureChannel(channel.DisplayName, "DVB-EPG"); - tvChannel = _tvSchedulerAgent.GetChannelById(tvChannelId); - } - if (tvChannel != null) - { - Guid guideChannelId; - if (!tvChannel.GuideChannelId.HasValue) + TvChannel tvChannel = _tvSchedulerAgent.GetChannelByDisplayName(channel.DisplayName); + if (tvChannel == null + && epgSyncAutoCreateChannels) { - string externalId = channel.ExternalId; - if (String.IsNullOrEmpty(externalId)) + Guid tvChannelId = _tvSchedulerAgent.EnsureChannel(channel.DisplayName, "DVB-EPG"); + tvChannel = _tvSchedulerAgent.GetChannelById(tvChannelId); + } + if (tvChannel != null) + { + Guid guideChannelId; + if (!tvChannel.GuideChannelId.HasValue) { - externalId = tvChannel.TvChannelId.ToString("N", CultureInfo.InvariantCulture); + string externalId = channel.ExternalId; + if (String.IsNullOrEmpty(externalId)) + { + externalId = tvChannel.TvChannelId.ToString("N", CultureInfo.InvariantCulture); + } + guideChannelId = _tvGuideAgent.EnsureChannel(externalId, channel.DisplayName); + _tvSchedulerAgent.AttachChannelToGuide(tvChannel.TvChannelId, guideChannelId); } - guideChannelId = _tvGuideAgent.EnsureChannel(externalId, channel.DisplayName); - _tvSchedulerAgent.AttachChannelToGuide(tvChannel.TvChannelId, guideChannelId); - } - else - { - guideChannelId = tvChannel.GuideChannelId.Value; - } + else + { + guideChannelId = tvChannel.GuideChannelId.Value; + } - IList mpPrograms = layer.GetPrograms(channel, synchronizeAll ? DateTime.Today : latestProgramTime, DateTime.Today.AddDays(14)); - List<GuideProgram> guidePrograms = new List<GuideProgram>(); - foreach (Program program in mpPrograms) - { - if (program.StartTime < program.EndTime) + IList mpPrograms = layer.GetPrograms(channel, synchronizeAll ? DateTime.Today : latestProgramTime, DateTime.Today.AddDays(14)); + List<GuideProgram> guidePrograms = new List<GuideProgram>(); + foreach (Program program in mpPrograms) { - GuideProgram guideProgram = new GuideProgram(); - guideProgram.GuideChannelId = guideChannelId; - guideProgram.Category = program.Genre; - guideProgram.Description = program.Description; - guideProgram.EpisodeNumberDisplay = program.EpisodeNum; - guideProgram.Rating = program.Classification; - guideProgram.StartTime = program.StartTime; - guideProgram.StopTime = program.EndTime; - guideProgram.Title = program.Title; - guidePrograms.Add(guideProgram); + if (program.StartTime < program.EndTime) + { + GuideProgram guideProgram = new GuideProgram(); + guideProgram.GuideChannelId = guideChannelId; + guideProgram.Category = program.Genre; + guideProgram.Description = program.Description; + guideProgram.EpisodeNumberDisplay = program.EpisodeNum; + guideProgram.Rating = program.Classification; + guideProgram.StartTime = program.StartTime; + guideProgram.StopTime = program.EndTime; + guideProgram.Title = program.Title; + guidePrograms.Add(guideProgram); - if (guideProgram.StartTime > latestProgramTime) - { - latestProgramTime = guideProgram.StartTime; + if (guideProgram.StartTime > latestProgramTime) + { + latestProgramTime = guideProgram.StartTime; + } + + if (guidePrograms.Count >= _syncBatchSize) + { + _tvGuideAgent.ImportPrograms(guidePrograms.ToArray(), GuideSource.DvbEpg); + guidePrograms.Clear(); + } } - if (guidePrograms.Count >= _syncBatchSize) + aborted = this.StopThreadEvent.WaitOne(0, false); + if (aborted) { - _tvGuideAgent.ImportPrograms(guidePrograms.ToArray(), GuideSource.DvbEpg); - guidePrograms.Clear(); + break; } } + if (!aborted + && guidePrograms.Count > 0) + { + _tvGuideAgent.ImportPrograms(guidePrograms.ToArray(), GuideSource.DvbEpg); + } } - if (guidePrograms.Count > 0) - { - _tvGuideAgent.ImportPrograms(guidePrograms.ToArray(), GuideSource.DvbEpg); - } } + + if (aborted) + { + break; + } } } + finally + { + _tvGuideAgent.EndGuideImport(); + } return latestProgramTime; } Modified: trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/Utility.cs =================================================================== --- trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/Utility.cs 2008-10-27 12:45:24 UTC (rev 2277) +++ trunk/plugins/ForTheRecord/ForTheRecord.RecorderTuners.MediaPortalTvServer/Utility.cs 2008-10-29 12:48:34 UTC (rev 2278) @@ -63,6 +63,44 @@ return foundChannel; } + public static TuningDetail FindTuningDetailOnCard(Channel channel, int cardId) + { + try + { + CardType cardType = TvServerPlugin.TvController.Type(cardId); + IList tuningDetails = channel.ReferringTuningDetail(); + foreach (TuningDetail tuningDetail in tuningDetails) + { + if (CardTunesChannelType(cardType, tuningDetail.ChannelType)) + { + return tuningDetail; + } + } + } + catch + { + } + return null; + } + + public static bool CardTunesChannelType(CardType cardType, int channelType) + { + switch (cardType) + { + case CardType.Analog: + return (channelType == 0); + case CardType.Atsc: + return (channelType == 1); + case CardType.DvbC: + return (channelType == 2); + case CardType.DvbS: + return (channelType == 3); + case CardType.DvbT: + return (channelType == 4); + } + return false; + } + public static IChannel FindTuningChannelOnCard(Channel channel, int cardId) { IChannel tuningChannel = null; @@ -71,7 +109,7 @@ List<IChannel> tunings = new TvBusinessLayer().GetTuningChannelByName(channel); foreach (IChannel tuning in tunings) { - if (RemoteControl.Instance.CanTune(cardId, tuning)) + if (TvServerPlugin.TvController.CanTune(cardId, tuning)) { tuningChannel = tuning; break; @@ -99,5 +137,35 @@ } return cards; } + + public static bool IsSameTransponder(int cardId, TuningDetail tuning, int otherChannelId) + { + Channel otherChannel = Channel.Retrieve(otherChannelId); + if (otherChannel != null) + { + return IsSameTransponder(cardId, tuning, otherChannel); + } + return false; + } + + public static bool IsSameTransponder(int cardId, TuningDetail tuning, Channel otherChannel) + { + TuningDetail otherTuning = Utility.FindTuningDetailOnCard(otherChannel, cardId); + if (tuning != null + && otherTuning != null) + { + if (tuning.ChannelType >= 2 && tuning.ChannelType <= 4 // DVB-x channel? ,no Atsc(==1) + && tuning.ChannelType == otherTuning.ChannelType + && tuning.Frequency == otherTuning.Frequency + && tuning.Symbolrate == otherTuning.Symbolrate + && tuning.Polarisation == otherTuning.Polarisation + && tuning.Bandwidth == otherTuning.Bandwidth + && tuning.Modulation == otherTuning.Modulation) + { + return true; + } + } + return false; + } } } Modified: trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ActiveRecordings.cs =================================================================== --- trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ActiveRecordings.cs 2008-10-27 12:45:24 UTC (rev 2277) +++ trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ActiveRecordings.cs 2008-10-29 12:48:34 UTC (rev 2278) @@ -43,7 +43,6 @@ using ForTheRecord.ServiceAgents; using ForTheRecord.ServiceContracts; using ForTheRecord.UI.Process.Recordings; -using ForTheRecord.UI.MediaPortal.Resources; namespace ForTheRecord.UI.MediaPortal { @@ -275,7 +274,7 @@ switch (dlg.SelectedId) { case 655: // Play - OnPlayRecording(activeRecording); + PlayRecording(activeRecording, false); break; case 1449: // Abort @@ -296,7 +295,7 @@ { UpcomingProgram program = activeRecording.Program; - dlgYesNo.SetHeading(GUILocalizeStrings.Get(1449)); + dlgYesNo.SetHeading(Utility.GetLocalizedText(TextId.StopRecording)); dlgYesNo.SetLine(1, program.TvChannel.DisplayName); dlgYesNo.SetLine(2, program.Title); dlgYesNo.SetLine(3, string.Empty); @@ -324,20 +323,29 @@ ActiveRecording activeRecording = item.TVTag as ActiveRecording; if (activeRecording != null) { - return OnPlayRecording(activeRecording); + return PlayRecording(activeRecording, false); } return false; } - private bool OnPlayRecording(ActiveRecording activeRecording) + internal static bool PlayRecording(ActiveRecording activeRecording, bool jumpToLivePoint) { - TvRecording recording = this.TvControlAgent.GetRecordingById(activeRecording.TvRecordingId); - if (recording != null) + using (TvControlServiceAgent tvControlAgent = new TvControlServiceAgent()) { - TvRecorded.PlayRecording(recording); - return true; + TvRecording recording = tvControlAgent.GetRecordingById(activeRecording.TvRecordingId); + if (recording != null) + { + int? jumpTo = null; + if (jumpToLivePoint) + { + TimeSpan duration = DateTime.Now - activeRecording.RecordingStartTime; + jumpTo = (int)duration.TotalSeconds - 3; + } + TvRecorded.PlayRecording(recording, jumpTo); + return true; + } + return false; } - return false; } public override void Process() @@ -363,7 +371,7 @@ _viewsList.Add(item); } - string strObjects = string.Format("{0} {1}", _viewsList.Count, GlobalText.RecordingsListItemsSuffix); + string strObjects = string.Format("{0} {1}", _viewsList.Count, Utility.GetLocalizedText(TextId.RecordingsListItemsSuffix)); GUIPropertyManager.SetProperty("#itemcount", strObjects); GUIControl cntlLabel = GetControl(12); @@ -552,8 +560,8 @@ switch (_currentSortMethod) { case SortMethod.Played: - //item1.Label2 = string.Format("{0} {1}", rec1.TimesWatched, GUILocalizeStrings.Get(677));//times - //item2.Label2 = string.Format("{0} {1}", rec2.TimesWatched, GUILocalizeStrings.Get(677));//times + //item1.Label2 = string.Format("{0} {1}", rec1.TimesWatched, Utility.GetLocalizedText(TextId.Times)); + //item2.Label2 = string.Format("{0} {1}", rec2.TimesWatched, Utility.GetLocalizedText(TextId.Times)); if (rec1.LastWatchedPosition == rec2.LastWatchedPosition) { goto case SortMethod.Name; Added: trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ChannelNavigator.cs =================================================================== --- trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ChannelNavigator.cs (rev 0) +++ trunk/plugins/ForTheRecord/ForTheRecord.UI.MediaPortal/ChannelNavigator.cs 2008-10-29 12:48:34 UTC (rev 2278) @@ -0,0 +1,804 @@ +#region Copyright (C) 2005-2008 Team MediaPortal + +/* + * Copyright (C) 2005-2008 Team MediaPortal + * http://www.team-mediaportal.com + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Text; + +using MediaPortal.Configuration; +using MediaPortal.GUI.Library; +using MediaPortal.Player; +using MediaPortal.Dialogs; + +using ForTheRecord.Entities; +using ForTheRecord.ServiceAgents; + +namespace ForTheRecord.UI.MediaPortal +{ + internal class ChannelNavigator + { + private List<TvChannelGroup> _groups = new List<TvChannelGroup>(); + private TvChannelGroup _currentChannelGroup; + private List<TvChannel> _channels = new List<TvChannel>(); + private CurrentAndNextProgram _currentNextProgram; + private GuideProgram _currentProgram; + private GuideProgram _nextProgram; + private TvChannel _currentChannel; + private TvChannel _previousChannel; + private TvChannelGroup _previousChannelGroup; + private TvChannelGroup _zapGroup; + private TvChannel _zapChannel; + private DateTime _zapTime; + private GuideProgram _zapProgram; + private long _zapDelayMs; + + public ChannelNavigator() + { + RefreshChannelGroups(); + } + + #region Public properties + + /// <summary> + /// Gets the channel that we currently watch. + /// Returns empty string if there is no current channel. + /// </summary> + public string CurrentChannelName + { + get + { + return _currentChannel == null ? String.Empty : _currentChannel.DisplayName; + } + } + + public TvChannel CurrentChannel + { + get { return _currentChannel; } + } + + public string ZapChannelName + { + get + { + return _zapChannel == null ? String.Empty : _zapChannel.DisplayName; + } + } + + public TvChannel ZapChannel + { + get { return _zapChannel; } + } + + /// <summary> + /// Gets and sets the last viewed channel, null if there is none. + /// </summary> + public TvChannel PreviousChannel + { + get { return _previousChannel; } + set { _previousChannel = value; } + } + + /// <summary> + /// Gets the currently active tv channel group. + /// </summary> + public TvChannelGroup CurrentGroup + { + get { return _currentChannelGroup; } + set { _currentChannelGroup = value; RefreshChannelsInGroup(); } + } + + /// <summary> + /// Gets the list of tv channel groups. + /// </summary> + public List<TvChannelGroup> Groups + { + get { return _groups; } + } + + public GuideProgram CurrentProgram + { + get { return _currentProgram; } + } + + public GuideProgram NextProgram + { + get { return _nextProgram; } + } + + public GuideProgram ZapProgram + { + get { return _zapProgram; } + } + + public bool IsLiveTvOn + { + get { return _liveTvStream != null; } + } + + #endregion + + #region Public methods + + public void RefreshChannelGroups() + { + try + { + using (TvSchedulerServiceAgent tvSchedulerAgent = new TvSchedulerServiceAgent()) + { + _groups = new List<TvChannelGroup>(tvSchedulerAgent.GetAllChannelGroups(true)); + if (_currentChannelGroup != null + && _currentChannelGroup.TvChannelGroupId != Guid.Empty) + { + bool currentFound = false; + foreach (TvChannelGroup group in _groups) + { + if (group.TvChannelGroupId == _currentChannelGroup.TvChannelGroupId) + { + currentFound = true; + break; + } + } + if (!currentFound) + { + _currentChannelGroup = null; + } + } + + bool hideAllChannelsGroup = false; + using (global::MediaPortal.Profile.Settings xmlreader = + new global::MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml"))) + { + hideAllChannelsGroup = xmlreader.GetValueAsBool("mytv", "hideAllChannelsGroup", false); + } + + if (!hideAllChannelsGroup) + { + _groups.Add(new TvChannelGroup(Guid.Empty, Utility.GetLocalizedText(TextId.AllChannels), true, int.MaxValue, 0)); + } + if (_currentChannelGroup == null + && _groups.Count > 0) + { + _currentChannelGroup = _groups[0]; + RefreshChannelsInGroup(tvSchedulerAgent); + } + } + } + catch (Exception ex) + { + Log.Error("ChannelNavigator: Error in LoadChannelGroups - {0}", ex.Message); + } + } + + public void ZapNow() + { + _zapTime = DateTime.Now.AddSeconds(-1); + } + + private bool _reentrant = false; + + /// <summary> + /// Checks if it is time to zap to a different channel. This is called during Process(). + /// </summary> + public bool CheckChannelChange() + { + if (_reentrant) + { + return false; + } + try + { + _reentrant = true; + + //UpdateCurrentChannel(); + + // Make sure current and next is up to date. + if (_currentNextProgram != null) + { + if ((_currentNextProgram.Current != null + && _currentNextProgram.Current.StopTime < DateTime.Now) + || (_currentNextProgram.Next != null + && _currentNextProgram.Next.StartTime < DateTime.Now)) + { + RefreshCurrentAndNext(); + } + } + + // Zapping to another group or channel? + if (_zapGroup != null || _zapChannel != null) + { + // Time to zap? + if (DateTime.Now >= _zapTime) + { + // Zapping to another group? +... [truncated message content] |