public override byte[] GetTeletextPageBytes(LiveStream liveStream, int pageNumber, int subPageNumber, out int subPageCount) { subPageCount = 0; if (liveStream.Channel.ChannelType == ChannelType.Television) { try { if (_liveStreams.ContainsKey(liveStream.RtspUrl)) { IUser tve3User = _liveStreamUsers[liveStream.RtspUrl]; byte[] result = TvServerPlugin.TvController_GetTeletextPage(tve3User, pageNumber, subPageNumber); if (result != null) { subPageCount = TvServerPlugin.TvController_SubPageCount(tve3User, pageNumber); } return(result); } } catch (Exception ex) { Log(TraceEventType.Error, ex.Message); } } return(null); }
public override void StopLiveStream(LiveStream liveStream) { lock (_liveStreamsLock) { try { if (_liveStreams.ContainsKey(liveStream.RtspUrl)) { IUser tve3User = _liveStreamUsers[liveStream.RtspUrl]; #if USE_ARGUS_RTSP StopRtspStream(liveStream); #endif if (TvServerPlugin.TvController_IsTimeShifting(ref tve3User)) { if (!TvServerPlugin.TvController_StopTimeShifting(ref tve3User)) { Log(TraceEventType.Error, "Failed to stop live stream '{0}'", liveStream.RtspUrl); } } _liveStreams.Remove(liveStream.RtspUrl); _liveStreamUsers.Remove(liveStream.RtspUrl); } CleanUpTimeshiftingFiles(liveStream.TimeshiftFile); } catch (Exception ex) { Log(TraceEventType.Error, ex.Message); } } }
public static bool CardFreeOrUsingSameTransponder(TvDatabase.Card card, TvDatabase.Channel channel, IUser userToIgnore) { IUser[] cardUsers = TvServerPlugin.TvController_GetUsersForCard(card.IdCard); if (cardUsers != null) { TvDatabase.TuningDetail tuning = Utility.FindTuningDetailOnCard(channel, card.IdCard); HashSet <int> activeChannels = new HashSet <int>(); foreach (IUser cardUser in cardUsers) { if (userToIgnore == null || cardUser.Name != userToIgnore.Name) { if (!cardUser.Name.Equals("epg", StringComparison.InvariantCultureIgnoreCase)) { activeChannels.Add(cardUser.IdChannel); if (!Utility.IsSameTransponder(card.IdCard, tuning, cardUser.IdChannel)) { return(false); } } } } return(activeChannels.Contains(channel.IdChannel) || card.DecryptLimit == 0 || activeChannels.Count < card.DecryptLimit); } return(true); }
protected override void OnError() { if (_tve3User != null && TvServerPlugin.TvController_IsRecording(ref _tve3User)) { StopMediaPortalRecording(_tve3User); } }
private void Resume() { if (_tvServerNeedsRestart && _restartTvServerOnResume) { TvServerPlugin.TvController_Restart(); } _tvServerNeedsRestart = false; }
private static string GetTsBufferFile(IUser tve3User) { string tsBufferFile = TvServerPlugin.TvController_TimeShiftFileName(ref tve3User); string uncTimeshiftFolder = ArgusTV.Recorders.Common.ShareExplorer.GetUncPathForLocalPath(Path.GetDirectoryName(tsBufferFile)); if (!String.IsNullOrEmpty(uncTimeshiftFolder)) { return(Path.Combine(uncTimeshiftFolder, Path.GetFileName(tsBufferFile))); } return(null); }
private bool EnsureCardFree(bool allowOtherArgusUser, ref string errorMessage, out bool argusIsRecordingOnCard) { argusIsRecordingOnCard = false; IUser[] cardUsers = TvServerPlugin.TvController_GetUsersForCard(_recordOnCard.IdCard); if (cardUsers != null) { TvDatabase.TuningDetail tuning = Utility.FindTuningDetailOnCard(_channel, _recordOnCard.IdCard); foreach (IUser cardUser in cardUsers) { if (!cardUser.Name.Equals("epg", StringComparison.InvariantCultureIgnoreCase)) { if (cardUser.Name.StartsWith("ArgusTV")) { if (!allowOtherArgusUser && !Utility.IsSameTransponder(_recordOnCard.IdCard, tuning, cardUser.IdChannel)) { // Seems another ARGUS TV user is using this card, but on a different // transponder! Normally this should never happen, but in rare conditions // we need to be able to handle this. errorMessage = "Card is in use by previous recording"; argusIsRecordingOnCard = true; return(false); } } else { IUser tmpUser = cardUser; if (TvServerPlugin.TvController_IsRecording(ref tmpUser)) { if (!TvServerPlugin.TvController_StopRecording(ref tmpUser)) { errorMessage = "Failed to stop recording on channel " + _channel.DisplayName; return(false); } } else if (TvServerPlugin.TvController_IsTimeShifting(ref tmpUser)) { if (!Utility.IsSameTransponder(_recordOnCard.IdCard, tuning, tmpUser.IdChannel)) { if (!TvServerPlugin.TvController_StopTimeShifting(ref tmpUser, TvStoppedReason.RecordingStarted)) { errorMessage = "Failed to stop timeshifting on channel " + _channel.DisplayName; return(false); } } } } } } } return(true); }
private static bool StopMediaPortalRecording(IUser tve3User) { for (int count = 0; count < 60; count++) { try { if (TvServerPlugin.TvController_StopRecording(ref tve3User)) { return(true); } } catch { } Thread.Sleep(250); } return(false); }
public override void StopGrabbingTeletext(LiveStream liveStream) { if (liveStream.Channel.ChannelType == ChannelType.Television) { try { if (_liveStreams.ContainsKey(liveStream.RtspUrl)) { IUser tve3User = _liveStreamUsers[liveStream.RtspUrl]; TvServerPlugin.TvController_StopGrabbingTeletext(tve3User); } } catch (Exception ex) { Log(TraceEventType.Error, ex.Message); } } }
public static TvDatabase.TuningDetail FindTuningDetailOnCard(TvDatabase.Channel channel, int cardId) { try { CardType cardType = TvServerPlugin.TvController_Type(cardId); IList <TvDatabase.TuningDetail> tuningDetails = channel.ReferringTuningDetail(); foreach (TvDatabase.TuningDetail tuningDetail in tuningDetails) { if (CardTunesChannelType(cardType, tuningDetail.ChannelType)) { return(tuningDetail); } } } catch { } return(null); }
public override bool HasTeletext(LiveStream liveStream) { if (liveStream.Channel.ChannelType == ChannelType.Television) { try { if (_liveStreams.ContainsKey(liveStream.RtspUrl)) { IUser tve3User = _liveStreamUsers[liveStream.RtspUrl]; return(TvServerPlugin.TvController_HasTeletext(tve3User)); } } catch (Exception ex) { Log(TraceEventType.Error, ex.Message); } } return(false); }
public static IChannel FindTuningChannelOnCard(TvDatabase.Channel channel, int cardId) { IChannel tuningChannel = null; try { List <IChannel> tunings = new TvDatabase.TvBusinessLayer().GetTuningChannelsByDbChannel(channel); foreach (IChannel tuning in tunings) { if (TvServerPlugin.TvController_CanTune(cardId, tuning)) { tuningChannel = tuning; break; } } } catch { tuningChannel = null; } return(tuningChannel); }
public override bool KeepLiveStreamAlive(LiveStream liveStream) { lock (_liveStreamsLock) { if (_liveStreams.ContainsKey(liveStream.RtspUrl)) { _liveStreams[liveStream.RtspUrl].StreamLastAliveTimeUtc = liveStream.StreamLastAliveTimeUtc; IUser tve3User = _liveStreamUsers[liveStream.RtspUrl]; if (TvServerPlugin.TvController_IsTimeShifting(ref tve3User)) { TvServerPlugin.TvController_HeartBeat(tve3User); return(true); } else { _liveStreams.Remove(liveStream.RtspUrl); _liveStreamUsers.Remove(liveStream.RtspUrl); } } } return(false); }
public override ServiceTuning GetLiveStreamTuningDetails(LiveStream liveStream) { ServiceTuning result = null; lock (_liveStreamsLock) { if (_liveStreams.ContainsKey(liveStream.RtspUrl)) { IUser tve3User = _liveStreamUsers[liveStream.RtspUrl]; IChannel channel = TvServerPlugin.TvController_CurrentChannel(tve3User); var dvbSChannel = channel as TvLibrary.Channels.DVBSChannel; if (dvbSChannel != null) { result = new ServiceTuning() { CardType = ArgusTV.DataContracts.Tuning.CardType.DvbS, Frequency = (int)dvbSChannel.Frequency, InnerFecRate = (ArgusTV.DataContracts.Tuning.FecCodeRate)dvbSChannel.InnerFecRate, Modulation = (ArgusTV.DataContracts.Tuning.Modulation)dvbSChannel.ModulationType, Name = dvbSChannel.Name, ONID = dvbSChannel.NetworkId, OrbitalPosition = dvbSChannel.SatelliteIndex, // TODO: check if this is the right number Pilot = (ArgusTV.DataContracts.Tuning.Pilot)dvbSChannel.Pilot, ProviderName = dvbSChannel.Provider, IsFreeToAir = dvbSChannel.FreeToAir, RollOff = (ArgusTV.DataContracts.Tuning.RollOff)dvbSChannel.Rolloff, SID = dvbSChannel.ServiceId, SignalPolarisation = (ArgusTV.DataContracts.Tuning.SignalPolarisation)dvbSChannel.Polarisation, SymbolRate = dvbSChannel.SymbolRate, TSID = dvbSChannel.TransportId }; } else { var dvbCChannel = channel as TvLibrary.Channels.DVBCChannel; if (dvbCChannel != null) { result = new ServiceTuning() { CardType = ArgusTV.DataContracts.Tuning.CardType.DvbC, Frequency = (int)dvbCChannel.Frequency, Modulation = (ArgusTV.DataContracts.Tuning.Modulation)dvbCChannel.ModulationType, Name = dvbCChannel.Name, ONID = dvbCChannel.NetworkId, ProviderName = dvbCChannel.Provider, IsFreeToAir = dvbCChannel.FreeToAir, SID = dvbCChannel.ServiceId, SymbolRate = dvbCChannel.SymbolRate, TSID = dvbCChannel.TransportId }; } else { var dvbTChannel = channel as TvLibrary.Channels.DVBTChannel; if (dvbTChannel != null) { result = new ServiceTuning() { CardType = ArgusTV.DataContracts.Tuning.CardType.DvbT, Frequency = (int)dvbTChannel.Frequency, Bandwidth = dvbTChannel.BandWidth, Name = dvbTChannel.Name, ONID = dvbTChannel.NetworkId, ProviderName = dvbTChannel.Provider, IsFreeToAir = dvbTChannel.FreeToAir, SID = dvbTChannel.ServiceId, TSID = dvbTChannel.TransportId }; } else { var atscChannel = channel as TvLibrary.Channels.ATSCChannel; if (atscChannel != null) { result = new ServiceTuning() { CardType = ArgusTV.DataContracts.Tuning.CardType.Atsc, Frequency = (int)atscChannel.Frequency, MajorChannel = atscChannel.MajorChannel, MinorChannel = atscChannel.MinorChannel, Name = atscChannel.Name, PhysicalChannel = atscChannel.PhysicalChannel, ProviderName = atscChannel.Provider, IsFreeToAir = atscChannel.FreeToAir, SID = atscChannel.ServiceId, TSID = atscChannel.TransportId }; } else { var analogChannel = channel as TvLibrary.Implementations.AnalogChannel; if (analogChannel != null) { result = new ServiceTuning() { CardType = ArgusTV.DataContracts.Tuning.CardType.Analog, Frequency = (int)analogChannel.Frequency, Name = analogChannel.Name, IsFreeToAir = analogChannel.FreeToAir, PhysicalChannel = analogChannel.ChannelNumber }; } else { var dvbIPChannel = channel as TvLibrary.Channels.DVBIPChannel; if (dvbIPChannel != null) { result = new ServiceTuning() { CardType = ArgusTV.DataContracts.Tuning.CardType.DvbIP, Url = dvbIPChannel.Url, Name = dvbIPChannel.Name, ProviderName = dvbIPChannel.Provider, IsFreeToAir = dvbIPChannel.FreeToAir }; } } } } } } if (result != null) { result.SignalQuality = TvServerPlugin.TvController_SignalQuality(tve3User.CardId); result.SignalStrength = TvServerPlugin.TvController_SignalLevel(tve3User.CardId); } } } return(result); }
protected override string OnStartRecording(RecorderCallbackServiceAgent callbackAgent, ref string errorMessage) { string baseFileName = _suggestedBaseFileName; if (String.IsNullOrEmpty(baseFileName)) { baseFileName = Common.Utility.BuildRecordingBaseFileName(null, this.RecordingProgram); } else { this.UsedSuggestedBaseFileName = true; } string fileName = Path.Combine(_recordOnCard.RecordingFolder, baseFileName); string extension = (_recordOnCard.RecordingFormat == 0) ? ".ts" : ".mpg"; _tve3RecordingFileName = Common.Utility.GetFreeFileName(fileName, extension, 0); string tve3RecordingDirectory = Path.GetDirectoryName(_tve3RecordingFileName); if (!Directory.Exists(tve3RecordingDirectory)) { Directory.CreateDirectory(tve3RecordingDirectory); } string uncRecordingFolder = Common.ShareExplorer.GetUncPathForLocalPath(tve3RecordingDirectory); if (String.IsNullOrEmpty(uncRecordingFolder)) { errorMessage = "Failed to convert '" + Path.GetDirectoryName(_tve3RecordingFileName) + "' to UNC path, please add required share"; return(null); } bool argusIsRecordingOnCard; if (!EnsureCardFree(false, ref errorMessage, out argusIsRecordingOnCard)) { if (!WaitCardFree(argusIsRecordingOnCard, ref errorMessage)) { return(null); } } IChannel tuningChannel = Utility.FindTuningChannelOnCard(_channel, _recordOnCard.IdCard); if (tuningChannel == null) { errorMessage = "Failed to find tuning details for channel " + _channel.DisplayName; return(null); } // Make sure only one thread can tune and start a recording at the same time. lock (_startRecordingLock) { if (TvServerPlugin.TvController_Tune(ref _tve3User, tuningChannel, _channel.IdChannel) != TvResult.Succeeded) { errorMessage = "Failed to tune to channel " + _channel.DisplayName; return(null); } if (TvServerPlugin.TvController_StartRecording(ref _tve3User, ref _tve3RecordingFileName) != TvResult.Succeeded) { errorMessage = "TV Server failed to start recording on channel " + _channel.DisplayName; return(null); } } return(Path.Combine(uncRecordingFolder, Path.GetFileName(_tve3RecordingFileName))); }
public override LiveStream[] GetLiveStreams() { List <LiveStream> liveStreams = new List <LiveStream>(); lock (_liveStreamsLock) { try { // Get cards in reverse priority. List <TvDatabase.Card> cards = Utility.GetAllCards(); cards.Sort(delegate(TvDatabase.Card c1, TvDatabase.Card c2) { return(-c1.Priority.CompareTo(c2.Priority)); }); // Get the list of live streams from TV Server Dictionary <string, IUser> mpStreamUsers = new Dictionary <string, IUser>(); foreach (TvDatabase.Card card in cards) { IUser[] cardUsers = TvServerPlugin.TvController_GetUsersForCard(card.IdCard); if (cardUsers != null) { foreach (IUser user in cardUsers) { if (user.Name.StartsWith(_argusLiveUserName)) { IUser tve3User = user; if (TvServerPlugin.TvController_IsTimeShifting(ref tve3User)) { mpStreamUsers.Add(TvServerPlugin.TvController_GetStreamingUrl(tve3User), tve3User); } } } } } // Now loop our own list and check if all those streams are indeed still up. List <string> keysToRemove = new List <string>(); foreach (LiveStream stream in _liveStreams.Values) { if (mpStreamUsers.ContainsKey(stream.RtspUrl)) { liveStreams.Add(stream); } else { keysToRemove.Add(stream.RtspUrl); } } // Remove streams that no longer exist. foreach (string keyToRemove in keysToRemove) { _liveStreams.Remove(keyToRemove); _liveStreamUsers.Remove(keyToRemove); } // Check if there are any live streams within MP that we don't know about. // If so, stop those streams (they may be left-overs from client crashes). foreach (string rtspUrl in mpStreamUsers.Keys) { if (!_liveStreams.ContainsKey(rtspUrl)) { IUser tve3User = mpStreamUsers[rtspUrl]; TvServerPlugin.TvController_StopTimeShifting(ref tve3User, TvStoppedReason.KickedByAdmin); } } } catch (Exception ex) { Log(TraceEventType.Error, ex.Message); } } return(liveStreams.ToArray()); }
private LiveStreamResult StartTimeShifting(Channel channel, TvDatabase.Card card, TvDatabase.Channel mpChannel, ref IUser tve3User, ref LiveStream liveStream) { IChannel tuningChannel = Utility.FindTuningChannelOnCard(mpChannel, card.IdCard); if (tuningChannel != null) { if (TvServerPlugin.TvController_Tune(ref tve3User, tuningChannel, mpChannel.IdChannel) == TvResult.Succeeded) { string timeshiftFileName = Path.Combine(card.TimeShiftFolder, String.Format(CultureInfo.InvariantCulture, @"live{0}-{1}", tve3User.CardId, tve3User.SubChannel)); switch (TvServerPlugin.TvController_StartTimeShifting(ref tve3User, ref timeshiftFileName)) { case TvResult.Succeeded: if (liveStream == null) { string rtspUrl = TvServerPlugin.TvController_GetStreamingUrl(tve3User); string tsBufferFile = GetTsBufferFile(tve3User); liveStream = new LiveStream(channel, rtspUrl); liveStream.TimeshiftFile = tsBufferFile; #if USE_ARGUS_RTSP string rtspUrlSuffix = String.Format(_rtspUrlSuffixFormat, tve3User.CardId, tve3User.SubChannel); liveStream.RtspUrl = StartRtspStream(tsBufferFile, rtspUrlSuffix); #endif } liveStream.Channel = channel; liveStream.CardId = tve3User.CardId.ToString(CultureInfo.InvariantCulture); liveStream.StreamLastAliveTimeUtc = DateTime.UtcNow; lock (_liveStreamsLock) { _liveStreams[liveStream.RtspUrl] = liveStream; _liveStreamUsers[liveStream.RtspUrl] = tve3User; } return(LiveStreamResult.Succeeded); case TvResult.AllCardsBusy: return(LiveStreamResult.NoFreeCardFound); case TvResult.ChannelIsScrambled: return(LiveStreamResult.IsScrambled); case TvResult.ChannelNotMappedToAnyCard: case TvResult.NoSignalDetected: case TvResult.NoTuningDetails: case TvResult.NoVideoAudioDetected: case TvResult.UnknownChannel: return(LiveStreamResult.ChannelTuneFailed); default: return(LiveStreamResult.UnknownError); } } else { Log(TraceEventType.Error, "StartTimeShifting(): failed to tune to {0}", tuningChannel.Name); return(LiveStreamResult.ChannelTuneFailed); } } else { Log(TraceEventType.Error, "StartTimeShifting(): no tuning channel found for {0}", mpChannel.DisplayName); return(LiveStreamResult.ChannelTuneFailed); } }