public TvNotifyManager() { using (Settings xmlreader = new MPSettings()) { _enableRecNotification = xmlreader.GetValueAsBool("mytv", "enableRecNotifier", false); _preNotifyConfig = xmlreader.GetValueAsInt("mytv", "notifyTVBefore", 300); } _busy = false; _timer = new Timer(); _timer.Stop(); // check every 15 seconds for notifies _dummyuser = new User(); _dummyuser.IsAdmin = false; _dummyuser.Name = "Free channel checker"; _timer.Interval = 15000; _timer.Enabled = true; // Execute TvNotifyManager in a separate thread, so that it doesn't block the Main UI Render thread when Tvservice connection died new Thread(() => { _timer.Tick += new EventHandler(_timer_Tick); } ) {Name = "TvNotifyManager"}.Start(); _notifiedRecordings = new ArrayList(); }
public static bool StopTimeshift(ref TvControl.User me) { bool result = serverIntf.StopTimeShifting(ref me); timeshiftUrl = null; return(result); }
public bool Connect(string hostname) { try { string connStr; string provider; if (!GetDatabaseConnectionString(out connStr, out provider)) return false; RemoteControl.HostName = hostname; Gentle.Framework.ProviderFactory.SetDefaultProviderConnectionString(connStr); me = new User(); me.IsAdmin = true; groups = ChannelGroup.ListAll(); radioGroups = RadioChannelGroup.ListAll(); channels = Channel.ListAll(); mappings = GroupMap.ListAll(); cards = Card.ListAll(); } catch (Exception ex) { lastException = ex; RemoteControl.Clear(); return false; } return true; }
/// <summary> /// Initializes a new instance of the <see cref="VirtualCard"/> class. /// </summary> /// <param name="user">The user.</param> /// <param name="server">The server.</param> /// <param name="recordingFormat">The recording format.</param> public VirtualCard(User user, string server, int recordingFormat) { _user = user; _server = server; _recordingFolder = String.Format(@"{0}\Team MediaPortal\MediaPortal TV Server\recordings", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); _recordingFormat = recordingFormat; }
public void AddUserOwnerTest() { ITvCardContext ctx = new TvCardContext(); IUser u1 = new User("u1", false, 1); ctx.Add(u1); Assert.IsTrue(ctx.IsOwner(u1), "user is not owner"); }
public void AddNewUserTest() { ITvCardContext ctx = new TvCardContext(); IUser u1 = new User("u1", false, 1); ctx.Add(u1); Assert.IsTrue(UserExists(ctx, u1), "user is not found"); }
public void RemoveUserTest() { ITvCardContext ctx = new TvCardContext(); IUser u1 = new User("u1", false, 1); ctx.Add(u1); ctx.Remove(u1); Assert.AreEqual(0, ctx.Users.Length, "user count wrong"); Assert.IsFalse(UserExists(ctx, u1), "user is found"); Assert.IsTrue(((TvCardContext)ctx).UsersOld.Contains(u1), "user not found in history"); }
public void AddAlreadyExistingUserTest() { ITvCardContext ctx = new TvCardContext(); IUser u1 = new User("u1", false, 1); ctx.Add(u1); User u2 = new User("u1", false, 2); ctx.Add(u2); Assert.AreEqual(1, ctx.Users.Length, "user count wrong"); Assert.IsTrue(UserExists(ctx, u2), "user is not found"); }
public void AddAnotherUserNotOwnerTest() { ITvCardContext ctx = new TvCardContext(); IUser u1 = new User("u1", false, 1); ctx.Add(u1); User u2 = new User("u2", false, 2); ctx.Add(u2); Assert.IsTrue(ctx.IsOwner(u1), "user is owner"); Assert.IsFalse(ctx.IsOwner(u2), "user is not owner"); }
public static ChannelInfo getTimeshiftInfo(ref TvControl.User me) { int channelnr = 0; if (timeshiftChannel.TryGetValue(me.Name, out channelnr)) { return(serverIntf.GetChannelInfo(channelnr)); } else if (me.IdChannel > 0) { return(serverIntf.GetChannelInfo(me.IdChannel)); } return(null); }
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); }
/// <summary> /// constructor /// </summary> /// <param name="schedule">Schedule of this recording</param> /// <param name="channel">Channel on which the recording is done</param> /// <param name="endTime">Date/Time the recording should start without pre-record interval</param> /// <param name="endTime">Date/Time the recording should stop with post record interval</param> /// <param name="isSerie">Is serie recording</param> /// /// public RecordingDetail(Schedule schedule, Channel channel, DateTime endTime, bool isSerie) { _user = new User(); User.Name = string.Format("scheduler{0}", schedule.IdSchedule); User.CardId = -1; User.SubChannel = -1; User.IsAdmin = true; _schedule = schedule; _channel = channel; _endTime = endTime; _program = null; _isSerie = isSerie; DateTime startTime = DateTime.MinValue; if (isSerie) { DateTime now = DateTime.Now.AddMinutes(schedule.PreRecordInterval); startTime = new DateTime(now.Year, now.Month, now.Day, schedule.StartTime.Hour, schedule.StartTime.Minute, 0); } else { startTime = schedule.StartTime; } _program = schedule.ReferencedChannel().GetProgramAt(startTime); //no program? then treat this as a manual recording if (_program == null) { _program = new TvDatabase.Program(0, DateTime.Now, endTime, "manual", "", "", TvDatabase.Program.ProgramState.None, System.Data.SqlTypes.SqlDateTime.MinValue.Value, string.Empty, string.Empty, string.Empty, string.Empty, -1, string.Empty, 0); } }
public bool StopTimeShifting(int idChannel,int idCard,string userName) { if (!ConnectToDatabase()) return false; User user = new User(userName, false, idCard); user.IdChannel = idChannel; return RemoteControl.Instance.StopTimeShifting(ref user); }
public WebTvResult StartTimeShifting(int idChannel) { if (!ConnectToDatabase()) return new WebTvResult(); VirtualCard vcard; TvResult result; string rtspURL=""; string timeshiftFilename=""; User me = new User(System.Guid.NewGuid().ToString("B"),false); try { result = RemoteControl.Instance.StartTimeShifting(ref me, idChannel, out vcard); } catch (Exception) { return new WebTvResult(); } if (result == TvResult.Succeeded) { me.IdChannel = idChannel; me.CardId = vcard.Id; rtspURL = vcard.RTSPUrl; timeshiftFilename=vcard.TimeShiftFileName; } return new WebTvResult((int)result,rtspURL,timeshiftFilename,me); }
public void SendHeartBeat(int idChannel,int idCard,string userName) { if (!ConnectToDatabase()) return; User user = new User(userName, false, idCard); user.IdChannel = idChannel; try { RemoteControl.Instance.HeartBeat(user); } catch (Exception) { } }
public List<WebTvServerStatus> GetTvServerStatus() { List<WebTvServerStatus> states = new List<WebTvServerStatus>(); if (!ConnectToDatabase()) return states; VirtualCard vcard; try { IList<Card> cards = Card.ListAll(); foreach (Card card in cards) { User user = new User(); User[] usersForCard = null; user.CardId = card.IdCard; try { usersForCard = RemoteControl.Instance.GetUsersForCard(card.IdCard); } catch (Exception) { } if (usersForCard == null) { WebTvServerStatus state = new WebTvServerStatus(); state.recordingFolder = card.RecordingFolder; state.timeshiftFolder = card.TimeShiftFolder; vcard = new VirtualCard(user, RemoteControl.HostName); string tmp = "idle"; state.status = (int)CardStatus.Idle; if (vcard.IsScanning) { tmp = "Scanning"; state.status = (int)CardStatus.Scanning; } if (vcard.IsGrabbingEpg) { tmp = "Grabbing EPG"; state.status = (int)CardStatus.Grabbing_EPG; } state.idCard = card.IdCard; state.cardName = vcard.Name; state.cardType = (int)vcard.Type; state.cardTypeStr = vcard.Type.ToString(); state.statusStr = tmp; state.channel = ""; state.userName = ""; states.Add(state); continue; } if (usersForCard.Length == 0) { WebTvServerStatus state = new WebTvServerStatus(); state.recordingFolder = card.RecordingFolder; state.timeshiftFolder = card.TimeShiftFolder; vcard = new VirtualCard(user, RemoteControl.HostName); string tmp = "idle"; state.status = (int)CardStatus.Idle; if (vcard.IsScanning) { tmp = "Scanning"; state.status = (int)CardStatus.Scanning; } if (vcard.IsGrabbingEpg) { tmp = "Grabbing EPG"; state.status = (int)CardStatus.Grabbing_EPG; } state.idCard = card.IdCard; state.cardName = vcard.Name; state.cardType = (int)vcard.Type; state.cardTypeStr = vcard.Type.ToString(); state.statusStr = tmp; state.channel = ""; state.userName = ""; states.Add(state); continue; } for (int i = 0; i < usersForCard.Length; ++i) { WebTvServerStatus state = new WebTvServerStatus(); state.recordingFolder = card.RecordingFolder; state.timeshiftFolder = card.TimeShiftFolder; string tmp = "idle"; state.status = (int)CardStatus.Idle; vcard = new VirtualCard(usersForCard[i], RemoteControl.HostName); if (vcard.IsTimeShifting) { tmp = "Timeshifting"; state.status = (int)CardStatus.TimeShifting; } else if (vcard.IsRecording) { tmp = "Recording"; state.status = (int)CardStatus.Recording; } else if (vcard.IsScanning) { tmp = "Scanning"; state.status = (int)CardStatus.Scanning; } else if (vcard.IsGrabbingEpg) { tmp = "Grabbing EPG"; state.status = (int)CardStatus.Grabbing_EPG; } state.idCard = card.IdCard; state.cardName = vcard.Name; state.cardType = (int)vcard.Type; state.cardTypeStr = vcard.Type.ToString(); state.statusStr = tmp; state.idChannel = vcard.IdChannel; state.channel = vcard.ChannelName; state.userName = vcard.User.Name; states.Add(state); } } } catch (Exception ex) { } return states; }
/// <summary> /// Scan Thread /// </summary> private void DoScan() { suminfo tv = new suminfo(); suminfo radio = new suminfo(); IUser user = new User(); user.CardId = _cardNumber; try { scanState = ScanState.Scanning; if (_dvbcChannels.Count == 0) return; RemoteControl.Instance.EpgGrabberEnabled = false; SetButtonState(); TvBusinessLayer layer = new TvBusinessLayer(); Card card = layer.GetCardByDevicePath(RemoteControl.Instance.CardDevice(_cardNumber)); for (int index = 0; index < _dvbcChannels.Count; ++index) { if (scanState == ScanState.Cancel) return; float percent = ((float)(index)) / _dvbcChannels.Count; percent *= 100f; if (percent > 100f) percent = 100f; progressBar1.Value = (int)percent; Application.DoEvents(); DVBCChannel tuneChannel = new DVBCChannel(_dvbcChannels[index]); // new DVBCChannel(); string line = String.Format("{0}tp- {1}", 1 + index, tuneChannel.TuningInfo.ToString()); ListViewItem item = listViewStatus.Items.Add(new ListViewItem(line)); item.EnsureVisible(); if (index == 0) { RemoteControl.Instance.Scan(ref user, tuneChannel, -1); } IChannel[] channels = RemoteControl.Instance.Scan(_cardNumber, tuneChannel); UpdateStatus(); if (channels == null || channels.Length == 0) { if (RemoteControl.Instance.TunerLocked(_cardNumber) == false) { line = String.Format("{0}tp- {1} {2} {3}:No signal", 1 + index, tuneChannel.Frequency, tuneChannel.ModulationType, tuneChannel.SymbolRate); item.Text = line; item.ForeColor = Color.Red; continue; } line = String.Format("{0}tp- {1} {2} {3}:Nothing found", 1 + index, tuneChannel.Frequency, tuneChannel.ModulationType, tuneChannel.SymbolRate); item.Text = line; item.ForeColor = Color.Red; continue; } radio.newChannel = 0; radio.updChannel = 0; tv.newChannel = 0; tv.updChannel = 0; for (int i = 0; i < channels.Length; ++i) { Channel dbChannel; DVBCChannel channel = (DVBCChannel)channels[i]; bool exists; TuningDetail currentDetail; //Check if we already have this tuningdetail. The user has the option to enable channel move detection... if (checkBoxEnableChannelMoveDetection.Checked) { //According to the DVB specs ONID + SID is unique, therefore we do not need to use the TSID to identify a service. //The DVB spec recommends that the SID should not change if a service moves. This theoretically allows us to //track channel movements. currentDetail = layer.GetTuningDetail(channel.NetworkId, channel.ServiceId, TvBusinessLayer.GetChannelType(channel)); } else { //There are certain providers that do not maintain unique ONID + SID combinations. //In those cases, ONID + TSID + SID is generally unique. The consequence of using the TSID to identify //a service is that channel movement tracking won't work (each transponder/mux should have its own TSID). currentDetail = layer.GetTuningDetail(channel.NetworkId, channel.TransportId, channel.ServiceId, TvBusinessLayer.GetChannelType(channel)); } if (currentDetail == null) { //add new channel exists = false; dbChannel = layer.AddNewChannel(channel.Name); dbChannel.SortOrder = 10000; if (channel.LogicalChannelNumber >= 1) { dbChannel.SortOrder = channel.LogicalChannelNumber; } dbChannel.IsTv = channel.IsTv; dbChannel.IsRadio = channel.IsRadio; dbChannel.Persist(); } else { exists = true; dbChannel = currentDetail.ReferencedChannel(); } if (dbChannel.IsTv) { layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.AllChannels); if (checkBoxCreateSignalGroup.Checked) { layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.DVBC); } if (checkBoxCreateGroups.Checked) { layer.AddChannelToGroup(dbChannel, channel.Provider); } } if (dbChannel.IsRadio) { layer.AddChannelToRadioGroup(dbChannel, TvConstants.RadioGroupNames.AllChannels); if (checkBoxCreateSignalGroup.Checked) { layer.AddChannelToRadioGroup(dbChannel, TvConstants.RadioGroupNames.DVBC); } if (checkBoxCreateGroups.Checked) { layer.AddChannelToRadioGroup(dbChannel, channel.Provider); } } if (currentDetail == null) { layer.AddTuningDetails(dbChannel, channel); } else { //update tuning details... TuningDetail td = layer.UpdateTuningDetails(dbChannel, channel, currentDetail); td.Persist(); } if (channel.IsTv) { if (exists) { tv.updChannel++; } else { tv.newChannel++; tv.newChannels.Add(channel); } } if (channel.IsRadio) { if (exists) { radio.updChannel++; } else { radio.newChannel++; radio.newChannels.Add(channel); } } layer.MapChannelToCard(card, dbChannel, false); line = String.Format("{0}tp- {1} {2} {3}:New TV/Radio:{4}/{5} Updated TV/Radio:{6}/{7}", 1 + index, tuneChannel.Frequency, tuneChannel.ModulationType, tuneChannel.SymbolRate, tv.newChannel, radio.newChannel, tv.updChannel, radio.updChannel); item.Text = line; } tv.updChannelSum += tv.updChannel; radio.updChannelSum += radio.updChannel; } } catch (Exception ex) { Log.Write(ex); } finally { RemoteControl.Instance.StopCard(user); RemoteControl.Instance.EpgGrabberEnabled = true; progressBar1.Value = 100; scanState = ScanState.Done; SetButtonState(); } listViewStatus.Items.Add( new ListViewItem(String.Format("Total radio channels updated:{0}, new:{1}", radio.updChannelSum, radio.newChannelSum))); foreach (IChannel newChannel in radio.newChannels) { listViewStatus.Items.Add(new ListViewItem(String.Format(" -> new channel: {0}", newChannel.Name))); } listViewStatus.Items.Add( new ListViewItem(String.Format("Total tv channels updated:{0}, new:{1}", tv.updChannelSum, tv.newChannelSum))); foreach (IChannel newChannel in tv.newChannels) { listViewStatus.Items.Add(new ListViewItem(String.Format(" -> new channel: {0}", newChannel.Name))); } ListViewItem lastItem = listViewStatus.Items.Add(new ListViewItem("Scan done...")); lastItem.EnsureVisible(); }
private void DoTvScan() { int channelsNew = 0; int channelsUpdated = 0; string buttonText = mpButtonScanTv.Text; checkButton.Enabled = false; try { _isScanning = true; _stopScanning = false; mpButtonScanTv.Text = "Cancel..."; RemoteControl.Instance.EpgGrabberEnabled = false; TvBusinessLayer layer = new TvBusinessLayer(); Card card = layer.GetCardByDevicePath(RemoteControl.Instance.CardDevice(_cardNumber)); mpComboBoxCountry.Enabled = false; mpComboBoxSource.Enabled = false; mpComboBoxSensitivity.Enabled = false; checkBoxCreateSignalGroup.Enabled = false; checkBoxNoMerge.Enabled = false; mpButtonScanRadio.Enabled = false; mpButtonAddSvideoChannels.Enabled = false; mpListView1.Items.Clear(); CountryCollection countries = new CountryCollection(); IUser user = new User(); user.CardId = _cardNumber; AnalogChannel temp = new AnalogChannel(); temp.TunerSource = mpComboBoxSource.SelectedIndex == 0 ? TunerInputType.Antenna : TunerInputType.Cable; temp.VideoSource = AnalogChannel.VideoInputType.Tuner; temp.AudioSource = AnalogChannel.AudioInputType.Tuner; temp.Country = countries.Countries[mpComboBoxCountry.SelectedIndex]; temp.IsRadio = false; temp.IsTv = true; TvResult tuneResult = RemoteControl.Instance.Tune(ref user, temp, -1); if (tuneResult == TvResult.SWEncoderMissing) { Log.Error("analog: DoTvScan error (missing software encoder)"); MessageBox.Show("Please install a supported audio/video encoder for your software analog card", "Unable to scan", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (tuneResult == TvResult.GraphBuildingFailed) { Log.Error("analog: DoTvScan error (missing software encoder)"); MessageBox.Show( "The graph building. Mostly your card is not supported by TvServer. Please create a report in our forum", "Unable to scan", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (string.IsNullOrEmpty(_configuration.Graph.Capture.Name)) { _configuration = Configuration.readConfiguration(_cardNumber, _cardName, _devicePath); ReCheckSettings(); } int minChannel = RemoteControl.Instance.MinChannel(_cardNumber); int maxChannel = RemoteControl.Instance.MaxChannel(_cardNumber); if (maxChannel <= 0) { maxChannel = mpComboBoxSource.SelectedIndex == 0 ? 69 : 125; } if (minChannel < 0) minChannel = 1; Log.Info("Min channel = {0}. Max channel = {1}", minChannel, maxChannel); for (int channelNr = minChannel; channelNr <= maxChannel; channelNr++) { if (_stopScanning) return; float percent = ((float)((channelNr - minChannel)) / (maxChannel - minChannel)); percent *= 100f; if (percent > 100f) percent = 100f; if (percent < 0) percent = 0f; progressBar1.Value = (int)percent; AnalogChannel channel = new AnalogChannel(); channel.TunerSource = mpComboBoxSource.SelectedIndex == 0 ? TunerInputType.Antenna : TunerInputType.Cable; channel.Country = countries.Countries[mpComboBoxCountry.SelectedIndex]; channel.ChannelNumber = channelNr; channel.IsTv = true; channel.IsRadio = false; channel.VideoSource = AnalogChannel.VideoInputType.Tuner; channel.AudioSource = AnalogChannel.AudioInputType.Automatic; string line = String.Format("channel:{0} source:{1} ", channel.ChannelNumber, mpComboBoxSource.SelectedItem); ListViewItem item = mpListView1.Items.Add(new ListViewItem(line)); item.EnsureVisible(); IChannel[] channels = RemoteControl.Instance.Scan(_cardNumber, channel); UpdateStatus(); if (channels == null || channels.Length == 0) { if (RemoteControl.Instance.TunerLocked(_cardNumber) == false) { line = String.Format("channel:{0} source:{1} : No Signal", channel.ChannelNumber, mpComboBoxSource.SelectedItem); item.Text = line; item.ForeColor = Color.Red; continue; } line = String.Format("channel:{0} source:{1} : Nothing found", channel.ChannelNumber, mpComboBoxSource.SelectedItem); item.Text = line; item.ForeColor = Color.Red; continue; } bool exists = false; channel = (AnalogChannel)channels[0]; if (channel.Name == "") channel.Name = String.Format(channel.ChannelNumber.ToString()); Channel dbChannel = null; if (checkBoxNoMerge.Checked) { dbChannel = layer.AddNewChannel(channel.Name); } else { IList<TuningDetail> tuningDetails = layer.GetTuningDetailsByName(channel.Name, 0); if (tuningDetails != null && tuningDetails.Count > 0) { dbChannel = tuningDetails[0].ReferencedChannel(); } if (dbChannel != null) { exists = true; } else { dbChannel = layer.AddNewChannel(channel.Name); } } dbChannel.IsTv = channel.IsTv; dbChannel.IsRadio = channel.IsRadio; dbChannel.Persist(); layer.AddTuningDetails(dbChannel, channel); layer.MapChannelToCard(card, dbChannel, false); if (dbChannel.IsTv) { layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.AllChannels); if (checkBoxCreateSignalGroup.Checked) { layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.Analog); } } if (dbChannel.IsRadio) { layer.AddChannelToGroup(dbChannel, TvConstants.RadioGroupNames.AllChannels); if (checkBoxCreateSignalGroup.Checked) { layer.AddChannelToRadioGroup(dbChannel, TvConstants.RadioGroupNames.Analog); } } if (exists) { line = String.Format("channel:{0} source:{1} : Channel update found - {2}", channel.ChannelNumber, mpComboBoxSource.SelectedItem, channel.Name); channelsUpdated++; } else { line = String.Format("channel:{0} source:{1} : New channel found - {2}", channel.ChannelNumber, mpComboBoxSource.SelectedItem, channel.Name); channelsNew++; } item.Text = line; } } catch (TvExceptionSWEncoderMissing) { Log.Error("analog: DoTvScan error (missing software encoder)"); MessageBox.Show("Please install a supported audio/video encoder for your software analog card", "Unable to scan", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (TvExceptionGraphBuildingFailed) { Log.Error("analog: DoTvScan error (missing software encoder)"); MessageBox.Show( "The graph building. Mostly your card is not supported by TvServer. Please create a report in our forum", "Unable to scan", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception ex) { Log.Error("analog: DoTvScan error ({0})", ex.StackTrace); MessageBox.Show(string.Format("Generic error: {0}", ex.Message), "Unable to scan", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { IUser user = new User(); user.CardId = _cardNumber; RemoteControl.Instance.StopCard(user); RemoteControl.Instance.EpgGrabberEnabled = true; mpButtonScanTv.Text = buttonText; progressBar1.Value = 100; mpComboBoxCountry.Enabled = true; mpComboBoxSource.Enabled = true; mpComboBoxSensitivity.Enabled = true; checkBoxCreateSignalGroup.Enabled = true; checkBoxNoMerge.Enabled = true; mpButtonScanTv.Enabled = true; mpButtonScanRadio.Enabled = true; mpButtonAddSvideoChannels.Enabled = true; _isScanning = false; checkButton.Enabled = true; } ListViewItem lastItem = mpListView1.Items.Add( new ListViewItem(String.Format("Total tv channels new:{0} updated:{1}", channelsNew, channelsUpdated))); lastItem.EnsureVisible(); }
/// <summary> /// Ensures that the navigator has the correct current channel (retrieved from the Recorder). /// </summary> public void UpdateCurrentChannel() { Channel newChannel = null; //if current card is watching tv then use that channel int id; if (TVHome.Connected) { if (TVHome.Card.IsTimeShifting || TVHome.Card.IsRecording) { id = TVHome.Card.IdChannel; if (id >= 0) { newChannel = Channel.Retrieve(id); } } else { // else if any card is recording // then get & use that channel if (TVHome.IsAnyCardRecording) { TvServer server = new TvServer(); for (int i = 0; i < server.Count; ++i) { User user = new User(); VirtualCard card = server.CardByIndex(user, i); if (card.IsRecording) { id = card.IdChannel; if (id >= 0) { newChannel = Channel.Retrieve(id); break; } } } } } if (newChannel == null) { newChannel = m_currentChannel; } int currentChannelId = 0; int newChannelId = 0; if (m_currentChannel != null) { currentChannelId = m_currentChannel.IdChannel; } if (newChannel != null) { newChannelId = newChannel.IdChannel; } if (currentChannelId != newChannelId) { m_currentChannel = newChannel; m_currentChannel.CurrentGroup = CurrentGroup; } } }
/// <summary> /// Method which returns if the card is idle or not /// </summary> /// <param name="cardId">id of card</param> /// <returns>true if card is idle, otherwise false</returns> private bool IsCardIdle(int cardId) { if (_isRunning == false) return false; if (cardId < 0) return false; IUser user = new User(); user.CardId = cardId; if (RemoteControl.Instance.IsRecording(ref user)) return false; if (RemoteControl.Instance.IsTimeShifting(ref user)) return false; if (RemoteControl.Instance.IsScanning(user.CardId)) return false; IUser cardUser; if (_tvController.IsCardInUse(cardId, out cardUser)) return false; if (_tvController.IsCardInUse(user.CardId, out cardUser)) { if (cardUser != null) { return cardUser.Name == _user.Name; } return false; } return true; }
public static void OnGlobalMessage(GUIMessage message) { switch (message.Message) { case GUIMessage.MessageType.GUI_MSG_STOP_SERVER_TIMESHIFTING: { User user = new User(); if (user.Name == Card.User.Name) { Card.StopTimeShifting(); } ; break; } case GUIMessage.MessageType.GUI_MSG_NOTIFY_REC: string heading = message.Label; string text = message.Label2; Channel ch = message.Object as Channel; //Log.Debug("Received rec notify message: {0}, {1}, {2}", heading, text, (ch != null).ToString()); //remove later string logo = TVUtil.GetChannelLogo(ch); GUIDialogNotify pDlgNotify = (GUIDialogNotify)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_NOTIFY); if (pDlgNotify != null) { pDlgNotify.Reset(); pDlgNotify.ClearAll(); pDlgNotify.SetHeading(heading); if (!string.IsNullOrEmpty(text)) { pDlgNotify.SetText(text); } pDlgNotify.SetImage(logo); pDlgNotify.TimeOut = 5; pDlgNotify.DoModal(GUIWindowManager.ActiveWindow); } break; case GUIMessage.MessageType.GUI_MSG_NOTIFY_TV_PROGRAM: { TVNotifyYesNoDialog tvNotifyDlg = (TVNotifyYesNoDialog)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_TVNOTIFYYESNO); TVProgramDescription notify = message.Object as TVProgramDescription; if (tvNotifyDlg == null || notify == null) { return; } int minUntilStart = _preNotifyConfig / 60; if (notify.StartTime > DateTime.Now) { if (minUntilStart > 1) { tvNotifyDlg.SetHeading(String.Format(GUILocalizeStrings.Get(1018), minUntilStart)); } else { tvNotifyDlg.SetHeading(1019); // Program is about to begin } } else { tvNotifyDlg.SetHeading(String.Format(GUILocalizeStrings.Get(1206), (DateTime.Now - notify.StartTime).Minutes.ToString())); } tvNotifyDlg.SetLine(1, notify.Title); tvNotifyDlg.SetLine(2, notify.Description); tvNotifyDlg.SetLine(4, String.Format(GUILocalizeStrings.Get(1207), notify.Channel.DisplayName)); Channel c = notify.Channel; string strLogo = string.Empty; if (c.IsTv) { strLogo = MediaPortal.Util.Utils.GetCoverArt(Thumbs.TVChannel, c.DisplayName); } else if (c.IsRadio) { strLogo = MediaPortal.Util.Utils.GetCoverArt(Thumbs.Radio, c.DisplayName); } tvNotifyDlg.SetImage(strLogo); tvNotifyDlg.TimeOut = _notifyTVTimeout; if (_playNotifyBeep) { MediaPortal.Util.Utils.PlaySound("notify.wav", false, true); } tvNotifyDlg.SetDefaultToYes(false); tvNotifyDlg.DoModal(GUIWindowManager.ActiveWindow); if (tvNotifyDlg.IsConfirmed) { try { MediaPortal.Player.g_Player.Stop(); if (c.IsTv) { MediaPortal.GUI.Library.GUIWindowManager.ActivateWindow((int)MediaPortal.GUI.Library.GUIWindow.Window.WINDOW_TV); TVHome.ViewChannelAndCheck(c); if (TVHome.Card.IsTimeShifting && TVHome.Card.IdChannel == c.IdChannel) { g_Player.ShowFullScreenWindow(); } } else if (c.IsRadio) { MediaPortal.GUI.Library.GUIWindowManager.ActivateWindow((int)MediaPortal.GUI.Library.GUIWindow.Window.WINDOW_RADIO); Radio.CurrentChannel = c; Radio.Play(); } } catch (Exception e) { Log.Error("TVHome: TVNotification: Error on starting channel {0} after notification: {1} {2} {3}", notify.Channel.DisplayName, e.Message, e.Source, e.StackTrace); } } break; } } }
private void mpButtonTimeShift_Click(object sender, EventArgs e) { if (ServiceHelper.IsStopped) return; if (mpComboBoxChannels.SelectedItem == null) return; int id = ((ComboBoxExItem)mpComboBoxChannels.SelectedItem).Id; TvServer server = new TvServer(); VirtualCard card = GetCardTimeShiftingChannel(id); if (card != null) { card.StopTimeShifting(); mpButtonRec.Enabled = false; } else { string timeShiftingFilename = string.Empty; int cardId = -1; foreach (ListViewItem listViewItem in mpListView1.SelectedItems) { if (listViewItem.SubItems[2].Text != "disabled") { cardId = Convert.ToInt32(listViewItem.SubItems[0].Tag); break; // Keep the first card enabled selected only } } IUser user = new User(); user.Name = "setuptv-" + id + "-" + cardId; user.IsAdmin = true; user.CardId = cardId; TvResult result = server.StartTimeShifting(ref user, id, out card, cardId != -1); if (result != TvResult.Succeeded) { switch (result) { case TvResult.NoPmtFound: MessageBox.Show(this, "No PMT found"); break; case TvResult.NoSignalDetected: MessageBox.Show(this, "No signal"); break; case TvResult.CardIsDisabled: MessageBox.Show(this, "Card is not enabled"); break; case TvResult.AllCardsBusy: MessageBox.Show(this, "All cards are busy"); break; case TvResult.ChannelIsScrambled: MessageBox.Show(this, "Channel is scrambled"); break; case TvResult.NoVideoAudioDetected: MessageBox.Show(this, "No Video/Audio detected"); break; case TvResult.UnableToStartGraph: MessageBox.Show(this, "Unable to create/start graph"); break; case TvResult.ChannelNotMappedToAnyCard: MessageBox.Show(this, "Channel is not mapped to any card"); break; case TvResult.NoTuningDetails: MessageBox.Show(this, "No tuning information available for this channel"); break; case TvResult.UnknownChannel: MessageBox.Show(this, "Unknown channel"); break; case TvResult.UnknownError: MessageBox.Show(this, "Unknown error occured"); break; case TvResult.ConnectionToSlaveFailed: MessageBox.Show(this, "Cannot connect to slave server"); break; case TvResult.NotTheOwner: MessageBox.Show(this, "Failed since card is in use and we are not the owner"); break; case TvResult.GraphBuildingFailed: MessageBox.Show(this, "Unable to create graph"); break; case TvResult.SWEncoderMissing: MessageBox.Show(this, "No suppported software encoder installed"); break; case TvResult.NoFreeDiskSpace: MessageBox.Show(this, "No free disk space"); break; } } else { mpButtonRec.Enabled = true; } } }
/// <summary> /// Gets the current video stream format. /// </summary> /// <value>The available audio streams.</value> public IVideoStream GetCurrentVideoStream(User user) { if (User.CardId < 0) { return null; } try { RemoteControl.HostName = _server; return RemoteControl.Instance.GetCurrentVideoStream(user); } catch (Exception) { HandleFailure(); } return null; }
/// <summary> /// Finds out whether a channel is currently tuneable or not /// </summary> /// <param name="idChannel">the channel id</param> /// <param name="user">User</param> /// <returns>an enum indicating tunable/timeshifting/recording</returns> public ChannelState GetChannelState(int idChannel, User user) { try { if (User.CardId < 0) { return ChannelState.nottunable; } RemoteControl.HostName = _server; return RemoteControl.Instance.GetChannelState(idChannel, user); } catch (Exception) { HandleFailure(); } return ChannelState.nottunable; }
public WebChannelState GetChannelState(int channelId, string userName) { IUser user = new User(); user.Name = userName; TvControl.ChannelState state = _tvControl.GetChannelState(channelId, user); Log.Trace("ChannelId: " + channelId + ", State: " + state.ToString()); return state.ToWebChannelState(channelId); }
private void mpButtonKick_Click(object sender, EventArgs e) { foreach (ListViewItem item in listView1.SelectedItems) { RtspClient client = (RtspClient)item.Tag; IUser user = new User(); user.Name = System.Net.Dns.GetHostEntry(client.IpAdress).HostName; IList<Card> dbsCards = Card.ListAll(); foreach (Card card in dbsCards) { if (!card.Enabled) continue; if (!RemoteControl.Instance.CardPresent(card.IdCard)) continue; IUser[] users = RemoteControl.Instance.GetUsersForCard(card.IdCard); foreach (IUser u in users) { if (u.Name == user.Name || u.Name == "setuptv") { Channel ch = Channel.Retrieve(u.IdChannel); if (ch.DisplayName == client.Description) { user.CardId = card.IdCard; break; } } } if (user.CardId > -1) break; } bool res = RemoteControl.Instance.StopTimeShifting(ref user, TvStoppedReason.KickedByAdmin); if (res) { listView1.Items.Remove(item); } } listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); }
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; }
public static string getTimeshiftUrl(ref TvControl.User me) { return(serverIntf.GetTimeshiftUrl(ref me)); }
/** * \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.User me, ref string timeShiftFileName) { 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); 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("TVServerXBMC: 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("TVServerXBMC: IP resolve for '" + u.DnsSafeHost + "' failed."); Log.Debug("TVServerXBMC: Error: " + ex.ToString()); } } } } catch { //Console.WriteLine("IP resolve failed"); } // update globals timeshiftUrl = rtspURL; timeshiftChannel.Add(me.Name, chanId); } Log.Debug("TVServerXBMC: PlayChannel " + chanId.ToString() + " => URL=" + rtspURL); //Console.WriteLine("PlayChannel result : " + rtspURL); return(rtspURL); }
private void checkButton_Click(object sender, EventArgs e) { IUser user; try { TvBusinessLayer layer = new TvBusinessLayer(); Card card = layer.GetCardByDevicePath(RemoteControl.Instance.CardDevice(_cardNumber)); if (card.Enabled == false) { MessageBox.Show(this, "Card is disabled, please enable the card before checking quality control"); return; } else if (!RemoteControl.Instance.CardPresent(card.IdCard)) { MessageBox.Show(this, "Card is not found, please make sure card is present before checking quality control"); return; } // Check if the card is locked for scanning. if (RemoteControl.Instance.IsCardInUse(_cardNumber, out user)) { MessageBox.Show(this, "Card is locked. Checking quality control not possible at the moment ! Perhaps you are scanning an other part of a hybrid card."); return; } user = new User(); user.CardId = _cardNumber; AnalogChannel temp = new AnalogChannel(); temp.VideoSource = AnalogChannel.VideoInputType.Tuner; temp.AudioSource = AnalogChannel.AudioInputType.Tuner; temp.IsRadio = false; temp.IsTv = true; RemoteControl.Instance.Tune(ref user, temp, -1); if (RemoteControl.Instance.SupportsQualityControl(_cardNumber)) { _cardName = RemoteControl.Instance.CardName(_cardNumber); _devicePath = RemoteControl.Instance.CardDevice(_cardNumber); bitRateModeGroup.Enabled = RemoteControl.Instance.SupportsBitRateModes(_cardNumber); if (RemoteControl.Instance.SupportsPeakBitRateMode(_cardNumber)) { vbrPeakPlayback.Enabled = true; vbrPeakRecord.Enabled = true; } else { vbrPeakPlayback.Enabled = false; vbrPeakRecord.Enabled = false; } if (RemoteControl.Instance.SupportsBitRate(_cardNumber)) { bitRate.Enabled = true; customSettingsGroup.Enabled = true; customValue.Enabled = true; customValuePeak.Enabled = true; } else { bitRate.Enabled = false; customSettingsGroup.Enabled = false; customValue.Enabled = false; customValuePeak.Enabled = false; } _configuration = Configuration.readConfiguration(_cardNumber, _cardName, _devicePath); customValue.Value = _configuration.CustomQualityValue; customValuePeak.Value = _configuration.CustomPeakQualityValue; SetBitRateModes(); SetBitRate(); ReCheckSettings(); } else { Log.WriteFile("Card doesn't support quality control"); MessageBox.Show("The used encoder doesn't support quality control.", "MediaPortal - TV Server management console", MessageBoxButtons.OK, MessageBoxIcon.Information); if (string.IsNullOrEmpty(_configuration.Graph.Capture.Name)) { _configuration = Configuration.readConfiguration(_cardNumber, _cardName, _devicePath); ReCheckSettings(); } } } finally { user = new User(); user.CardId = _cardNumber; RemoteControl.Instance.StopCard(user); } }
private void UpdateCardStatus() { if (ServiceHelper.IsStopped) return; if (_cards == null) return; if (_cards.Count == 0) return; try { ListViewItem item; int off = 0; foreach (Card card in _cards) { IUser user = new User(); user.CardId = card.IdCard; if (off >= mpListView1.Items.Count) { item = mpListView1.Items.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); } else { item = mpListView1.Items[off]; } bool cardPresent = RemoteControl.Instance.CardPresent(card.IdCard); if (!cardPresent) { item.SubItems[0].Text = card.IdCard.ToString(); item.SubItems[1].Text = "n/a"; item.SubItems[2].Text = "n/a"; item.SubItems[3].Text = ""; item.SubItems[4].Text = ""; item.SubItems[5].Text = ""; item.SubItems[6].Text = card.Name; item.SubItems[7].Text = "0"; off++; continue; } ColorLine(card, item); VirtualCard vcard = new VirtualCard(user); item.SubItems[0].Text = card.IdCard.ToString(); item.SubItems[0].Tag = card.IdCard; item.SubItems[1].Text = vcard.Type.ToString(); if (card.Enabled == false) { item.SubItems[0].Text = card.IdCard.ToString(); item.SubItems[1].Text = vcard.Type.ToString(); item.SubItems[2].Text = "disabled"; item.SubItems[3].Text = ""; item.SubItems[4].Text = ""; item.SubItems[5].Text = ""; item.SubItems[6].Text = card.Name; item.SubItems[7].Text = "0"; off++; continue; } IUser[] usersForCard = RemoteControl.Instance.GetUsersForCard(card.IdCard); if (usersForCard == null || usersForCard.Length == 0) { string tmp = "idle"; if (vcard.IsScanning) tmp = "Scanning"; if (vcard.IsGrabbingEpg) tmp = "Grabbing EPG"; item.SubItems[2].Text = tmp; item.SubItems[3].Text = ""; item.SubItems[4].Text = ""; item.SubItems[5].Text = ""; item.SubItems[6].Text = card.Name; item.SubItems[7].Text = Convert.ToString(RemoteControl.Instance.GetSubChannels(card.IdCard)); off++; continue; } bool userFound = false; for (int i = 0; i < usersForCard.Length; ++i) { string tmp = "idle"; // Check if the card id fits. Hybrid cards share the context and therefor have // the same users. if (usersForCard[i].CardId != card.IdCard) { continue; } userFound = true; vcard = new VirtualCard(usersForCard[i]); item.SubItems[0].Text = card.IdCard.ToString(); item.SubItems[0].Tag = card.IdCard; item.SubItems[1].Text = vcard.Type.ToString(); if (vcard.IsTimeShifting) tmp = "Timeshifting"; if (vcard.IsRecording && vcard.User.IsAdmin) tmp = "Recording"; if (vcard.IsScanning) tmp = "Scanning"; if (vcard.IsGrabbingEpg) tmp = "Grabbing EPG"; if (vcard.IsTimeShifting && vcard.IsGrabbingEpg) tmp = "Timeshifting (Grabbing EPG)"; if (vcard.IsRecording && vcard.User.IsAdmin && vcard.IsGrabbingEpg) tmp = "Recording (Grabbing EPG)"; item.SubItems[2].Text = tmp; tmp = vcard.IsScrambled ? "yes" : "no"; item.SubItems[4].Text = tmp; string channelDisplayName; if (_channelNames.TryGetValue(vcard.IdChannel, out channelDisplayName)) { item.SubItems[3].Text = channelDisplayName; } else { item.SubItems[3].Text = vcard.ChannelName; } item.SubItems[5].Text = usersForCard[i].Name; item.SubItems[6].Text = card.Name; item.SubItems[7].Text = Convert.ToString(RemoteControl.Instance.GetSubChannels(card.IdCard)); off++; if (off >= mpListView1.Items.Count) { item = mpListView1.Items.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); item.SubItems.Add(""); } else { item = mpListView1.Items[off]; } } // If we haven't found a user that fits, than it is a hybrid card which is inactive // This means that the card is idle. if (!userFound) { item.SubItems[2].Text = "idle"; item.SubItems[3].Text = ""; item.SubItems[4].Text = ""; item.SubItems[5].Text = ""; item.SubItems[6].Text = card.Name; item.SubItems[7].Text = Convert.ToString(RemoteControl.Instance.GetSubChannels(card.IdCard)); off++; } } for (int i = off; i < mpListView1.Items.Count; ++i) { item = mpListView1.Items[i]; item.SubItems[0].Text = ""; item.SubItems[1].Text = ""; item.SubItems[2].Text = ""; item.SubItems[3].Text = ""; item.SubItems[4].Text = ""; item.SubItems[5].Text = ""; item.SubItems[6].Text = ""; item.SubItems[7].Text = ""; } } catch (Exception ex) { Log.Write(ex); } }
private void OnActiveStreams() { GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)Window.WINDOW_DIALOG_MENU); if (dlg == null) { return; } dlg.Reset(); dlg.SetHeading(692); // Active Tv Streams int selected = 0; string remoteHostName = string.Empty; IList<Card> cards = TvDatabase.Card.ListAll(); List<Channel> channels = new List<Channel>(); int count = 0; TvServer server = new TvServer(); List<IUser> _users = new List<IUser>(); foreach (Card card in cards) { if (card.Enabled == false) { continue; } if (!RemoteControl.Instance.CardPresent(card.IdCard)) { continue; } IUser[] users = RemoteControl.Instance.GetUsersForCard(card.IdCard); if (users == null) { return; } for (int i = 0; i < users.Length; ++i) { IUser user = users[i]; Log.Debug("rtsp url: {0}, {1}", user, RemoteControl.Instance.GetStreamingUrl(user)); if (card.IdCard != user.CardId) { continue; } bool isRecording; bool isTimeShifting; VirtualCard tvcard = new VirtualCard(user, RemoteControl.HostName); isRecording = tvcard.IsRecording; isTimeShifting = tvcard.IsTimeShifting; if (isTimeShifting || (isRecording && !isTimeShifting)) { int idChannel = tvcard.IdChannel; user = tvcard.User; Channel ch = Channel.Retrieve(idChannel); channels.Add(ch); GUIListItem item = new GUIListItem(); item.Label = ch.DisplayName; item.Label2 = user.Name; string strLogo = Utils.GetCoverArt(Thumbs.TVChannel, ch.DisplayName); if (string.IsNullOrEmpty(strLogo)) { strLogo = "defaultVideoBig.png"; } item.IconImage = strLogo; if (isRecording) { item.PinImage = Thumbs.TvRecordingIcon; } else { item.PinImage = ""; } dlg.Add(item); _users.Add(user); if (Card != null && Card.IdChannel == idChannel) { selected = count; } count++; } } } if (channels.Count == 0) { GUIDialogOK pDlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)Window.WINDOW_DIALOG_OK); if (pDlgOK != null) { pDlgOK.SetHeading(692); //my tv pDlgOK.SetLine(1, GUILocalizeStrings.Get(1511)); // No Active streams pDlgOK.SetLine(2, ""); pDlgOK.DoModal(this.GetID); } return; } dlg.SelectedLabel = selected; dlg.DoModal(this.GetID); if (dlg.SelectedLabel < 0) { return; } string selectedUrl = RemoteControl.Instance.GetStreamingUrl(_users[dlg.SelectedLabel]); VirtualCard vCard = new VirtualCard(_users[dlg.SelectedLabel], RemoteControl.HostName); Channel channel = Navigator.GetChannel(vCard.IdChannel); User myUser = new User(); /// Connect to the virtual user and play if (_users[dlg.SelectedLabel].Name.Contains("Placeshift Virtual User")) { if (inPlaceShift) { vPlaceshiftCard.StopTimeShifting(); } else if (Card.IsTimeShifting) { Card.StopTimeShifting(); } myUser.CardId = vCard.Id; // Replace the virtual user to local user RemoteControl.Instance.ReplaceTimeshiftUser(vCard.Id, myUser, _users[dlg.SelectedLabel].Name); // Send heartbeat ASAP RemoteControl.Instance.HeartBeat(myUser); if (!g_Player.Play(selectedUrl, g_Player.MediaType.TV, null, false)) { StopPlayback(); } // Seek to same position as the TV was stopped on another client. double TimeshiftPosition = RemoteControl.Instance.GetTimeshiftPosition(vCard.Id, myUser); g_Player.SeekAbsolute(TimeshiftPosition); Navigator.setChannel(channel); UpdateCurrentChannel(); Log.Debug("placeshift selected active rtspUrl: {0} for channel: {1}, user: {2}, vCard.Id: {3}, TimeshiftPosition: {4}", selectedUrl, channel.DisplayName, _users[dlg.SelectedLabel].Name, vCard.Id, TimeshiftPosition); // Setup vPlaceshiftCard for stoptimeshift vPlaceshiftCard = vCard; vPlaceshiftCard.User.Name = myUser.Name; inPlaceShift = true; } else { if (myUser.Name != _users[dlg.SelectedLabel].Name && OnShareTsBuffer()) { if (inPlaceShift) { vPlaceshiftCard.StopTimeShifting(); } else if (Card.IsTimeShifting) { Card.StopTimeShifting(); } if (!g_Player.Play(selectedUrl, g_Player.MediaType.TV, null, false)) { StopPlayback(); } Navigator.setChannel(channel); UpdateCurrentChannel(); } else { ViewChannel(channel); } } }
/// <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(); } }
/// <summary> /// Fill the list with channels /// </summary> public void FillChannelList() { List<Channel> tvChannelList = GetChannelListByGroup(); benchClock = Stopwatch.StartNew(); DateTime nextEPGupdate = GetNextEpgUpdate(); Dictionary<int, NowAndNext> listNowNext = GetNowAndNext(tvChannelList, nextEPGupdate); benchClock.Stop(); Log.Debug("TvMiniGuide: FillChannelList retrieved {0} programs for {1} channels in {2} ms", listNowNext.Count, tvChannelList.Count, benchClock.ElapsedMilliseconds.ToString()); GUIListItem item = null; string ChannelLogo = ""; //List<int> RecChannels = null; //List<int> TSChannels = null; int SelectedID = 0; int channelID = 0; bool DisplayStatusInfo = true; Dictionary<int, ChannelState> tvChannelStatesList = null; if (TVHome.ShowChannelStateIcons()) { benchClock.Reset(); benchClock.Start(); if (TVHome.Navigator.CurrentGroup.GroupName.Equals(TvConstants.TvGroupNames.AllChannels) || (!g_Player.IsTV && !g_Player.Playing)) { //we have no way of using the cached channelstates on the server in the following situations. // 1) when the "all channels" group is selected - too many channels. // 2) when user is not timeshifting - no user object on the server. User currentUser = new User(); tvChannelStatesList = TVHome.TvServer.GetAllChannelStatesForGroup(TVHome.Navigator.CurrentGroup.IdGroup, currentUser); } else { // use the more speedy approach // ask the server of the cached list of channel states corresponding to the user. tvChannelStatesList = TVHome.TvServer.GetAllChannelStatesCached(TVHome.Card.User); if (tvChannelStatesList == null) { //slow approach. tvChannelStatesList = TVHome.TvServer.GetAllChannelStatesForGroup(TVHome.Navigator.CurrentGroup.IdGroup, TVHome.Card.User); } } benchClock.Stop(); if (tvChannelStatesList != null) { Log.Debug("TvMiniGuide: FillChannelList - {0} channel states for group retrieved in {1} ms", Convert.ToString(tvChannelStatesList.Count), benchClock.ElapsedMilliseconds.ToString()); } } for (int i = 0; i < tvChannelList.Count; i++) { Channel CurrentChan = tvChannelList[i]; if (CurrentChan.VisibleInGuide) { ChannelState CurrentChanState = ChannelState.tunable; channelID = CurrentChan.IdChannel; if (TVHome.ShowChannelStateIcons()) { if (!tvChannelStatesList.TryGetValue(channelID, out CurrentChanState)) { CurrentChanState = ChannelState.tunable; } } //StringBuilder sb = new StringBuilder(); sb.Length = 0; item = new GUIListItem(""); // store here as it is not needed right now - please beat me later.. item.TVTag = CurrentChan; sb.Append(CurrentChan.DisplayName); ChannelLogo = Utils.GetCoverArt(Thumbs.TVChannel, CurrentChan.DisplayName); // if we are watching this channel mark it if (TVHome.Navigator != null && TVHome.Navigator.Channel != null && TVHome.Navigator.Channel.IdChannel == channelID) { item.IsRemote = true; SelectedID = lstChannels.Count; } if (!string.IsNullOrEmpty(ChannelLogo)) { item.IconImageBig = ChannelLogo; item.IconImage = ChannelLogo; } else { item.IconImageBig = string.Empty; item.IconImage = string.Empty; } if (DisplayStatusInfo) { bool showChannelStateIcons = (TVHome.ShowChannelStateIcons() && lstChannelsWithStateIcons != null); switch (CurrentChanState) { case ChannelState.nottunable: item.IsPlayed = true; if (showChannelStateIcons) { item.PinImage = Thumbs.TvIsUnavailableIcon; } else { sb.Append(" "); sb.Append(local1056); } break; case ChannelState.timeshifting: if (showChannelStateIcons) { item.PinImage = Thumbs.TvIsTimeshiftingIcon; } else { sb.Append(" "); sb.Append(local1055); } break; case ChannelState.recording: if (showChannelStateIcons) { item.PinImage = Thumbs.TvIsRecordingIcon; } else { sb.Append(" "); sb.Append(local1054); } break; default: item.IsPlayed = false; if (showChannelStateIcons) { item.PinImage = Thumbs.TvIsAvailableIcon; } break; } } //StringBuilder sbTmp = new StringBuilder(); sbTmp.Length = 0; NowAndNext currentNowAndNext = null; bool hasNowNext = listNowNext.TryGetValue(channelID, out currentNowAndNext); if (hasNowNext) { if (!string.IsNullOrEmpty(currentNowAndNext.TitleNow)) { sbTmp.Append(currentNowAndNext.NowStartTime.ToString("t", CultureInfo.CurrentCulture.DateTimeFormat)); sbTmp.Append(": "); TVUtil.TitleDisplay(sbTmp, currentNowAndNext.TitleNow, currentNowAndNext.EpisodeName, currentNowAndNext.SeriesNum, currentNowAndNext.EpisodeNum, currentNowAndNext.EpisodePart); } else { sbTmp.Append(local736); } } else { sbTmp.Append(local736); } item.Label2 = sbTmp.ToString(); sbTmp.Insert(0, string.Empty); item.Label3 = sbTmp.ToString(); sbTmp.Length = 0; if (_showChannelNumber == true) { sb.Append(" - "); if (!_byIndex) { sb.Append(tvChannelList[i].ChannelNumber); } else { sb.Append(i + 1); } } if (hasNowNext) { // if the "Now" DB entry is in the future we set MinValue intentionally to avoid wrong percentage calculations DateTime startTime = currentNowAndNext.NowStartTime; if (startTime != SqlDateTime.MinValue.Value) { DateTime endTime = currentNowAndNext.NowEndTime; int percent = (int)CalculateProgress(startTime, endTime); sb.Append(" - "); sb.Append( percent.ToString()); sb.Append("%"); item.HasProgressBar = true; item.ProgressBarPercentage = percent; if (endTime < nextEPGupdate || nextEPGupdate == DateTime.MinValue) { nextEPGupdate = endTime; SetNextEpgUpdate(endTime); } } } if (hasNowNext && listNowNext[channelID].IdProgramNext != -1) { sbTmp.Append(currentNowAndNext.NextStartTime.ToString("t", CultureInfo.CurrentCulture.DateTimeFormat)); sbTmp.Append(": "); TVUtil.TitleDisplay(sbTmp, currentNowAndNext.TitleNext, currentNowAndNext.EpisodeNameNext, currentNowAndNext.SeriesNumNext, currentNowAndNext.EpisodeNumNext, currentNowAndNext.EpisodePartNext); } else { sbTmp.Append(local736); } item.Label2 = sb.ToString(); sbTmp.Insert(0, string.Empty); item.Label = sbTmp.ToString(); lstChannels.Add(item); } } benchClock.Stop(); Log.Debug("TvMiniGuide: State check + filling completed after {0} ms", benchClock.ElapsedMilliseconds.ToString()); lstChannels.SelectedListItemIndex = SelectedID; if (lstChannels.GetID == 37) { GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SETFOCUS, GetID, 0, 37, 0, 0, null); OnMessage(msg); } sb.Length = 0; sbTmp.Length = 0; }