private string SwitchTVServerToChannel(string userName, int channelId) { if (String.IsNullOrEmpty(userName)) { ServiceRegistration.Get <ILogger>().Error("Called SwitchTVServerToChannel with empty userName"); throw new ArgumentNullException("userName"); } IUser currentUser = UserFactory.CreateBasicUser(userName, -1); ServiceRegistration.Get <ILogger>().Debug("Starting timeshifiting with username {0} on channel id {1}", userName, channelId); IInternalControllerService control = GlobalServiceProvider.Get <IInternalControllerService>(); IVirtualCard card; IUser user; TvResult result = control.StartTimeShifting(currentUser.Name, channelId, out card, out user); ServiceRegistration.Get <ILogger>().Debug("Tried to start timeshifting, result {0}", result); if (result != TvResult.Succeeded) { // TODO: should we retry? ServiceRegistration.Get <ILogger>().Error("Starting timeshifting failed with result {0}", result); throw new Exception("Failed to start tv stream: " + result); } return(userName.StartsWith(LOCAL_USERNAME + "-") ? card.TimeShiftFileName : card.RTSPUrl); }
protected override string SwitchTVServerToChannel(string userName, int channelId) { if (String.IsNullOrEmpty(userName)) { ServiceRegistration.Get <ILogger>().Error("Called SwitchTVServerToChannel with empty userName"); throw new ArgumentNullException("userName"); } IUser currentUser = UserFactory.CreateBasicUser(userName, -1); ServiceRegistration.Get <ILogger>().Debug("Starting timeshifiting with username {0} on channel id {1}", userName, channelId); // actually start timeshifting VirtualCard card; TvResult result = _tvControl.StartTimeShifting(ref currentUser, channelId, out card); // make sure result is correct and return if (result != TvResult.Succeeded) { ServiceRegistration.Get <ILogger>().Error("Starting timeshifting failed with result {0}", result); return(null); } if (card == null) { ServiceRegistration.Get <ILogger>().Error("Couldn't get virtual card"); return(null); } return(userName.StartsWith(LOCAL_USERNAME + "-") ? card.TimeShiftFileName : card.RTSPUrl); }
public TvResult Tune(ITvCardHandler tvcard, ref IUser user, IChannel channel, int idChannel, ICardTuneReservationTicket ticket) { TvResult tvResult = TvResult.AllCardsBusy; bool ticketFound; bool isTuningPending = CardReservationHelper.GetIsTuningPending(tvcard, ticket, out ticketFound); try { if (isTuningPending && ticketFound) { tvResult = tvcard.Tuner.Tune(ref user, channel, idChannel); bool succes = (tvResult == TvResult.Succeeded); if (succes) { if (!OnStartTune(user)) { tvResult = TvResult.AllCardsBusy; } } CardReservationHelper.SetCardStateBasedOnTVresult(tvcard, tvResult); } else // state is not tuning, some other card tune session is busy. { } } finally { CardReservationHelper.RemoveTuneTicket(tvcard, ticket, ticketFound); tvcard.Tuner.CleanUpPendingTune(ticket.PendingSubchannel); } return(tvResult); }
private void gridRadioChannels_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { serverIntf.StopTimeShifting(); extPlayer.Stop(); string rtspURL = ""; if (gridRadioChannels.SelectedRows[0].Cells[2].Value.ToString() == "DVB") { StBarLabel.Text = "Trying to start timeshifting..."; StBar.Update(); TvResult result = serverIntf.StartTimeShifting(int.Parse(gridRadioChannels.SelectedRows[0].Cells[0].Value.ToString()), ref rtspURL); StBarLabel.Text = ""; StBar.Update(); if (result != TvResult.Succeeded) { MessageBox.Show("Could not start timeshifting\nReason: " + result.ToString()); } } else { rtspURL = serverIntf.GetWebStreamURL(int.Parse(gridRadioChannels.SelectedRows[0].Cells[0].Value.ToString())); } if (ClientSettings.useOverride) { rtspURL = ClientSettings.overrideURL; } string args = string.Format(ClientSettings.playerArgs, rtspURL); if (!extPlayer.Start(ClientSettings.playerPath, args)) { MessageBox.Show("Failed to start external player.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void LoadSubDirectories(string searchDirectory, TreeNode treeNode) { try { string[] subdirectories = Directory.GetDirectories(searchDirectory); foreach (string subdirectory in subdirectories) { DirectoryInfo directoryInfo = new DirectoryInfo(subdirectory); TreeNode treeNode1 = (TreeNode)TvResult.Invoke(new Func <string, TreeNode>((s) => treeNode.Nodes.Add(s)), directoryInfo.Name); treeNode1.Tag = directoryInfo.FullName; LoadSubDirectories(subdirectory, treeNode1); LoadFiles(subdirectory, treeNode1); if (treeNode1.Nodes.Count == 0) { TvResult.Invoke(new Action <TreeNode>((s) => treeNode.Nodes.Remove(s)), treeNode1); Thread.Sleep(25); } } } catch (UnauthorizedAccessException) { } }
/// <summary> /// Gets a list of all free cards which can receive the channel specified /// List is sorted. /// </summary> /// <returns>list containg all free cards which can receive the channel</returns> public List <CardDetail> GetFreeCardsForChannel(Dictionary <int, ITvCardHandler> cards, Channel dbChannel, ref IUser user, out TvResult result) { Stopwatch stopwatch = Stopwatch.StartNew(); try { //Log.Info("GetFreeCardsForChannel st {0}", Environment.StackTrace); //construct list of all cards we can use to tune to the new channel if (LogEnabled) { Log.Info("Controller: find free card for channel {0}", dbChannel.DisplayName); } var cardsAvailable = new List <CardDetail>(); Dictionary <int, TvResult> cardsUnAvailable; List <CardDetail> cardDetails = GetAvailableCardsForChannel(cards, dbChannel, ref user, out cardsUnAvailable); foreach (CardDetail cardDetail in cardDetails) { bool checkTransponder = CheckTransponder(user, cards[cardDetail.Card.IdCard], cardDetail.Card.DecryptLimit, cardDetail.Card.IdCard, cardDetail.TuningDetail); if (checkTransponder) { cardsAvailable.Add(cardDetail); } } //sort cards cardsAvailable.Sort(); if (cardsAvailable.Count > 0) { result = TvResult.Succeeded; } else { TvResult resultNoCards = GetResultNoCards(cardsUnAvailable); result = cardDetails.Count == 0 ? resultNoCards : TvResult.AllCardsBusy; } if (LogEnabled) { Log.Info("Controller: found {0} free card(s)", cardsAvailable.Count); } return(cardsAvailable); } catch (Exception ex) { result = TvResult.UnknownError; Log.Write(ex); return(null); } finally { stopwatch.Stop(); Log.Info("AdvancedCardAllocation.GetFreeCardsForChannel took {0} msec", stopwatch.ElapsedMilliseconds); } }
private void LoadFiles(string searchDirectory, TreeNode treeNode) { try { string[] files = Directory.GetFiles(searchDirectory, TbTemplateFileNames.Text); foreach (string file in files) { FileInfo fileInfo = new FileInfo(file); currentFileName = fileInfo.Name; Thread.Sleep(50); if (!string.IsNullOrEmpty(TbSymbolsInFile.Text)) { char[] symbols = TbSymbolsInFile.Text.ToCharArray(); try { FileStream fileStream = new FileStream(fileInfo.FullName, FileMode.Open); StreamReader streamReader = new StreamReader(fileStream); string fileText = streamReader.ReadToEnd(); foreach (char symbol in symbols) { if (fileText.Contains(symbol.ToString())) { treeNode = (TreeNode)TvResult.Invoke(new Func <string, TreeNode>((s) => treeNode.Nodes.Add(s)), fileInfo.Name); treeNode.Tag = fileInfo.FullName; break; } } streamReader.Close(); } catch (IOException) { } } else { treeNode = (TreeNode)TvResult.Invoke(new Func <string, TreeNode>((s) => treeNode.Nodes.Add(s)), fileInfo.Name); treeNode.Tag = fileInfo.FullName; } filesCounter++; currentFileName = string.Empty; } } catch (UnauthorizedAccessException) { filesCounter++; } }
private IUser StartTimeshifting(Channel channel, IUser user, int nextRowIndexForDiscUpdate, out long mSecsElapsed, out TvResult result, out VirtualCard card) { Stopwatch sw = Stopwatch.StartNew(); UpdateDiscontinuityCounter(user, nextRowIndexForDiscUpdate); result = RemoteControl.Instance.StartTimeShifting(ref user, channel.IdChannel, out card); mSecsElapsed = sw.ElapsedMilliseconds; _avg += mSecsElapsed; return(user); }
private static TvResult GetResultNoCards(Dictionary <int, TvResult> cardsUnAvailable) { TvResult resultNoCards = TvResult.ChannelNotMappedToAnyCard; Dictionary <int, TvResult> .ValueCollection values = cardsUnAvailable.Values; if (values.Any(tvResult => tvResult == TvResult.ChannelIsScrambled)) { resultNoCards = TvResult.ChannelIsScrambled; } return(resultNoCards); }
private bool TuneEPGgrabber(Channel channel, IChannel tuning, Card card, TvResult result) { try { _user.CardId = Card.IdCard; ITvCardHandler cardHandler; if (_tvController.CardCollection.TryGetValue(Card.IdCard, out cardHandler)) { ICardTuneReservationTicket ticket = null; try { ICardReservation cardReservationImpl = new CardReservationTimeshifting(_tvController); ticket = cardReservationImpl.RequestCardTuneReservation(cardHandler, tuning, _user, channel.IdChannel); if (ticket != null) { result = _tvController.Tune(ref _user, tuning, channel.IdChannel, ticket); if (result == TvResult.Succeeded) { if (!_isRunning || false == _tvController.GrabEpg(this, Card.IdCard)) { if (!_isRunning) { Log.Epg("Tuning finished but EpgGrabber no longer enabled"); } _tvController.StopGrabbingEpg(_user); _user.CardId = -1; Log.Epg("Epg: card:{0} could not start dvbt grabbing", Card.IdCard); return(false); } _user.CardId = Card.IdCard; return(true); } } } catch (Exception) { CardReservationHelper.CancelCardReservation(cardHandler, ticket); throw; } } _user.CardId = -1; Log.Epg("Epg: card:{0} could not tune to channel:{1}", Card.IdCard, result.ToString()); return(false); } catch (Exception ex) { Log.Write(ex); throw; } }
/// <summary> /// Start timeshifting on a specific channel /// </summary> /// <param name="user">The user.</param> /// <param name="idChannel">id of the channel</param> /// <param name="card">returns on which card timeshifting is started</param> /// <param name="forceCardId">Indicated, if the card should be forced</param> /// <returns> /// TvResult indicating whether method succeeded /// </returns> public TvResult StartTimeShifting(ref IUser user, int idChannel, out VirtualCard card, bool forceCardId) { card = null; try { TvResult result = RemoteControl.Instance.StartTimeShifting(ref user, idChannel, out card, forceCardId); return(result); } catch (Exception e) { HandleFailure("StartTimeShifting.3", e); } return(TvResult.UnknownError); }
public void GrabData(object ParamTo) { DataGrabArgs ParamToUse = (DataGrabArgs)ParamTo; int ChannelID = ParamToUse.ChannelID; int Seconds = ParamToUse.Seconds; List <int> Pids = ParamToUse.Pids; string Filename = "Custom_" + ChannelID.ToString() + ".ts"; Complete = false; TvServer server = new TvServer(); IUser user = new User(Filename, false); WantedPIDS = Pids; TvResult result = default(TvResult); //Used to start and ensure we can tune the channel result = server.StartTimeShifting(ref user, ChannelID, out _card); if ((result == TvResult.Succeeded)) { Thread.Sleep(2000); _card.StopTimeShifting(); result = server.StartTimeShiftingWithCustom(ref user, ChannelID, out _card, Filename, Pids); if ((result == TvResult.Succeeded)) { string NewFile = _card.TimeshiftFolder + "\\" + Filename; TimeStamp = DateTime.Now.AddSeconds(Seconds); ProcessPackets(NewFile); Decoders.Remove(ChannelID); } else { Decoders.Remove(ChannelID); if (OnComplete != null) { OnComplete(true, result.ToString()); } } } else { Decoders.Remove(ChannelID); if (OnComplete != null) { OnComplete(true, result.ToString()); } } }
/// <summary> /// Start timeshifting on a specific channel /// </summary> /// <param name="user">The user.</param> /// <param name="idChannel">id of the channel</param> /// <param name="card">returns on which card timeshifting is started</param> /// <param name="cardChanged">indicates if card was changed</param> /// <returns> /// TvResult indicating whether method succeeded /// </returns> public TvResult StartTimeShifting(ref IUser user, int idChannel, out VirtualCard card, out bool cardChanged) { card = null; cardChanged = false; try { TvResult result = RemoteControl.Instance.StartTimeShifting(ref user, idChannel, out card, out cardChanged); return(result); } catch (Exception) { HandleFailure(); } return(TvResult.UnknownError); }
private int GetSearchResultOrder(TvResult result, int?year) { if (year.HasValue) { DateTime r; // These dates are always in this exact format if (DateTime.TryParseExact(result.first_air_date, "yyyy-MM-dd", EnUs, DateTimeStyles.None, out r)) { // Allow one year tolernace, preserve order from Tmdb return(Math.Abs(r.Year - year.Value)); } } return(int.MaxValue); }
private void ScanForUsableChannels() { _abortScanning = false; _isScanning = true; NotifyForm dlg = new NotifyForm("Testing all checked tv channels...", "Please be patient..."); dlg.Show(this); dlg.WaitForDisplay(); // Create tunning objects Server, User and Card TvServer _server = new TvServer(); IUser _user = new User(); VirtualCard _card; foreach (ListViewItem item in mpListView1.Items) { if (item.Checked == false) { continue; // do not test "un-checked" channels } Channel _channel = (Channel)item.Tag; // get channel dlg.SetMessage( string.Format("Please be patient...\n\nTesting channel {0} ( {1} of {2} )", _channel.DisplayName, item.Index + 1, mpListView1.Items.Count)); Application.DoEvents(); TvResult result = _server.StartTimeShifting(ref _user, _channel.IdChannel, out _card); if (result == TvResult.Succeeded) { _card.StopTimeShifting(); } else { item.Checked = false; _channel.VisibleInGuide = false; _channel.Persist(); } if (_abortScanning) { break; } } mpButtonTestAvailable.Text = "Test"; dlg.Close(); _isScanning = false; _abortScanning = false; }
public static void SetCardStateBasedOnTVresult(ITvCardHandler tvcard, TvResult tvResult) { if (tvResult == TvResult.Succeeded) { SetTunedCardState(tvcard); } else if (tvResult == TvResult.NoVideoAudioDetected || tvResult == TvResult.NoPmtFound || tvResult == TvResult.ChannelIsScrambled) { SetCurrentCardState(tvcard); } else { SetFailedCardState(tvcard); } }
public TvResult CardTune(ITvCardHandler tvcard, ref IUser user, IChannel channel, Channel dbChannel, ICardTuneReservationTicket ticket) { TvResult tvResult = TvResult.AllCardsBusy; bool ticketFound; bool isTuningPending = CardReservationHelper.GetIsTuningPending(tvcard, ticket, out ticketFound); try { if (isTuningPending && ticketFound) { user.IsFreeToAir = ticket.TuningDetail.FreeToAir; Log.Debug("CardReservationBase.CardTune: tvcard={0}, user={1}, dbChannel={2}, ticket={3}, tunestate={4}, stopstate={5}, ticketFTA={6}", tvcard.DataBaseCard.IdCard, user.Name, dbChannel.IdChannel, ticket.Id, tvcard.Tuner.CardTuneState, tvcard.Tuner.CardStopState, ticket.TuningDetail.FreeToAir); tvResult = tvcard.Tuner.CardTune(ref user, channel, dbChannel); if (tvResult == TvResult.Succeeded) { if (OnStartCardTune != null) { if (!_tvController.IsTimeShifting(ref user)) { CleanTimeShiftFiles(tvcard.DataBaseCard.TimeShiftFolder, String.Format("live{0}-{1}.ts", user.CardId, user.SubChannel)); } string timeshiftFileName = String.Format(@"{0}\live{1}-{2}.ts", tvcard.DataBaseCard.TimeShiftFolder, user.CardId, user.SubChannel); tvResult = OnStartCardTune(ref user, ref timeshiftFileName); } } CardReservationHelper.SetCardStateBasedOnTVresult(tvcard, tvResult); } else // state is not tuning, some other card tune session is busy. { } } finally { CardReservationHelper.RemoveTuneTicket(tvcard, ticket, ticketFound); tvcard.Tuner.CleanUpPendingTune(ticket.PendingSubchannel); } return(tvResult); }
private void FileSearcher() { stopwatch.Restart(); DirectoryInfo directoryInfo = new DirectoryInfo(TbSearchDirectory.Text); TreeNode treeNode = (TreeNode)TvResult.Invoke(new Func <string, TreeNode>((s) => TvResult.Nodes.Add(s)), directoryInfo.Name); treeNode.Tag = directoryInfo.FullName; if (CbUserSubdirectories.Checked) { LoadSubDirectories(TbSearchDirectory.Text, treeNode); } LoadFiles(TbSearchDirectory.Text, treeNode); stopwatch.Stop(); searchStatus = "notstarted"; }
private VirtualCard SwitchTVServerToChannel(string userName, int channelId) { // validate arguments if (String.IsNullOrEmpty(userName)) { Log.Error("Called SwitchTVServerToChannel with empty userName"); return(null); } // create the user Log.Debug("Starting timeshifting with username {0} on channel id {1}", userName, channelId); IUser currentUser = new User(); currentUser.Name = userName; currentUser.IsAdmin = true; // actually start timeshifting VirtualCard tvCard; Log.Debug("Starting timeshifting"); TvResult result = _tvControl.StartTimeShifting(ref currentUser, channelId, out tvCard); Log.Trace("Tried to start timeshifting, result {0}", result); // make sure result is correct and return if (result != TvResult.Succeeded) { Log.Error("Starting timeshifting failed with result {0}", result); return(null); } Log.Debug("Timeshifting succeeded"); if (tvCard == null) { Log.Error("Couldn't get virtual card"); return(null); } return(tvCard); }
private VirtualCard SwitchTVServerToChannel(string userName, int channelId) { if (String.IsNullOrEmpty(userName)) { Log.Error("Called SwitchTVServerToChannel with empty userName"); throw new ArgumentNullException("userName"); } Log.Debug("Starting timeshifting with username {0} on channel id {1}", userName, channelId); IUser currentUser = GetUserByUserName(userName, true); VirtualCard tvCard; Log.Debug("Starting timeshifting"); TvResult result = _tvControl.StartTimeShifting(ref currentUser, channelId, out tvCard); Log.Trace("Tried to start timeshifting, result {0}", result); if (result != TvResult.Succeeded) { // TODO: should we retry? Log.Error("Starting timeshifting failed with result {0}", result); throw new Exception("Failed to start tv stream: " + result); } Log.Debug("Timeshifting succeeded"); if (tvCard == null) { Log.Error("Couldn't get virtual card"); throw new Exception("Couldn't get virtual card"); } // set card id and channel id of user, required for heartbeat and stopping of timeshifting currentUser.CardId = tvCard.Id; currentUser.IdChannel = channelId; _tvUsers[userName] = currentUser; return(tvCard); }
public new DialogResult ShowDialog(IWin32Window owner) { Text = "Preview " + _channel.DisplayName; TvServer server = new TvServer(); IUser user = new User("setuptv", false); TvResult result = server.StartTimeShifting(ref user, _channel.IdChannel, out _card); if (result != TvResult.Succeeded) { MessageBox.Show("Preview failed:" + result); Close(); return(DialogResult.None); } Log.Info("preview {0} user:{1} {2} {3} {4}", _channel.DisplayName, user.CardId, user.SubChannel, user.Name, _card.TimeShiftFileName); _player = new Player(); _player.Play(_card.TimeShiftFileName, this); return(base.ShowDialog(owner)); }
public void ShowVideo(IWin32Window owner) { Text = "Preview " + _channel.DisplayName; TvServer server = new TvServer(); IUser user = UserFactory.CreateBasicUser("setuptv"); TvResult result = server.StartTimeShifting(ref user, _channel.IdChannel, out _card); if (result != TvResult.Succeeded) { MessageBox.Show("Preview failed:" + result); Close(); throw new Exception(result.ToString()); } Log.Info("preview {0} user:{1} {2} {3} {4}", _channel.DisplayName, user.CardId, user.SubChannel, user.Name, _card.TimeShiftFileName); _player = new Player(); _player.Play(_card.TimeShiftFileName, this); this.Show(owner); }
public IList<CardDetail> UpdateFreeCardsForChannelBasedOnTicket(ICollection<CardDetail> cardsAvailable, IUser user, out TvResult result) { var cardetails = new List<CardDetail>(); foreach (CardDetail cardDetail in cardsAvailable) { ICardTuneReservationTicket ticket = GetCardTuneReservationTicket(cardDetail.Card.IdCard); if (ticket != null) { cardDetail.SameTransponder = ticket.IsSameTransponder; cardDetail.NumberOfOtherUsers = ticket.NumberOfOtherUsersOnCurrentCard; LogNumberOfOtherUsersFound(cardDetail); IDictionary<int, ITvCardHandler> cards = _controller.CardCollection; IChannel tuningDetail = cardDetail.TuningDetail; bool checkTransponder = CheckTransponder(user, cards[cardDetail.Card.IdCard], tuningDetail); if (checkTransponder) cardetails.Add(cardDetail); } } cardetails.SortStable(); if (cardetails.Count > 0) { result = TvResult.Succeeded; } else { result = cardsAvailable.Count == 0 ? TvResult.ChannelNotMappedToAnyCard : TvResult.AllCardsBusy; } return cardetails; }
/// <summary> /// Gets a list of all free cards which can receive the channel specified /// List is sorted. /// </summary> /// <returns>list containg all free cards which can receive the channel</returns> public List<CardDetail> GetFreeCardsForChannel(IDictionary<int, ITvCardHandler> cards, Channel dbChannel, ref IUser user, out TvResult result) { Stopwatch stopwatch = Stopwatch.StartNew(); try { //Log.Info("GetFreeCardsForChannel st {0}", Environment.StackTrace); //construct list of all cards we can use to tune to the new channel if (LogEnabled) { Log.Info("Controller: find free card for channel {0}", dbChannel.DisplayName); } var cardsAvailable = new List<CardDetail>(); IDictionary<int, TvResult> cardsUnAvailable; List<CardDetail> cardDetails = GetAvailableCardsForChannel(cards, dbChannel, ref user, out cardsUnAvailable); foreach (CardDetail cardDetail in cardDetails) { ITvCardHandler tvCardHandler = cards[cardDetail.Card.IdCard]; bool checkTransponder = CheckTransponder(user, tvCardHandler, cardDetail.TuningDetail); if (checkTransponder) { cardsAvailable.Add(cardDetail); } } //sort cards cardsAvailable.SortStable(); if (cardsAvailable.Count > 0) { result = TvResult.Succeeded; } else { TvResult resultNoCards = GetResultNoCards(cardsUnAvailable); result = cardDetails.Count == 0 ? resultNoCards : TvResult.AllCardsBusy; } if (LogEnabled) { Log.Info("Controller: found {0} free card(s)", cardsAvailable.Count); } return cardsAvailable; } catch (Exception ex) { result = TvResult.UnknownError; Log.Write(ex); return null; } finally { stopwatch.Stop(); Log.Info("AdvancedCardAllocation.GetFreeCardsForChannel took {0} msec", stopwatch.ElapsedMilliseconds); } }
private static void AddCardUnAvailable(ref IDictionary<int, TvResult> cardsUnAvailable, int cardId, TvResult tvResult) { if (!cardsUnAvailable.ContainsKey(cardId)) { cardsUnAvailable.Add(cardId, tvResult); } }
/// <summary> /// Start timeshifting. /// </summary> /// <param name="user">User</param> /// <param name="fileName">Name of the timeshiftfile.</param> /// <returns>TvResult indicating whether method succeeded</returns> public TvResult Start(ref IUser user, ref string fileName) { TvResult result = TvResult.UnknownError; try { #if DEBUG if (File.Exists(@"\failts_" + _cardHandler.DataBaseCard.IdCard)) { throw new Exception("failed ts on purpose"); } #endif if (IsTuneCancelled()) { result = TvResult.TuneCancelled; return(result); } _eventTimeshift.Reset(); if (_cardHandler.DataBaseCard.Enabled) { // Let's verify if hard disk drive has enough free space before we start time shifting. The function automatically handles both local and UNC paths if (!IsTimeShifting(ref user) && !HasFreeDiskSpace(fileName)) { result = TvResult.NoFreeDiskSpace; } else { Log.Write("card: StartTimeShifting {0} {1} ", _cardHandler.DataBaseCard.IdCard, fileName); var context = _cardHandler.Card.Context as ITvCardContext; if (context != null) { context.GetUser(ref user); ITvSubChannel subchannel = GetSubChannel(user.SubChannel); if (subchannel != null) { _subchannel = subchannel; Log.Write("card: CAM enabled : {0}", _cardHandler.HasCA); AttachAudioVideoEventHandler(subchannel); if (subchannel.IsTimeShifting) { result = GetTvResultFromTimeshiftingSubchannel(ref user, context); } else { bool tsStarted = subchannel.StartTimeShifting(fileName); if (tsStarted) { fileName += ".tsbuffer"; result = GetTvResultFromTimeshiftingSubchannel(ref user, context); } else { result = TvResult.UnableToStartGraph; } } } } } } else { result = TvResult.CardIsDisabled; } } catch (Exception ex) { Log.Write(ex); result = TvResult.UnknownError; } finally { _eventTimeshift.Set(); _cancelled = false; if (result != TvResult.Succeeded) { Stop(ref user); } } return(result); }
/** * \brief timeshift a channel and get the stream url * \param OriginalURL is the URL given to us by the TVServer * \return value is the URL with resolved hostnames, */ public static String playChannel(int chanId, bool resolveHostnames, ref string OriginalURL, ref TvControl.IUser me, ref string timeShiftFileName, ref Int64 timeShiftBufPos, ref long timeShiftBufNr) { string rtspURL = ""; string remoteserver = ""; //serverIntf.StopTimeShifting(ref me); timeshiftChannel.Remove(me.Name); TvResult result = serverIntf.StartTimeShifting(chanId, ref rtspURL, ref remoteserver, ref me, ref timeShiftFileName, ref timeShiftBufPos, ref timeShiftBufNr); if (result != TvResult.Succeeded) { rtspURL = "[ERROR]: TVServer answer: " + result.ToString() + "|" + (int)result; } else { // we resolve any host names, as xbox can't do NETBIOS resolution.. try { //Workaround for MP TVserver bug when using default port for rtsp => returns rtsp://ip:0 rtspURL = rtspURL.Replace(":554", ""); rtspURL = rtspURL.Replace(":0", ""); OriginalURL = rtspURL; if (resolveHostnames) { Uri u = new Uri(rtspURL); IPAddress ipaddr = null; try { ipaddr = IPAddress.Parse(u.DnsSafeHost); //Fails on a hostname } catch { } if ((ipaddr == null) || (ipaddr.IsIPv6LinkLocal || ipaddr.IsIPv6Multicast || ipaddr.IsIPv6SiteLocal)) { try { IPHostEntry hostEntry = System.Net.Dns.GetHostEntry(u.DnsSafeHost); string newHost = ""; foreach (IPAddress ipaddr2 in hostEntry.AddressList) { // we only want ipv4.. this is just the xbox after all if (ipaddr2.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6) { newHost = ipaddr2.ToString(); break; } } rtspURL = u.AbsoluteUri.Replace(u.Scheme + "://" + u.Host + "/", u.Scheme + "://" + newHost + "/"); if (newHost.Length == 0) { Log.Debug("TVServerKodi: No IPv4 adress found for '" + u.DnsSafeHost + "' failed. Returning original URL."); Console.WriteLine("No IPv4 adress found for '" + u.DnsSafeHost + "' failed. Returning original URL."); } } catch (Exception ex) { Console.WriteLine("IP resolve for '" + u.DnsSafeHost + "' failed."); Console.WriteLine("Error: " + ex.ToString()); Log.Debug("TVServerKodi: IP resolve for '" + u.DnsSafeHost + "' failed."); Log.Debug("TVServerKodi: Error: " + ex.ToString()); } } } } catch { //Console.WriteLine("IP resolve failed"); } // update globals timeshiftUrl = rtspURL; timeshiftChannel.Add(me.Name, chanId); } Log.Debug("TVServerKodi: PlayChannel " + chanId.ToString() + " => URL=" + rtspURL); //Console.WriteLine("PlayChannel result : " + rtspURL); return(rtspURL); }
private int GetSearchResultOrder(TvResult result, int? year) { if (year.HasValue) { DateTime r; // These dates are always in this exact format if (DateTime.TryParseExact(result.first_air_date, "yyyy-MM-dd", EnUs, DateTimeStyles.None, out r)) { // Allow one year tolernace, preserve order from Tmdb return Math.Abs(r.Year - year.Value); } } return int.MaxValue; }
private bool BeforeTune(IChannel channel, ref IUser user, out TvResult result) { result = TvResult.UnknownError; //@FIX this fails for back-2-back recordings //if (CurrentDbChannel(ref user) == idChannel && idChannel >= 0) //{ // return true; //} Log.Debug("card: user: {0}:{1}:{2} tune {3}", user.Name, user.CardId, user.SubChannel, channel.ToString()); _cardHandler.Card.CamType = (CamType)_cardHandler.DataBaseCard.CamType; _cardHandler.SetParameters(); //check if transponder differs ITvCardContext context = _cardHandler.Card.Context as ITvCardContext; if (_cardHandler.Card.SubChannels.Length > 0) { if (IsTunedToTransponder(channel) == false) { if (context.IsOwner(user) || user.IsAdmin) { Log.Debug("card: to different transponder"); //remove all subchannels, except for this user... IUser[] users = context.Users; for (int i = 0; i < users.Length; ++i) { if (users[i].Name != user.Name) { Log.Debug(" stop subchannel: {0} user: {1}", i, users[i].Name); //fix for b2b mantis; http://mantis.team-mediaportal.com/view.php?id=1112 if (users[i].IsAdmin) // if we are stopping an on-going recording/schedule (=admin), we have to make sure that we remove the schedule also. { Log.Debug("user is scheduler: {0}", users[i].Name); int recScheduleId = RemoteControl.Instance.GetRecordingSchedule(users[i].CardId, users[i].IdChannel); if (recScheduleId > 0) { Schedule schedule = Schedule.Retrieve(recScheduleId); Log.Info("removing schedule with id: {0}", schedule.IdSchedule); RemoteControl.Instance.StopRecordingSchedule(schedule.IdSchedule); schedule.Delete(); } } else { _cardHandler.Card.FreeSubChannel(users[i].SubChannel); context.Remove(users[i]); } } } } else { Log.Debug("card: user: {0} is not the card owner. Cannot switch transponder", user.Name); result = TvResult.NotTheOwner; return(false); } } else // same transponder, free previous subchannel before tuning.. { _cardHandler.Card.FreeSubChannel(user.SubChannel); } } if (OnBeforeTuneEvent != null) { OnBeforeTuneEvent(_cardHandler); } TvCardBase card = _cardHandler.Card as TvCardBase; if (card != null) { card.AfterTuneEvent -= new TvCardBase.OnAfterTuneDelegate(Card_OnAfterTuneEvent); card.AfterTuneEvent += new TvCardBase.OnAfterTuneDelegate(Card_OnAfterTuneEvent); } else { HybridCard hybridCard = _cardHandler.Card as HybridCard; if (hybridCard != null) { hybridCard.AfterTuneEvent = new TvCardBase.OnAfterTuneDelegate(Card_OnAfterTuneEvent); } } result = TvResult.Succeeded; return(true); }
private string GetErrMsgFromTVResult(TvResult result) { string err = ""; switch (result) { case TvResult.NoPmtFound: err = "No PMT found"; break; case TvResult.NoSignalDetected: err = "No signal"; break; case TvResult.CardIsDisabled: err = "Card is not enabled"; break; case TvResult.AllCardsBusy: err = "All cards are busy"; break; case TvResult.ChannelIsScrambled: err = "Channel is scrambled"; break; case TvResult.NoVideoAudioDetected: err = "No Video/Audio detected"; break; case TvResult.UnableToStartGraph: err = "Unable to create/start graph"; break; case TvResult.ChannelNotMappedToAnyCard: err = "Channel is not mapped to any card"; break; case TvResult.NoTuningDetails: err = "No tuning information available for this channel"; break; case TvResult.UnknownChannel: err = "Unknown channel"; break; case TvResult.UnknownError: err = "Unknown error occured"; break; case TvResult.ConnectionToSlaveFailed: err = "Cannot connect to slave server"; break; case TvResult.NotTheOwner: err = "Failed since card is in use and we are not the owner"; break; case TvResult.GraphBuildingFailed: err = "Unable to create graph"; break; case TvResult.SWEncoderMissing: err = "No suppported software encoder installed"; break; case TvResult.NoFreeDiskSpace: err = "No free disk space"; break; } return(err); }
private bool BeforeTune(IChannel channel, ref IUser user, out TvResult result) { result = TvResult.UnknownError; //@FIX this fails for back-2-back recordings //if (CurrentDbChannel(ref user) == idChannel && idChannel >= 0) //{ // return true; //} Log.Debug("card: user: {0}:{1}:{2} tune {3}", user.Name, user.CardId, user.SubChannel, channel.ToString()); _cardHandler.Card.CamType = (CamType)_cardHandler.DataBaseCard.CamType; _cardHandler.SetParameters(); //check if transponder differs ITvCardContext context = _cardHandler.Card.Context as ITvCardContext; if (_cardHandler.Card.SubChannels.Length > 0) { if (IsTunedToTransponder(channel) == false) { if (context.IsOwner(user) || user.IsAdmin) { Log.Debug("card: to different transponder"); //remove all subchannels, except for this user... IUser[] users = context.Users; for (int i = 0; i < users.Length; ++i) { if (users[i].Name != user.Name) { Log.Debug(" stop subchannel: {0} user: {1}", i, users[i].Name); //fix for b2b mantis; http://mantis.team-mediaportal.com/view.php?id=1112 if (users[i].IsAdmin) // if we are stopping an on-going recording/schedule (=admin), we have to make sure that we remove the schedule also. { Log.Debug("user is scheduler: {0}", users[i].Name); int recScheduleId = RemoteControl.Instance.GetRecordingSchedule(users[i].CardId, users[i].IdChannel); if (recScheduleId > 0) { Schedule schedule = Schedule.Retrieve(recScheduleId); Log.Info("removing schedule with id: {0}", schedule.IdSchedule); RemoteControl.Instance.StopRecordingSchedule(schedule.IdSchedule); schedule.Delete(); } } else { _cardHandler.Card.FreeSubChannel(users[i].SubChannel); context.Remove(users[i]); } } } } else { Log.Debug("card: user: {0} is not the card owner. Cannot switch transponder", user.Name); result = TvResult.NotTheOwner; return false; } } else // same transponder, free previous subchannel before tuning.. { _cardHandler.Card.FreeSubChannel(user.SubChannel); } } if (OnBeforeTuneEvent != null) { OnBeforeTuneEvent(_cardHandler); } TvCardBase card = _cardHandler.Card as TvCardBase; if (card != null) { card.AfterTuneEvent -= new TvCardBase.OnAfterTuneDelegate(Card_OnAfterTuneEvent); card.AfterTuneEvent += new TvCardBase.OnAfterTuneDelegate(Card_OnAfterTuneEvent); } else { HybridCard hybridCard = _cardHandler.Card as HybridCard; if (hybridCard != null) { hybridCard.AfterTuneEvent = new TvCardBase.OnAfterTuneDelegate(Card_OnAfterTuneEvent); } } result = TvResult.Succeeded; return true; }
/// <summary> /// Gets a list of all free cards which can receive the channel specified /// List is sorted. /// </summary> /// <returns>list containg all free cards which can receive the channel</returns> public List <CardDetail> GetFreeCardsForChannel(IDictionary <int, ITvCardHandler> cards, Channel dbChannel, ref IUser user, out TvResult result) { Stopwatch stopwatch = Stopwatch.StartNew(); try { //Log.Info("GetFreeCardsForChannel st {0}", Environment.StackTrace); //construct list of all cards we can use to tune to the new channel Log.Debug("GetFreeCardsForChannel {0}", dbChannel.DisplayName); IDictionary <int, TvResult> cardsUnAvailable; List <CardDetail> cardDetails = GetAvailableCardsForChannel(cards, dbChannel, ref user, out cardsUnAvailable); if (IsStatic()) { //Just return the already sorted 'cardDetails' list as CheckTransponder() is overridden in 'AdvancedCardAllocationStatic.cs' if (cardDetails.Count > 0) { result = TvResult.Succeeded; } else { result = GetResultNoCards(cardsUnAvailable); } Log.Info("GetFreeCardsForChannel found {0} available card(s), channel: {1}, user:{2}", cardDetails.Count, dbChannel.DisplayName, user.Name); return(cardDetails); } var cardsFree = new List <CardDetail>(); bool currLogEn = LogEnabled; LogEnabled = false; foreach (CardDetail cardDetail in cardDetails) { ITvCardHandler tvCardHandler = cards[cardDetail.Card.IdCard]; for (int i = 0; i <= 2; i++) { // Try up to 3 times with increasing user priority level bool checkTransponder = CheckTransponder(user, tvCardHandler, cardDetail.TuningDetail, i); if (i == 0) { cardDetail.SameTranspCAMavail = checkTransponder; } if (checkTransponder) { //Log.Debug("GetFreeCardsForChannel, add card, id:{0}, level:{1}, checkTransponder:{2}",cardDetail.Id, i, checkTransponder); cardDetail.TransponderCheckLevel = i; cardsFree.Add(cardDetail); break; } } } LogEnabled = currLogEn; //Sort the list so that the 'most preferred' Card Details are at the front (see 'CardDetail.cs' for sort order) cardsFree.SortStable(); if (cardsFree.Count > 0) { result = TvResult.Succeeded; } else { TvResult resultNoCards = GetResultNoCards(cardsUnAvailable); result = cardDetails.Count == 0 ? resultNoCards : TvResult.AllCardsBusy; } Log.Info("GetFreeCardsForChannel found {0} free card(s), channel: {1}, user:{2}", cardsFree.Count, dbChannel.DisplayName, user.Name); for (int i = 0; i < cardsFree.Count; i++) { Log.Debug("GetFreeCardsForChannel, free card:{0}, id:{1}, STCA:{2}, ST:{3}, PRI:{4}, CL:{5}, NOU:{6}", i, cardsFree[i].Id, cardsFree[i].SameTranspCAMavail, cardsFree[i].SameTransponder, cardsFree[i].Priority, cardsFree[i].TransponderCheckLevel, cardsFree[i].NumberOfOtherUsers); } return(cardsFree); } catch (Exception ex) { result = TvResult.UnknownError; Log.Write(ex); return(null); } finally { stopwatch.Stop(); Log.Debug("GetFreeCardsForChannel took {0} msec", stopwatch.ElapsedMilliseconds); } }
/// <summary> /// This method will try to start the epg grabber for the channel and tuning details specified /// Epg grabbing can only be started if there is a card idle which can receive the channel specified /// </summary> /// <param name="channel">channel to grab/param> /// <param name="tuning">tuning information</param> /// <param name="card">card to use for grabbing</param> /// <returns>true if grabbing has started else false</returns> private bool GrabEpgForChannel(Channel channel, IChannel tuning, Card card) { if (channel == null) { Log.Error("Epg: invalid channel"); return(false); } if (tuning == null) { Log.Error("Epg: invalid tuning"); return(false); } if (card == null) { Log.Error("Epg: invalid card"); return(false); } if (_tvController == null) { Log.Error("Epg: invalid tvcontroller"); return(false); } if (_user == null) { Log.Error("Epg: invalid user"); return(false); } //remove following check to enable multi-card epg grabbing (still beta) if (_tvController.AllCardsIdle == false) { Log.Epg("Epg: card:{0} cards are not idle", Card.IdCard); return(false); } TvResult result = TvResult.UnknownError; //handle ATSC ATSCChannel atscChannel = tuning as ATSCChannel; if (atscChannel != null) { if (_tvController.Type(Card.IdCard) == CardType.Atsc) { if (IsCardIdle(Card.IdCard) == false) { Log.Epg("Epg: card:{0} atsc card is not idle", Card.IdCard); return(false); //card is busy } return(TuneEPGgrabber(channel, tuning, card, result)); } Log.Epg("Epg: card:{0} could not tune to atsc channel:{1}", Card.IdCard, tuning.ToString()); return(false); } //handle DVBC DVBCChannel dvbcChannel = tuning as DVBCChannel; if (dvbcChannel != null) { if (_tvController.Type(Card.IdCard) == CardType.DvbC) { if (IsCardIdle(Card.IdCard) == false) { Log.Epg("Epg: card:{0} dvbc card is not idle", Card.IdCard); return(false); //card is busy } return(TuneEPGgrabber(channel, tuning, card, result)); } Log.Epg("Epg: card:{0} could not tune to dvbc channel:{1}", Card.IdCard, tuning.ToString()); return(false); } //handle DVBS DVBSChannel dvbsChannel = tuning as DVBSChannel; if (dvbsChannel != null) { if (_tvController.Type(Card.IdCard) == CardType.DvbS) { if (IsCardIdle(Card.IdCard) == false) { Log.Epg("Epg: card:{0} dvbs card is not idle", Card.IdCard); return(false); //card is busy } return(TuneEPGgrabber(channel, tuning, card, result)); } Log.Epg("Epg: card:{0} could not tune to dvbs channel:{1}", Card.IdCard, tuning.ToString()); return(false); } //handle DVBT DVBTChannel dvbtChannel = tuning as DVBTChannel; if (dvbtChannel != null) { if (_tvController.Type(Card.IdCard) == CardType.DvbT) { if (IsCardIdle(Card.IdCard) == false) { Log.Epg("Epg: card:{0} dvbt card is not idle", Card.IdCard); return(false); //card is busy } return(TuneEPGgrabber(channel, tuning, card, result)); } Log.Epg("Epg: card:{0} could not tune to dvbt channel:{1}", Card.IdCard, tuning.ToString()); return(false); } //handle DVBIP DVBIPChannel dvbipChannel = tuning as DVBIPChannel; if (dvbipChannel != null) { if (_tvController.Type(Card.IdCard) == CardType.DvbIP) { if (IsCardIdle(Card.IdCard) == false) { Log.Epg("Epg: card:{0} dvbip card is not idle", Card.IdCard); return(false); //card is busy } return(TuneEPGgrabber(channel, tuning, card, result)); } else { Log.Epg("Epg: card:{0} could not tune to dvbip channel:{1}", Card.IdCard, tuning.ToString()); } return(false); } Log.Epg("Epg: card:{0} could not tune to channel:{1}", Card.IdCard, tuning.ToString()); return(false); }
/// <summary> /// Scans the the specified card to the channel. /// </summary> /// <param name="user">User</param> /// <param name="channel">The channel.</param> /// <param name="idChannel">The channel id</param> /// <returns></returns> public TvResult Scan(ref IUser user, IChannel channel, int idChannel) { ITvSubChannel result = null; try { if (_cardHandler.DataBaseCard.Enabled == false) { return(TvResult.CardIsDisabled); } Log.Info("card: Scan {0} to {1}", _cardHandler.DataBaseCard.IdCard, channel.Name); // fix mantis 0002776: Code locking in cardtuner can cause hangs //lock (this) { if (_cardHandler.IsLocal == false) { try { RemoteControl.HostName = _cardHandler.DataBaseCard.ReferencedServer().HostName; return(RemoteControl.Instance.Scan(ref user, channel, idChannel)); } catch (Exception) { Log.Error("card: unable to connect to slave controller at: {0}", _cardHandler.DataBaseCard.ReferencedServer().HostName); return(TvResult.ConnectionToSlaveFailed); } } TvResult tvResult = TvResult.UnknownError; if (!BeforeTune(channel, ref user, out tvResult)) { return(tvResult); } result = _cardHandler.Card.Scan(user.SubChannel, channel); if (result != null) { return(AfterTune(user, idChannel, result)); } else { return(TvResult.UnknownError); } } } catch (TvExceptionNoSignal) { if (result != null) { _cardHandler.Card.FreeSubChannel(result.SubChannelId); } return(TvResult.NoSignalDetected); } catch (TvExceptionSWEncoderMissing ex) { Log.Write(ex); if (result != null) { _cardHandler.Card.FreeSubChannel(result.SubChannelId); } return(TvResult.SWEncoderMissing); } catch (TvExceptionGraphBuildingFailed ex2) { Log.Write(ex2); if (result != null) { _cardHandler.Card.FreeSubChannel(result.SubChannelId); } return(TvResult.GraphBuildingFailed); } catch (TvExceptionNoPMT) { if (result != null) { _cardHandler.Card.FreeSubChannel(result.SubChannelId); } return(TvResult.NoPmtFound); } catch (Exception ex) { Log.Write(ex); if (result != null) { _cardHandler.Card.FreeSubChannel(result.SubChannelId); } return(TvResult.UnknownError); } }
private static void ChannelTuneFailedNotifyUser(TvResult succeeded, bool wasPlaying, Channel channel) { GUIGraphicsContext.RenderBlackImage = false; _lastError.Result = succeeded; _lastError.FailingChannel = channel; _lastError.Messages.Clear(); int TextID = 0; _lastError.Messages.Add(GUILocalizeStrings.Get(1500)); switch (succeeded) { case TvResult.NoPmtFound: TextID = 1498; break; case TvResult.NoSignalDetected: TextID = 1499; break; case TvResult.CardIsDisabled: TextID = 1501; break; case TvResult.AllCardsBusy: TextID = 1502; break; case TvResult.ChannelIsScrambled: TextID = 1503; break; case TvResult.NoVideoAudioDetected: TextID = 1504; break; case TvResult.UnableToStartGraph: TextID = 1505; break; case TvResult.TuneCancelled: TextID = 1524; break; case TvResult.UnknownError: // this error can also happen if we have no connection to the server. if (!Connected) // || !IsRemotingConnected()) { TextID = 1510; } else { TextID = 1506; } break; case TvResult.UnknownChannel: TextID = 1507; break; case TvResult.ChannelNotMappedToAnyCard: TextID = 1508; break; case TvResult.NoTuningDetails: TextID = 1509; break; case TvResult.GraphBuildingFailed: TextID = 1518; break; case TvResult.SWEncoderMissing: TextID = 1519; break; case TvResult.NoFreeDiskSpace: TextID = 1520; break; default: // this error can also happen if we have no connection to the server. if (!Connected) // || !IsRemotingConnected()) { TextID = 1510; } else { TextID = 1506; } break; } if (TextID != 0) { _lastError.Messages.Add(GUILocalizeStrings.Get(TextID)); } GUIDialogNotify pDlgNotify = (GUIDialogNotify)GUIWindowManager.GetWindow((int)Window.WINDOW_DIALOG_NOTIFY); string caption = GUILocalizeStrings.Get(605) + " - " + _lastError.FailingChannel.DisplayName; pDlgNotify.SetHeading(caption); //my tv pDlgNotify.SetImage(TVUtil.GetChannelLogo(_lastError.FailingChannel)); StringBuilder sbMessage = new StringBuilder(); // ignore the "unable to start timeshift" line to avoid scrolling, because NotifyDLG has very few space available. for (int idx = 1; idx < _lastError.Messages.Count; idx++) { sbMessage.AppendFormat("\n{0}", _lastError.Messages[idx]); } pDlgNotify.SetText(sbMessage.ToString()); // Fullscreen shows the TVZapOSD to handle error messages if (GUIWindowManager.ActiveWindow == (int)(int)Window.WINDOW_TVFULLSCREEN) { // If failed and wasPlaying TV, left screen as it is and show osd with error message Log.Info("send message to fullscreen tv"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_TV_ERROR_NOTIFY, GUIWindowManager.ActiveWindow, 0, 0, 0, 0, null); msg.SendToTargetWindow = true; msg.TargetWindowId = (int)(int)Window.WINDOW_TVFULLSCREEN; msg.Object = _lastError; // forward error info object msg.Param1 = 3; // sec timeout GUIGraphicsContext.SendMessage(msg); return; } else { // show notify dialog pDlgNotify.DoModal((int)GUIWindowManager.ActiveWindowEx); } }
private bool TuneEPGgrabber(Channel channel, IChannel tuning, Card card, TvResult result) { try { _user.CardId = card.IdCard; ITvCardHandler cardHandler; if (_tvController.CardCollection.TryGetValue(card.IdCard, out cardHandler)) { ICardTuneReservationTicket ticket = null; try { ICardReservation cardReservationImpl = new CardReservationTimeshifting(_tvController); ticket = cardReservationImpl.RequestCardTuneReservation(cardHandler, tuning, _user); if (ticket != null) { result = _tvController.Tune(ref _user, tuning, channel.IdChannel, ticket); if (result == TvResult.Succeeded) { if (!_isRunning || false == _tvController.GrabEpg(this, card.IdCard)) { if (!_isRunning) Log.Epg("Tuning finished but EpgGrabber no longer enabled"); _tvController.StopGrabbingEpg(_user); _user.CardId = -1; Log.Epg("Epg: card:{0} could not start dvbt grabbing", card.IdCard); return false; } _user.CardId = card.IdCard; return true; } } } catch (Exception) { CardReservationHelper.CancelCardReservation(cardHandler, ticket); throw; } } _user.CardId = -1; Log.Epg("Epg: card:{0} could not tune to channel:{1}", card.IdCard, result.ToString()); return false; } catch (Exception ex) { Log.Write(ex); throw; } }
private static void AddCardUnAvailable(ref Dictionary <int, TvResult> cardsUnAvailable, int cardId, TvResult tvResult) { if (!cardsUnAvailable.ContainsKey(cardId)) { cardsUnAvailable.Add(cardId, tvResult); } }