public GetTuningDetail ( TvLibrary.Channels.DVBBaseChannel channel ) : TvDatabase.TuningDetail | ||
channel | TvLibrary.Channels.DVBBaseChannel | |
Résultat | TvDatabase.TuningDetail |
public ICardTuneReservationTicket RequestCardTuneReservation(ITvCardHandler tvcard, IChannel tuningDetail, IUser user) { ICardTuneReservationTicket cardTuneReservationTicket = null; var layer = new TvBusinessLayer(); CardTuneState cardTuneState; int ticketId = 0; bool isCardAvail; bool hasUserHigherPriorityThanBlockingUser = false; lock (tvcard.Tuner.CardReservationsLock) { isCardAvail = IsCardAvail(tvcard); if (!isCardAvail) { if (tvcard.Tuner.CardTuneState != CardTuneState.TuneCancelled) { IUser blockingUser = GetBlockingUser(tvcard); hasUserHigherPriorityThanBlockingUser = (HasUserHigherPriorityThanBlockingUser(user, blockingUser)); if (hasUserHigherPriorityThanBlockingUser) { tvcard.Tuner.CardTuneState = CardTuneState.TuneCancelled; } } } } if (!isCardAvail) { if (hasUserHigherPriorityThanBlockingUser) { tvcard.Tuner.CancelTune(tvcard.Tuner.ActiveCardTuneReservationTicket.PendingSubchannel); lock (tvcard.Tuner.CardReservationsLock) { isCardAvail = IsCardAvail(tvcard); } } } lock (tvcard.Tuner.CardReservationsLock) { if (isCardAvail) { tvcard.Tuner.CardTuneState = CardTuneState.TunePending; bool isTunedToTransponder = IsTunedToTransponder(tvcard, tuningDetail); if (isTunedToTransponder) { CheckTransponder(tvcard, tuningDetail, layer, user); } int ownerSubchannel = -1; int numberOfUsersOnSameCurrentChannel = 0; int numberOfOtherUsersOnSameChannel = 0; int numberOfOtherUsersOnCurrentCard = 0; bool hasUserHighestPriority = false; bool hasUserEqualOrHigherPriority = false; bool isCamAlreadyDecodingChannel = false; bool conflictingSubchannelFound = false; bool isRecordingAnyUser = false; bool isAnySubChannelTimeshifting = tvcard.TimeShifter.IsAnySubChannelTimeshifting; bool isOwner = tvcard.Users.IsOwner(user); var users = new List<IUser>(tvcard.Users.GetUsers()); var inactiveUsers = new List<IUser>(); var activeUsers = new List<IUser>(); var recUsers = new List<IUser>(); var tsUsers = new List<IUser>(); var context = tvcard.Card.Context as ITvCardContext; if (context != null) { context.GetUser(ref user); hasUserHighestPriority = context.HasUserHighestPriority(user); hasUserEqualOrHigherPriority = context.HasUserEqualOrHigherPriority(user); } int currentChannelId = tvcard.CurrentDbChannel(ref user); for (int i = users.Count - 1; i > -1; i--) { IUser actualUser = users[i]; CardReservationHelper.AddUserIfRecording(tvcard, ref actualUser, recUsers); CardReservationHelper.AddUserIfTimeshifting(tvcard, ref actualUser, tsUsers); bool isCurrentUser = user.Name.Equals(actualUser.Name); IChannel userChannel = tvcard.CurrentChannel(ref actualUser); var userDVBchannel = userChannel as DVBBaseChannel; if (!isCurrentUser) { if (!isRecordingAnyUser) { isRecordingAnyUser = CardReservationHelper.IsRecordingUser(tvcard, user, ref actualUser); } if (actualUser.SubChannel == user.SubChannel && user.IdChannel > 0) { conflictingSubchannelFound = true; } numberOfOtherUsersOnCurrentCard = CardReservationHelper.GetNumberOfOtherUsersOnCurrentCard(user, numberOfOtherUsersOnCurrentCard); if (userChannel == null) { inactiveUsers.Add(actualUser); } else { if (userDVBchannel != null) { actualUser.IdChannel = layer.GetTuningDetail(userDVBchannel).IdChannel; } bool isDiffTS = tuningDetail.IsDifferentTransponder(userChannel); if (isDiffTS) { activeUsers.Add(actualUser); } else { if (!isOwner) { bool isUserOnSameChannel = CardReservationHelper.IsUserOnSameChannel(tuningDetail, layer, userDVBchannel); if (isUserOnSameChannel) { numberOfOtherUsersOnSameChannel++; //we do not want to hook up on schedulers existing subchannel if (!actualUser.IsAdmin) { ownerSubchannel = actualUser.SubChannel; } } } } } } bool isUserOnSameCurrentChannel = CardReservationHelper.IsUserOnSameCurrentChannel(currentChannelId, actualUser); if (isUserOnSameCurrentChannel) { numberOfUsersOnSameCurrentChannel++; } if (!isCamAlreadyDecodingChannel) { isCamAlreadyDecodingChannel = IsCamAlreadyDecodingChannel(tuningDetail, userChannel); } } bool isFreeToAir = CardReservationHelper.IsFreeToAir(tvcard, user); cardTuneReservationTicket = new CardTuneReservationTicket ( user, tuningDetail, isTunedToTransponder, numberOfOtherUsersOnSameChannel, isAnySubChannelTimeshifting, inactiveUsers, activeUsers, users, ownerSubchannel, isOwner, tvcard.DataBaseCard.IdCard, tvcard.NumberOfChannelsDecrypting, isFreeToAir, numberOfOtherUsersOnCurrentCard, recUsers, tsUsers, conflictingSubchannelFound, numberOfUsersOnSameCurrentChannel, isCamAlreadyDecodingChannel, hasUserHighestPriority, hasUserEqualOrHigherPriority); tvcard.Tuner.ActiveCardTuneReservationTicket = cardTuneReservationTicket; tvcard.Tuner.ReservationsForTune.Add(cardTuneReservationTicket); } cardTuneState = tvcard.Tuner.CardTuneState; if (tvcard.Tuner.ActiveCardTuneReservationTicket != null) { ticketId = tvcard.Tuner.ActiveCardTuneReservationTicket.Id; } } if (cardTuneReservationTicket != null) { Log.Debug("CardReservationBase.RequestCardTuneReservation: placed reservation with id={0}, tuningdetails={1}", cardTuneReservationTicket.Id, cardTuneReservationTicket.TuningDetail); } else { if (ticketId > 0) { Log.Debug("CardReservationBase.RequestCardTuneReservation: failed reservation tuningdetails={0}, res id blocking={1}, state={2}", tuningDetail, ticketId, cardTuneState); } else { Log.Debug("CardReservationBase.RequestCardTuneReservation: failed reservation tuningdetails={0}, res id blocking={1}, state={2}", tuningDetail, "n/a", cardTuneState); } } return cardTuneReservationTicket; }
public static bool IsUserOnSameChannel(IChannel tuningDetail, TvBusinessLayer layer, DVBBaseChannel userDVBchannel) { bool isUserOnSameChannel = false; if (userDVBchannel != null) { var currentDVBchannel = tuningDetail as DVBBaseChannel; if (currentDVBchannel != null) { TuningDetail currentDVBtuningDetail = layer.GetTuningDetail(currentDVBchannel); TuningDetail userDVBtuningDetail = layer.GetTuningDetail(userDVBchannel); isUserOnSameChannel = (currentDVBtuningDetail != null && currentDVBtuningDetail.IdChannel == userDVBtuningDetail.IdChannel); } } return isUserOnSameChannel; }
/// <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 PersistPMTtoDataBase(int pmtPid) { // check if PMT has changed, in this case update tuning details DVBBaseChannel currentDvbChannel = _currentChannel as DVBBaseChannel; if (currentDvbChannel != null && pmtPid != currentDvbChannel.PmtPid && !alwaysUsePATLookup) { currentDvbChannel.PmtPid = pmtPid; TvBusinessLayer layer = new TvBusinessLayer(); TuningDetail currentDetail = layer.GetTuningDetail(currentDvbChannel); if (currentDetail != null) { try { currentDetail.PmtPid = pmtPid; currentDetail.Persist(); Log.Log.Debug("Updated PMT Pid to {0:X}!", pmtPid); } catch (Exception e) { Log.Log.Error("PMT {0:X} could not be persisted to DB!", pmtPid, e); } } else { Log.Log.Debug("PMT {0:X} could not be persisted to DB, no tuningdetails found!", pmtPid); } } }
private void DoScan() { int tvChannelsNew = 0; int radioChannelsNew = 0; int tvChannelsUpdated = 0; int radioChannelsUpdated = 0; string buttonText = mpButtonScanTv.Text; IUser user = new User(); user.CardId = _cardNumber; try { // First lock the card, because so that other parts of a hybrid card can't be used at the same time _isScanning = true; _stopScanning = false; mpButtonScanTv.Text = "Cancel..."; RemoteControl.Instance.EpgGrabberEnabled = false; listViewStatus.Items.Clear(); PlayList playlist = new PlayList(); if (mpComboBoxService.SelectedIndex == 0) { //TODO read SAP announcements } else { IPlayListIO playlistIO = PlayListFactory.CreateIO(String.Format(@"{0}\TuningParameters\dvbip\{1}.m3u", PathManager.GetDataPath, mpComboBoxService.SelectedItem)); playlistIO.Load(playlist, String.Format(@"{0}\TuningParameters\dvbip\{1}.m3u", PathManager.GetDataPath, mpComboBoxService.SelectedItem)); } if (playlist.Count == 0) return; mpComboBoxService.Enabled = false; checkBoxCreateGroups.Enabled = false; checkBoxEnableChannelMoveDetection.Enabled = false; TvBusinessLayer layer = new TvBusinessLayer(); Card card = layer.GetCardByDevicePath(RemoteControl.Instance.CardDevice(_cardNumber)); int index = -1; IEnumerator<PlayListItem> enumerator = playlist.GetEnumerator(); while (enumerator.MoveNext()) { if (_stopScanning) return; index++; float percent = ((float)(index)) / playlist.Count; percent *= 100f; if (percent > 100f) percent = 100f; progressBar1.Value = (int)percent; string url = enumerator.Current.FileName.Substring(enumerator.Current.FileName.LastIndexOf('\\') + 1); string name = enumerator.Current.Description; DVBIPChannel tuneChannel = new DVBIPChannel(); tuneChannel.Url = url; tuneChannel.Name = name; string line = String.Format("{0}- {1} - {2}", 1 + index, tuneChannel.Name, tuneChannel.Url); ListViewItem item = listViewStatus.Items.Add(new ListViewItem(line)); item.EnsureVisible(); RemoteControl.Instance.Tune(ref user, tuneChannel, -1); IChannel[] channels; channels = RemoteControl.Instance.Scan(_cardNumber, tuneChannel); UpdateStatus(); if (channels == null || channels.Length == 0) { if (RemoteControl.Instance.TunerLocked(_cardNumber) == false) { line = String.Format("{0}- {1} - {2} :No Signal", 1 + index, tuneChannel.Url, tuneChannel.Name); item.Text = line; item.ForeColor = Color.Red; continue; } else { line = String.Format("{0}- {1} - {2} :Nothing found", 1 + index, tuneChannel.Url, tuneChannel.Name); item.Text = line; item.ForeColor = Color.Red; continue; } } int newChannels = 0; int updatedChannels = 0; for (int i = 0; i < channels.Length; ++i) { Channel dbChannel; DVBIPChannel channel = (DVBIPChannel)channels[i]; if (channels.Length > 1) { if (channel.Name.IndexOf("Unknown") == 0) { channel.Name = name + (i + 1); } } else { channel.Name = name; } bool exists; TuningDetail currentDetail; //Check if we already have this tuningdetail. According to DVB-IP specifications there are two ways to identify DVB-IP //services: one ONID + SID based, the other domain/URL based. At this time we don't fully and properly implement the DVB-IP //specifications, so the safest method for service identification is the URL. The user has the option to enable the use of //ONID + SID identification and channel move detection... if (checkBoxEnableChannelMoveDetection.Checked) { currentDetail = layer.GetTuningDetail(channel.NetworkId, channel.ServiceId, TvBusinessLayer.GetChannelType(channel)); } else { currentDetail = layer.GetTuningDetail(channel.Url, TvBusinessLayer.GetChannelType(channel)); } if (currentDetail == null) { //add new channel exists = false; dbChannel = layer.AddNewChannel(channel.Name, channel.LogicalChannelNumber); 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(); } layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.AllChannels); if (checkBoxCreateGroups.Checked) { layer.AddChannelToGroup(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) { tvChannelsUpdated++; updatedChannels++; } else { tvChannelsNew++; newChannels++; } } if (channel.IsRadio) { if (exists) { radioChannelsUpdated++; updatedChannels++; } else { radioChannelsNew++; newChannels++; } } layer.MapChannelToCard(card, dbChannel, false); line = String.Format("{0}- {1} :New:{2} Updated:{3}", 1 + index, tuneChannel.Name, newChannels, updatedChannels); item.Text = line; } } //DatabaseManager.Instance.SaveChanges(); } catch (Exception ex) { Log.Write(ex); } finally { RemoteControl.Instance.StopCard(user); RemoteControl.Instance.EpgGrabberEnabled = true; progressBar1.Value = 100; mpComboBoxService.Enabled = true; checkBoxCreateGroups.Enabled = true; checkBoxEnableChannelMoveDetection.Enabled = true; mpButtonScanTv.Text = buttonText; _isScanning = false; } ListViewItem lastItem = listViewStatus.Items.Add(new ListViewItem("Scan done...")); lastItem = listViewStatus.Items.Add( new ListViewItem(String.Format("Total radio channels new:{0} updated:{1}", radioChannelsNew, radioChannelsUpdated))); lastItem = listViewStatus.Items.Add( new ListViewItem(String.Format("Total tv channels new:{0} updated:{1}", tvChannelsNew, tvChannelsUpdated))); lastItem.EnsureVisible(); }
/// <summary> /// Start timeshifting on a specific channel /// </summary> /// <param name="user">user credentials.</param> /// <param name="idChannel">The id channel.</param> /// <param name="card">returns card for which timeshifting is started</param> /// <param name="forceCardId">Indicated, if the card should be forced</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, bool forceCardId, out bool cardChanged) { cardChanged = false; if (user == null) { card = null; return TvResult.UnknownError; } string intialTimeshiftingFilename = ""; VirtualCard initialCard = null; if (user.CardId != -1) initialCard = GetVirtualCard(user); if (initialCard != null && initialCard.TimeShiftFileName != null) { intialTimeshiftingFilename = initialCard.TimeShiftFileName; } Channel channel = Channel.Retrieve(idChannel); Log.Write("Controller: StartTimeShifting {0} {1}", channel.DisplayName, channel.IdChannel); card = null; if (_epgGrabber != null) { _epgGrabber.Stop(); } IUser userCopy = null; try { TvResult result; List<CardDetail> freeCards = _cardAllocation.GetFreeCardsForChannel(_cards, channel, ref user, out result); if (freeCards.Count == 0) { //no free cards available Log.Write("Controller: StartTimeShifting failed:{0}", result); if (_epgGrabber != null && AllCardsIdle) { _epgGrabber.Start(); } return result; } int maxCards; if (_maxFreeCardsToTry == 0) { maxCards = freeCards.Count; } else { maxCards = Math.Min(_maxFreeCardsToTry, freeCards.Count); if (maxCards > freeCards.Count) { maxCards = freeCards.Count; } } Log.Write("Controller: try max {0} of {1} cards for timeshifting", maxCards, freeCards.Count); TvBusinessLayer layer = new TvBusinessLayer(); //keep tuning each card until we are succesful for (int i = 0; i < maxCards; i++) { int nrOfOtherUsersTimeshiftingOnCard = 0; if (i > 0) { Log.Write("Controller: Timeshifting failed, lets try next available card."); cardChanged = (maxCards > 1); } userCopy = new User(user.Name, user.IsAdmin); CardDetail cardInfo = freeCards[i]; userCopy.CardId = cardInfo.Id; if (forceCardId && user.CardId != cardInfo.Id) { continue; } IChannel tuneChannel = cardInfo.TuningDetail; //setup folders if (cardInfo.Card.RecordingFolder == String.Empty) { cardInfo.Card.RecordingFolder = String.Format(@"{0}\Team MediaPortal\MediaPortal TV Server\recordings", Environment.GetFolderPath( Environment.SpecialFolder.CommonApplicationData)); if (!Directory.Exists(cardInfo.Card.RecordingFolder)) { Log.Write("Controller: creating recording folder {0} for card {0}", cardInfo.Card.RecordingFolder, cardInfo.Card.Name); Directory.CreateDirectory(cardInfo.Card.RecordingFolder); } } if (cardInfo.Card.TimeShiftFolder == String.Empty) { cardInfo.Card.TimeShiftFolder = String.Format( @"{0}\Team MediaPortal\MediaPortal TV Server\timeshiftbuffer", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); if (!Directory.Exists(cardInfo.Card.TimeShiftFolder)) { Log.Write("Controller: creating timeshifting folder {0} for card {0}", cardInfo.Card.TimeShiftFolder, cardInfo.Card.Name); Directory.CreateDirectory(cardInfo.Card.TimeShiftFolder); } } //todo : if the owner is changing channel to a new transponder, then kick any leeching users. ITvCardHandler tvcard = _cards[cardInfo.Id]; bool isTS = tvcard.TimeShifter.IsAnySubChannelTimeshifting; bool skipCard = false; if (isTS) { IUser[] users = tvcard.Users.GetUsers(); for (int j = users.Length - 1; j > -1; j--) { IUser u = users[j]; if (user.Name.Equals(u.Name)) { continue; } IChannel tmpChannel = tvcard.CurrentChannel(ref u); if (tmpChannel == null) { tvcard.Users.RemoveUser(u); //removing inactive user which shouldnt happen, but atleast its better than having timeshfiting fail. continue; } bool isDiffTS = tuneChannel.IsDifferentTransponder(tmpChannel); if (isDiffTS) { Log.Write("Controller: kicking leech user {0} off card {1} since owner {2} changed transponder", u.Name, cardInfo.Card.Name, user.Name); StopTimeShifting(ref u, TvStoppedReason.OwnerChangedTS); } else { DVBBaseChannel dvbBaseChannel = tmpChannel as DVBBaseChannel; if (dvbBaseChannel != null) { TuningDetail userChannel = layer.GetTuningDetail(dvbBaseChannel); bool isOnSameChannel = (idChannel == userChannel.IdChannel); if (isOnSameChannel) { if (tvcard.Users.IsOwner(userCopy)) { if (i < maxCards) { Log.Write("Controller: skipping card:{0} since other users are present on the same channel.", userCopy.CardId); skipCard = true; break; //try next card } } else { nrOfOtherUsersTimeshiftingOnCard++; if (!u.IsAdmin) { userCopy.SubChannel = u.SubChannel; } } } } } } } if (skipCard) { continue; } //tune to the new channel result = CardTune(ref userCopy, tuneChannel, channel); if (result != TvResult.Succeeded) { user.FailedCardId = userCopy.FailedCardId; StopTimeShifting(ref userCopy); continue; //try next card } Log.Info("control2:{0} {1} {2}", userCopy.Name, userCopy.CardId, userCopy.SubChannel); if (!IsTimeShifting(ref userCopy)) { CleanTimeShiftFiles(cardInfo.Card.TimeShiftFolder, String.Format("live{0}-{1}.ts", userCopy.CardId, userCopy.SubChannel)); } string timeshiftFileName = String.Format(@"{0}\live{1}-{2}.ts", cardInfo.Card.TimeShiftFolder, userCopy.CardId, userCopy.SubChannel); //start timeshifting result = StartTimeShifting(ref userCopy, ref timeshiftFileName); if (result != TvResult.Succeeded) { StopTimeShifting(ref userCopy); continue; //try next card } Log.Write("Controller: StartTimeShifting started on card:{0} to {1}", userCopy.CardId, timeshiftFileName); card = GetVirtualCard(userCopy); card.NrOfOtherUsersTimeshiftingOnCard = nrOfOtherUsersTimeshiftingOnCard; RemoveUserFromOtherCards(card.Id, userCopy); //only remove user from other cards if new tuning was a success UpdateChannelStatesForUsers(); if (card != null && card.TimeShiftFileName != null) { string newTimeshiftingFilename = card.TimeShiftFileName; cardChanged = (intialTimeshiftingFilename != newTimeshiftingFilename); } break; //if we made it to the bottom, then we have a successful timeshifting. } if (result != TvResult.Succeeded) { if (_epgGrabber != null && AllCardsIdle) { _epgGrabber.Start(); } } return result; } catch (Exception ex) { if (userCopy != null) { user.FailedCardId = userCopy.FailedCardId; } if (_epgGrabber != null && AllCardsIdle) { _epgGrabber.Start(); } Log.Write(ex); return TvResult.UnknownError; } }
private void DoScan() { int tvChannelsNew = 0; int radioChannelsNew = 0; int tvChannelsUpdated = 0; int radioChannelsUpdated = 0; string buttonText = mpButtonScanTv.Text; try { _isScanning = true; _stopScanning = false; mpButtonScanTv.Text = "Cancel..."; RemoteControl.Instance.EpgGrabberEnabled = false; if (_atscChannels.Count == 0) return; mpComboBoxFrequencies.Enabled = false; listViewStatus.Items.Clear(); TvBusinessLayer layer = new TvBusinessLayer(); Card card = layer.GetCardByDevicePath(RemoteControl.Instance.CardDevice(_cardNumber)); IUser user = new User(); user.CardId = _cardNumber; int minchan = 2; int maxchan = 69; //Check if QAM if so then the number of channels varies if (checkBoxQAM.Checked) { minchan = 0; maxchan = _atscChannels.Count; } for (int index = minchan; index < maxchan; ++index) { if (_stopScanning) return; float percent = ((float)(index)) / (maxchan - minchan); percent *= 100f; if (percent > 100f) percent = 100f; progressBar1.Value = (int)percent; ATSCChannel tuneChannel = new ATSCChannel(); tuneChannel.NetworkId = -1; tuneChannel.TransportId = -1; tuneChannel.ServiceId = -1; tuneChannel.MinorChannel = -1; tuneChannel.MajorChannel = -1; if (checkBoxQAM.Checked) { Log.WriteFile("ATSC tune: QAM checkbox selected... using Modulation 256Qam"); tuneChannel.PhysicalChannel = index + 1; tuneChannel.Frequency = _atscChannels[index].frequency; tuneChannel.ModulationType = ModulationType.Mod256Qam; } else { Log.WriteFile("ATSC tune: QAM checkbox not selected... using Modulation 8Vsb"); tuneChannel.PhysicalChannel = index; tuneChannel.Frequency = -1; tuneChannel.ModulationType = ModulationType.Mod8Vsb; } Log.WriteFile("ATSC tune: PhysicalChannel: {0} Frequency: {1} Modulation: {2}", tuneChannel.PhysicalChannel, tuneChannel.Frequency, tuneChannel.ModulationType); string line = String.Format("physical channel:{0} frequency:{1} modulation:{2}", tuneChannel.PhysicalChannel, tuneChannel.Frequency, tuneChannel.ModulationType); ListViewItem item = listViewStatus.Items.Add(new ListViewItem(line)); item.EnsureVisible(); if (index == minchan) { RemoteControl.Instance.Scan(ref user, tuneChannel, -1); } IChannel[] channels = RemoteControl.Instance.Scan(_cardNumber, tuneChannel); UpdateStatus(); /*if (channels == null || channels.Length == 0) { if (checkBoxQAM.Checked) { //try Modulation 64Qam now tuneChannel.PhysicalChannel = index + 1; tuneChannel.Frequency = _atscChannels[index].frequency; tuneChannel.ModulationType = ModulationType.Mod64Qam; line = String.Format("physical channel:{0} frequency:{1} modulation:{2}: No signal", tuneChannel.PhysicalChannel, tuneChannel.Frequency, tuneChannel.ModulationType); item.Text = line; channels = RemoteControl.Instance.Scan(_cardNumber, tuneChannel); } }*/ UpdateStatus(); if (channels == null || channels.Length == 0) { if (RemoteControl.Instance.TunerLocked(_cardNumber) == false) { line = String.Format("physical channel:{0} frequency:{1} modulation:{2}: No signal", tuneChannel.PhysicalChannel, tuneChannel.Frequency, tuneChannel.ModulationType); item.Text = line; item.ForeColor = Color.Red; continue; } line = String.Format("physical channel:{0} frequency:{1} modulation:{2}: Nothing found", tuneChannel.PhysicalChannel, tuneChannel.Frequency, tuneChannel.ModulationType); item.Text = line; item.ForeColor = Color.Red; continue; } int newChannels = 0; int updatedChannels = 0; for (int i = 0; i < channels.Length; ++i) { Channel dbChannel; ATSCChannel channel = (ATSCChannel)channels[i]; //No support for channel moving, or merging with existing channels here. //We do not know how ATSC works to correctly implement this. TuningDetail currentDetail = layer.GetTuningDetail(channel); if (currentDetail != null) if (channel.Frequency != currentDetail.Frequency) currentDetail = null; bool exists; if (currentDetail == null) { //add new channel exists = false; dbChannel = layer.AddNewChannel(channel.Name); dbChannel.SortOrder = 10000; if (channel.LogicalChannelNumber >= 1) { dbChannel.SortOrder = channel.LogicalChannelNumber; } } else { exists = true; dbChannel = currentDetail.ReferencedChannel(); } dbChannel.IsTv = channel.IsTv; dbChannel.IsRadio = channel.IsRadio; dbChannel.Persist(); if (dbChannel.IsTv) { layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.AllChannels); } if (dbChannel.IsRadio) { layer.AddChannelToRadioGroup(dbChannel, TvConstants.RadioGroupNames.AllChannels); } 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) { tvChannelsUpdated++; updatedChannels++; } else { tvChannelsNew++; newChannels++; } } if (channel.IsRadio) { if (exists) { radioChannelsUpdated++; updatedChannels++; } else { radioChannelsNew++; newChannels++; } } layer.MapChannelToCard(card, dbChannel, false); line = String.Format("physical channel:{0} frequency:{1} modulation:{2} New:{3} Updated:{4}", tuneChannel.PhysicalChannel, tuneChannel.Frequency, tuneChannel.ModulationType, newChannels, updatedChannels); item.Text = line; } } //DatabaseManager.Instance.SaveChanges(); } catch (Exception ex) { Log.Write(ex); } finally { IUser user = new User(); user.CardId = _cardNumber; RemoteControl.Instance.StopCard(user); RemoteControl.Instance.EpgGrabberEnabled = true; progressBar1.Value = 100; checkBoxQAM.Enabled = true; mpComboBoxFrequencies.Enabled = true; mpButtonScanTv.Text = buttonText; _isScanning = false; } listViewStatus.Items.Add( new ListViewItem(String.Format("Total radio channels new:{0} updated:{1}", radioChannelsNew, radioChannelsUpdated))); listViewStatus.Items.Add( new ListViewItem(String.Format("Total tv channels new:{0} updated:{1}", tvChannelsNew, tvChannelsUpdated))); ListViewItem lastItem = listViewStatus.Items.Add(new ListViewItem("Scan done...")); lastItem.EnsureVisible(); }
private void DoScan() { int tvChannelsNew = 0; int radioChannelsNew = 0; int tvChannelsUpdated = 0; int radioChannelsUpdated = 0; string buttonText = mpButtonScanTv.Text; try { _isScanning = true; _stopScanning = false; mpButtonScanTv.Text = "Cancel..."; RemoteControl.Instance.EpgGrabberEnabled = false; if (_atscChannels.Count == 0) return; mpComboBoxFrequencies.Enabled = false; listViewStatus.Items.Clear(); TvBusinessLayer layer = new TvBusinessLayer(); Card card = layer.GetCardByDevicePath(RemoteControl.Instance.CardDevice(_cardNumber)); IUser user = new User(); user.CardId = _cardNumber; int minchan = 2; int maxchan = 69 + 1; if ((string)mpComboBoxTuningMode.SelectedItem == "Clear QAM Cable") { minchan = 1; maxchan = _atscChannels.Count + 1; } else if ((string)mpComboBoxTuningMode.SelectedItem == "Digital Cable") { minchan = 0; maxchan = 1; } for (int index = minchan; index < maxchan; ++index) { if (_stopScanning) return; float percent = ((float)(index)) / (maxchan - minchan); percent *= 100f; if (percent > 100f) percent = 100f; progressBar1.Value = (int)percent; ATSCChannel tuneChannel = new ATSCChannel(); tuneChannel.NetworkId = -1; tuneChannel.TransportId = -1; tuneChannel.ServiceId = -1; tuneChannel.MinorChannel = -1; tuneChannel.MajorChannel = -1; string line; if ((string)mpComboBoxTuningMode.SelectedItem == "Clear QAM Cable") { tuneChannel.PhysicalChannel = index; tuneChannel.Frequency = _atscChannels[index - 1].frequency; if (tuneChannel.Frequency < 10000) { continue; } tuneChannel.ModulationType = ModulationType.Mod256Qam; line = string.Format("physical channel = {0}, frequency = {1} kHz, modulation = 256 QAM", tuneChannel.PhysicalChannel, tuneChannel.Frequency); Log.Info("ATSC: scanning clear QAM cable, {0}, frequency plan = {1}", line, mpComboBoxFrequencies.SelectedItem); } else if ((string)mpComboBoxTuningMode.SelectedItem == "ATSC Digital Terrestrial") { tuneChannel.PhysicalChannel = index; tuneChannel.Frequency = -1; tuneChannel.ModulationType = ModulationType.Mod8Vsb; line = string.Format("physical channel = {0}, modulation = 8 VSB", tuneChannel.PhysicalChannel); Log.Info("ATSC: scanning ATSC over-the-air, {0}", line); } else { tuneChannel.PhysicalChannel = 0; tuneChannel.ModulationType = ModulationType.Mod256Qam; line = "out-of-band service information"; Log.Info("ATSC: scanning digital cable, {0}", line); } line += "... "; ListViewItem item = listViewStatus.Items.Add(new ListViewItem(line)); item.EnsureVisible(); if (index == minchan) { RemoteControl.Instance.Scan(ref user, tuneChannel, -1); } IChannel[] channels = RemoteControl.Instance.Scan(_cardNumber, tuneChannel); UpdateStatus(); if (channels == null || channels.Length == 0) { if (tuneChannel.PhysicalChannel > 0 && !RemoteControl.Instance.TunerLocked(_cardNumber)) { line += "no signal"; } else { line += "signal locked, no channels found"; } item.Text = line; item.ForeColor = Color.Red; continue; } int newChannels = 0; int updatedChannels = 0; for (int i = 0; i < channels.Length; ++i) { Channel dbChannel; ATSCChannel channel = (ATSCChannel)channels[i]; //No support for channel moving, or merging with existing channels here. //We do not know how ATSC works to correctly implement this. TuningDetail currentDetail = layer.GetTuningDetail(channel); if (currentDetail != null) { if (channel.IsDifferentTransponder(layer.GetTuningChannel(currentDetail))) { currentDetail = null; } } bool exists; if (currentDetail == null) { //add new channel exists = false; dbChannel = layer.AddNewChannel(channel.Name, channel.LogicalChannelNumber); dbChannel.SortOrder = 10000; if (channel.LogicalChannelNumber >= 1) { dbChannel.SortOrder = channel.LogicalChannelNumber; } } else { exists = true; dbChannel = currentDetail.ReferencedChannel(); } dbChannel.IsTv = channel.IsTv; dbChannel.IsRadio = channel.IsRadio; dbChannel.Persist(); if (dbChannel.IsTv) { layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.AllChannels); } if (dbChannel.IsRadio) { layer.AddChannelToRadioGroup(dbChannel, TvConstants.RadioGroupNames.AllChannels); } 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) { tvChannelsUpdated++; updatedChannels++; } else { tvChannelsNew++; newChannels++; } } if (channel.IsRadio) { if (exists) { radioChannelsUpdated++; updatedChannels++; } else { radioChannelsNew++; newChannels++; } } layer.MapChannelToCard(card, dbChannel, false); } line += string.Format("new = {0}, updated = {1}", newChannels, updatedChannels); item.Text = line; Log.Info("ATSC: scan result, new = {0}, updated = {1}", newChannels, updatedChannels); } } catch (Exception ex) { Log.Write(ex); } finally { IUser user = new User(); user.CardId = _cardNumber; RemoteControl.Instance.StopCard(user); RemoteControl.Instance.EpgGrabberEnabled = true; progressBar1.Value = 100; mpComboBoxTuningMode.Enabled = true; UpdateQamFrequencyFieldAvailability(); mpButtonScanTv.Text = buttonText; _isScanning = false; } listViewStatus.Items.Add( new ListViewItem(String.Format("Total radio channels, new = {0}, updated = {1}", radioChannelsNew, radioChannelsUpdated))); listViewStatus.Items.Add( new ListViewItem(String.Format("Total TV channels, new = {0} updated = {1}", tvChannelsNew, tvChannelsUpdated))); ListViewItem lastItem = listViewStatus.Items.Add(new ListViewItem("Scan done!")); lastItem.EnsureVisible(); Log.Info("ATSC: scan summary, new TV = {0}, updated TV = {1}, new radio = {2}, updated radio = {3}", tvChannelsNew, tvChannelsUpdated, radioChannelsNew, radioChannelsUpdated); }