/// <summary> /// Prüft, ob eine Aufzeichnung läuft oder in Kürze beginnt. /// </summary> public override void KeepAlive() { // Read results var activities = (m_allActivities ?? Enumerable.Empty <VCRNETRestProxy.Current>()).Where(activity => ProfileManager.ProfileNameComparer.Equals(activity.device, Profile)).ToArray(); var running = activities.Where(activity => activity.IsActive).ToArray(); var gotResult = m_allActivitiesValid; // Prepare for next call m_allActivities = null; m_allActivitiesValid = false; // See if result is available if (gotResult) { if (running.Length > 0) { ValidateActiveRecording(running); } else if (activities.Length > 0) { ValidateIdle(activities[0]); } else { Adaptor.StartLIVE(); } } else { VCRNETRestProxy.GetActivities(Adaptor.EndPoint, ReceiveCurrentRecording, null); } }
/// <summary> /// Trägt zusätzliche Konfigurationsoptionen in die Liste aller Konfigurationseinträge ein. /// </summary> public override void FillOptions() { // Request all var profiles = VCRNETRestProxy.GetProfilesSync(EndPoint).Select(profile => profile.name).ToArray(); // Process all foreach (var profile in profiles) { // Format to use string format = Properties.Resources.OptionProfile; // See if this is active if (string.IsNullOrEmpty(Profile) && ProfileManager.ProfileNameComparer.Equals(profiles[0], profile)) { format = Properties.Resources.OptionProfileActive; } else if (ProfileManager.ProfileNameComparer.Equals(Profile, profile)) { format = Properties.Resources.OptionProfileActive; } else { format = Properties.Resources.OptionProfile; } // Register - Clone() is important since anonymous delegate would bind profile to the last iteration value for ALL items Parent.AddOption(new OptionDisplay(string.Format(format, profile), () => ChangeProfile(profile))); } // Forward m_CurrentConnector.FillOptions(); }
/// <summary> /// Wählt einen NVOD Dienst aus. /// </summary> /// <param name="service">Der gewünschte Dienst.</param> /// <returns>Name des Dienstes inklusive der aktuellen Tonspur oder /// <i>null</i>, wenn eine Aktivierung des Dienstes nicht möglich war.</returns> public override string SetService(ServiceItem service) { // Must be a known channel VCRNETRestProxy.Source source; if (!Sources.TryGetValue(service.Identifier, out source)) { return(null); } // Stop sending data Accessor.Stop(); // Tune VCRNETRestProxy.TuneSync(m_serverRoot, Profile, SourceIdentifier.ToString(service.Identifier)); // Got the portal if (service.Index == 0) { // Reset CurrentService = null; // Done return(source.nameWithProvider); } // Got a real service CurrentService = service.Name; // Done return(CurrentService); }
/// <summary> /// Beim Wechsel des Profils wird die Verbindung zum VCR.NET gelöst. /// </summary> public override void OnProfileChanging() { // Forget the status m_LastStatus = null; // Stop LIVE mode VCRNETRestProxy.DisconnectSync(m_serverRoot, Profile); }
/// <summary> /// Wird aktiviert, wenn das Zugriffsmodul Daten anfordert. /// </summary> public override void OnWaitData() { // Already done if (m_Disposed) { return; } // Still calling? if (m_Waiting) { return; } // Test for move request if (m_Move.HasValue) { // Take it if (m_Length.HasValue) { m_Position = (long)(m_Move.Value * m_Length.Value); } // Forget m_Move = null; } else { // See how internal timing is currently set var offset = Accessor.StreamTimeOffset; if (offset.HasValue) { if (offset.Value < RestartTrigger) { // Try restart if (!RestartRecording()) { return; } } else if (offset.Value >= MaximumAheadTime) { // Do not feed any more data - for now return; } } } // Split off var parts = Adaptor.Target.Split(':'); // Request will start right now m_Waiting = true; // Force server to send data VCRNETRestProxy.RequestFilePart(Adaptor.EndPoint, m_Path, m_Position, ChunkSize, parts[0], ushort.Parse(parts[1]), DataAvailable, null); }
/// <summary> /// Erzeugt eine neue Zugriffsinstanz. /// </summary> /// <param name="main">Die zugehörige Anwendung.</param> /// <param name="replayPath">Pfad zu einer VCR.NET Aufzeichnungsdatei.</param> public VCRAdaptor(IViewerSite main, string replayPath) : base(main) { // Connect to alternate interfaces ChannelInfo = (IChannelInfo)main; StreamInfo = (IStreamInfo)main; // Remember m_Profile = RemoteInfo.VCRProfile; // Use default if (string.IsNullOrEmpty(m_Profile)) { m_Profile = "*"; } // Construct Url Uri uri = RemoteInfo.ServerUri; // Connect to stream Connect(StreamInfo.BroadcastIP, StreamInfo.BroadcastPort, uri.Host); // Check startup mode if (string.IsNullOrEmpty(replayPath)) { // Special if LIVE is active var current = VCRNETRestProxy.GetFirstActivityForProfile(EndPoint, Profile); if (current != null) { if (!current.IsActive) { current = null; } else if ("LIVE".Equals(current.name)) { current = null; } } // Start correct access module if (current == null) { StartLIVE(true); } else { StartWatch(null, true); } } else { // Start remote file replay StartReplay(replayPath, null, null, true); } }
/// <summary> /// Erzeugt eine neue Zugriffsinstanz. /// </summary> /// <param name="main">Die zugehörige Anwendung.</param> /// <param name="streamIndex">Teilaufzeichnung, die betrachtet werden soll.</param> /// <param name="timeshift">Gesetzt, wenn der Timeshift Modus aktiviert werden soll.</param> public VCRAdaptor(IViewerSite main, int streamIndex, bool timeshift) : base(main) { // Connect to alternate interfaces ChannelInfo = (IChannelInfo)main; StreamInfo = (IStreamInfo)main; // Remember m_Profile = RemoteInfo.VCRProfile; // Use default if (string.IsNullOrEmpty(m_Profile)) { m_Profile = "*"; } // Construct Url var uri = RemoteInfo.ServerUri; // Connect to stream Connect(StreamInfo.BroadcastIP, StreamInfo.BroadcastPort, uri.Host); // Find all current activities var activities = VCRNETRestProxy.GetActivitiesForProfile(EndPoint, Profile); if (activities.Count < 1) { StartLIVE(true); } else { // Find the activity var current = activities.FirstOrDefault(activity => activity.streamIndex == streamIndex); if (current == null) { StartWatch(null, true); } else if (timeshift && string.IsNullOrEmpty(StreamInfo.BroadcastIP) && (current.files.Length > 0)) { StartReplay(current.files[0], current.name, current, true); } else { StartWatch(string.Format("dvbnet:{0}", streamIndex), true); } } }
/// <summary> /// Prüft die Liste der aktiven Aufzeichnungen. /// </summary> /// <param name="activities">Eine nicht leere Liste von aktiven Auzeichnungen.</param> private void ValidateActiveRecording(VCRNETRestProxy.Current[] activities) { // Check for special operations var first = activities[0]; var current = m_CurrentSource; // See if there is a task running if (first.streamIndex < 0) { ShowMessage(Properties.Resources.CurrentUntil, Properties.Resources.Warning_NotAvailable, false, first.source, first.EndsAt.ToLocalTime()); } // See if we have no current source else if (current == null) { // Start watching Adaptor.StartWatch(null); // Done return; } // Check for current stream else { // Set if we are connected var newCurrent = activities.First(activity => activity.referenceId.Value == current.Activity.referenceId.Value); if (newCurrent != null) { if (string.IsNullOrEmpty(newCurrent.streamTarget)) { // Start watching Adaptor.StartWatch(null); // Done return; } } } // Restart request VCRNETRestProxy.GetActivities(Adaptor.EndPoint, ReceiveCurrentRecording, null); }
/// <summary> /// Wählt einen neuen Sender. /// </summary> /// <param name="context">Der zu wählende Sender.</param> /// <returns>Name des neuen Senders inklsuive der gewählten Tonspur /// oder <i>null</i>.</returns> public override string SetStation(object context) { // Stop sending data Accessor.Stop(); // Restart videotext caching from scratch Adaptor.VideoText.Deactivate(true); // Change type var source = (VCRNETRestProxy.Source)context; // Change the program VCRNETRestProxy.TuneSync(m_serverRoot, Profile, source.source); // Remember CurrentSource = source; CurrentService = null; // Store to settings return(Adaptor.RemoteInfo.VCRStation = source.nameWithProvider); }
/// <summary> /// Prüft, ob in den LIVE Modus gewechselt werden kann. /// </summary> /// <param name="next">Die als nächstens anstehende Aktivität.</param> private void ValidateIdle(VCRNETRestProxy.Current next) { // Get the next recording if (next.start.HasValue) { // When will it start var delta = next.start.Value - DateTime.UtcNow; if (delta.TotalMinutes <= 3) { // Report ShowMessage(Properties.Resources.NextRecording, Properties.Resources.Warning_NotAvailable, false, (int)delta.TotalSeconds); // Restart request VCRNETRestProxy.GetActivities(Adaptor.EndPoint, ReceiveCurrentRecording, null); // Done return; } } // Can use LIVE Adaptor.StartLIVE(); }
/// <summary> /// Startet eine Aufzeichnung im VCR.NET auf dem aktuellen Sender. /// </summary> /// <param name="duration"></param> private void StartRecording(int duration) { // Read the status var status = VCRNETRestProxy.GetStatusSync(m_serverRoot, Profile); // Not connected to us if (!StringComparer.InvariantCultureIgnoreCase.Equals(status.target, Adaptor.Target)) { return; } // Configure the new schedule var schedule = new VCRNETRestProxy.Schedule { lastDay = new DateTime(2999, 12, 31), name = "Gestartet vom DVB.NET Viewer", firstStart = DateTime.UtcNow, duration = duration, }; // Configure the new job var job = new VCRNETRestProxy.Job { sourceName = CurrentSource.nameWithProvider, name = "Manuelle Aufzeichnung", withSubtitles = true, withVideotext = true, includeDolby = true, allLanguages = true, device = Profile, }; // Send it VCRNETRestProxy.CreateNewSync(Adaptor.EndPoint, job, schedule); }
/// <summary> /// Prüft, ob der zugehörige VCR.NET noch im LIVE Modus Daten an die /// aktuelle Anwendung sendet. Ist das nicht der Fall, wird mit in /// zur Anzeige der aktuellen Aufzeichnung gewechselt. /// </summary> public override void KeepAlive() { // Read the status var status = m_LastStatus; // Clear it m_LastStatus = null; // Not connected to us if (status != null) { if (!StringComparer.InvariantCultureIgnoreCase.Equals(status.target, Adaptor.Target)) { // Switch mode Adaptor.StartWatch(null); // Done return; } } // Restart request VCRNETRestProxy.GetStatus(m_serverRoot, Profile, newState => m_LastStatus = newState, null); }
/// <summary> /// Ermittelt die Liste der verfügbaren Aufzeichnungen. /// </summary> public override void LoadStations() { // Index to set default upon int startupIndex = -1; // Special if (m_StartupStation != null) { if (m_StartupStation.StartsWith("dvbnet:")) { // Get the index startupIndex = int.Parse(m_StartupStation.Substring(7)); // No direct default m_StartupStation = null; } } // Reset current channel m_DefaultStation = m_StartupStation; m_StartupStation = null; // Forbid restriction on channels Favorites.DisableFavorites(); // All names already in use var duplicates = new Dictionary <string, int>(); // Find all current activities foreach (var activity in VCRNETRestProxy.GetActivitiesForProfile(Adaptor.EndPoint, Profile)) { // Create the information record var item = new JobScheduleInfo(activity); var name = activity.name; // Read counter int cnt; if (duplicates.TryGetValue(name, out cnt)) { name = string.Format("{0} ({1})", name, cnt); } else { cnt = 0; } // Store back duplicates[name] = ++cnt; // Add to list Favorites.AddChannel(name, item); // Remember if (m_DefaultStation == null) { if ((startupIndex < 0) || (startupIndex == activity.streamIndex)) { m_DefaultStation = name; } } } // Finish Favorites.FillChannelList(); }
/// <summary> /// Aktiviert den Netzwerkempfang. /// </summary> /// <param name="endPoint">Der zugehörige <i>VCR.NET Recording Service</i>.</param> /// <param name="target">Die Zieladresse des Netzwerkversands.</param> public void StreamTo(string endPoint, string target) { // Forward VCRNETRestProxy.SetStreamTargetSync(endPoint, Activity.device, Activity.source, Activity.referenceId.Value, target); }
/// <summary> /// Ermittelt die aktuelle Senderliste. /// </summary> public override void LoadStations() { // Allow restriction on channels Favorites.EnableFavorites(); // Reset all CurrentSource = null; CurrentService = null; Sources.Clear(); // Check free TV mode var free = Adaptor.ChannelInfo.FreeTV; var pay = Adaptor.ChannelInfo.PayTV; // Check service type var radio = Adaptor.ChannelInfo.UseRadio; var tv = Adaptor.ChannelInfo.UseTV; // Get radio and video separatly for (int radioFlag = 2; radioFlag-- > 0;) { foreach (var source in VCRNETRestProxy.ReadSourcesSync(m_serverRoot, Profile, radioFlag == 0, radioFlag == 1)) { // Add anything to map Sources[SourceIdentifier.Parse(source.source)] = source; // Check type if (radioFlag == 1) { // See if radio is allowed if (tv && !radio) { continue; } } else { // See if TV is allowed if (radio && !tv) { continue; } } // Check encryption if (source.encrypted) { // Only if encrypted is allowed if (free && !pay) { continue; } } else { // Only if free is allowed if (pay && !free) { continue; } } // Process Favorites.AddChannel(source.nameWithProvider, source); } } // Finished Favorites.FillChannelList(); }
/// <summary> /// Stellt eine neue Verbindung zu VCR.NET her. /// </summary> public override void OnProfileChanged() { // Start LIVE mode VCRNETRestProxy.ConnectSync(m_serverRoot, Profile, Adaptor.Target); }
/// <summary> /// Beendet die Nutzung dieser Kommunikationsinstanz endgültig. /// </summary> protected override void OnDispose() { // Release network ressources VCRNETRestProxy.DisconnectSync(m_serverRoot, Profile); }