/// <summary> /// Tunes to a new channel /// </summary> /// <param name="channel"></param> /// <returns></returns> public static bool ViewChannelAndCheck(Channel channel) { bool checkResult; bool doContinue; if (!Connected) { return false; } _status.Clear(); _doingChannelChange = false; try { checkResult = PreTuneChecks(channel, out doContinue); if (doContinue == false) return checkResult; _doingChannelChange = true; TvResult succeeded; IUser user = new User(); if (Card != null) { user.CardId = Card.Id; } if ((g_Player.Playing && g_Player.IsTimeShifting && !g_Player.Stopped) && (g_Player.IsTV || g_Player.IsRadio)) { _status.Set(LiveTvStatus.WasPlaying); } //Start timeshifting the new tv channel TvServer server = new TvServer(); VirtualCard card; int newCardId = -1; // check which card will be used newCardId = server.TimeShiftingWouldUseCard(ref user, channel.IdChannel); //Added by joboehl - If any major related to the timeshifting changed during the start, restart the player. if (newCardId != -1 && Card.Id != newCardId) { _status.Set(LiveTvStatus.CardChange); RegisterCiMenu(newCardId); } // we need to stop player HERE if card has changed. if (_status.AllSet(LiveTvStatus.WasPlaying | LiveTvStatus.CardChange)) { Log.Debug("TVHome.ViewChannelAndCheck(): Stopping player. CardId:{0}/{1}, RTSP:{2}", Card.Id, newCardId, Card.RTSPUrl); Log.Debug("TVHome.ViewChannelAndCheck(): Stopping player. Timeshifting:{0}", Card.TimeShiftFileName); Log.Debug("TVHome.ViewChannelAndCheck(): rebuilding graph (card changed) - timeshifting continueing."); } if (_status.IsSet(LiveTvStatus.WasPlaying)) { RenderBlackImage(); g_Player.PauseGraph(); } else { // if CI menu is not attached due to card change, do it if graph was not playing // (some handlers use polling threads that get stopped on graph stop) if (_status.IsNotSet(LiveTvStatus.CardChange)) RegisterCiMenu(newCardId); } // if card was not changed if (_status.IsNotSet(LiveTvStatus.CardChange)) { g_Player.OnZapping(0x80); // Setup Zapping for TsReader, requesting new PAT from stream } bool cardChanged = false; succeeded = server.StartTimeShifting(ref user, channel.IdChannel, out card, out cardChanged); if (_status.IsSet(LiveTvStatus.WasPlaying)) { if (card != null) g_Player.OnZapping((int)card.Type); else g_Player.OnZapping(-1); } if (succeeded != TvResult.Succeeded) { //timeshifting new channel failed. g_Player.Stop(); // ensure right channel name, even if not watchable:Navigator.Channel = channel; ChannelTuneFailedNotifyUser(succeeded, _status.IsSet(LiveTvStatus.WasPlaying), channel); _doingChannelChange = true; // keep fullscreen false; return true; // "success" } if (card != null && card.NrOfOtherUsersTimeshiftingOnCard > 0) { _status.Set(LiveTvStatus.SeekToEndAfterPlayback); } if (cardChanged) { _status.Set(LiveTvStatus.CardChange); if (card != null) { RegisterCiMenu(card.Id); } _status.Reset(LiveTvStatus.WasPlaying); } else { _status.Reset(LiveTvStatus.CardChange); _status.Set(LiveTvStatus.SeekToEnd); } // Update channel navigator if (Navigator.Channel != null && (channel.IdChannel != Navigator.Channel.IdChannel || (Navigator.LastViewedChannel == null))) { Navigator.LastViewedChannel = Navigator.Channel; } Log.Info("succeeded:{0} {1}", succeeded, card); Card = card; //Moved by joboehl - Only touch the card if starttimeshifting succeeded. // if needed seek to end if (_status.IsSet(LiveTvStatus.SeekToEnd)) { SeekToEnd(true); } // continue graph g_Player.ContinueGraph(); if (!g_Player.Playing || _status.IsSet(LiveTvStatus.CardChange) || (g_Player.Playing && !(g_Player.IsTV || g_Player.IsRadio))) { StartPlay(); // if needed seek to end if (_status.IsSet(LiveTvStatus.SeekToEndAfterPlayback)) { double dTime = g_Player.Duration - 5; g_Player.SeekAbsolute(dTime); } } _playbackStopped = false; _doingChannelChange = false; _ServerNotConnectedHandled = false; return true; } catch (Exception ex) { Log.Debug("TvPlugin:ViewChannelandCheckV2 Exception {0}", ex.ToString()); _doingChannelChange = false; Card.User.Name = new User().Name; g_Player.Stop(); Card.StopTimeShifting(); return false; } finally { StopRenderBlackImage(); _userChannelChanged = false; FireOnChannelChangedEvent(); Navigator.UpdateCurrentChannel(); } }