public void ReportPCR() { // Prepare receiption var station = GetDefaultStation(); // Prepare selection var selection = new StreamSelection { Videotext = false, ProgramGuide = false }; // Add all selection.AC3Tracks.LanguageMode = LanguageModes.Selection; selection.SubTitles.LanguageMode = LanguageModes.Selection; selection.MP2Tracks.LanguageMode = LanguageModes.Primary; // Get a file name var tempFile = GetUniqueFile(); // Collected PCR data var pcrData = new Dictionary<long, TimeSpan>(); // Minium TimeSpan? minPCR = null; // Open it using (var streamManager = new SourceStreamsManager( Device, Profile, station.Source, selection )) { // Attach PCR handler streamManager.OnWritingPCR += ( path, position, packet ) => { // Test Assert.AreEqual( tempFile.FullName, path ); // Get the PCR TimeSpan pcr = Manager.GetPCR( packet ); // Remember minimum if (!minPCR.HasValue) minPCR = pcr; // Remember pcrData.Add( position, pcr ); }; // Send to file streamManager.CreateStream( tempFile.FullName, station ); // Process Thread.Sleep( 10000 ); // Done streamManager.CloseStream(); } // Must have some Assert.IsTrue( minPCR.HasValue ); // Report foreach (var pair in pcrData.OrderBy( p => p.Key )) Console.WriteLine( "{0:000000000}\t{1}\t{2}", pair.Key, pair.Value, pair.Value - minPCR.Value ); }
/// <summary> /// Erzeugt eine neue Beschreibung. /// </summary> /// <param name="uniqueIdentifier">Die eindeutige Kennung dieses Datenstroms.</param> /// <param name="manager">Die Verwaltung des Empfangs.</param> /// <param name="targetPath">Ein optionaler Dateiname zur Ablage der empfangenen Daten.</param> /// <param name="originalSelection">Die ursprünglich angeforderte Konfiguration der Aufzeichnung.</param> /// <exception cref="ArgumentNullException">Es wurde keine Verwaltung angegeben</exception> public ActiveStream( Guid uniqueIdentifier, SourceStreamsManager manager, StreamSelection originalSelection, string targetPath ) { // Validate if (manager == null) throw new ArgumentNullException( "manager" ); // Remember SourceKey = new SourceIdenfierWithKey( uniqueIdentifier, manager.Source ); RequestedStreams = originalSelection.Clone(); TargetPath = targetPath; Manager = manager; }
/// <summary> /// Erzeugt eine neue Beschreibung. /// </summary> /// <param name="uniqueIdentifier">Die eindeutige Kennung dieses Datenstroms.</param> /// <param name="manager">Die Verwaltung des Empfangs.</param> /// <param name="targetPath">Ein optionaler Dateiname zur Ablage der empfangenen Daten.</param> /// <param name="originalSelection">Die ursprünglich angeforderte Konfiguration der Aufzeichnung.</param> /// <exception cref="ArgumentNullException">Es wurde keine Verwaltung angegeben</exception> public ActiveStream(Guid uniqueIdentifier, SourceStreamsManager manager, StreamSelection originalSelection, string targetPath) { // Validate if (manager == null) { throw new ArgumentNullException("manager"); } // Remember SourceKey = new SourceIdenfierWithKey(uniqueIdentifier, manager.Source); RequestedStreams = originalSelection.Clone(); TargetPath = targetPath; Manager = manager; }
/// <summary> /// Versucht, möglichst viele der gewünschten Aspekte dieser Quelle zu aktivieren. /// </summary> /// <param name="disableOrder">Die Reihenfolge, in der Aspekte deaktiviert werden /// dürfen.</param> /// <param name="report">Protokolliert die vorgenommenen Veränderungen.</param> public void Optimize(StreamDisableSelector[] disableOrder, Action <SourceSelection, string, int> report) { // Already did it if (ConsumerCount.HasValue) { return; } // Number of consumers possible at all int available = 0; // Try to open try { // Create the manager using (SourceStreamsManager manager = Source.Open(OriginalStreams)) if (!manager.CreateStream(null)) { // Fake entry CurrentStreams = OriginalStreams.Clone(); ConsumerCount = 0; } else { // Remember CurrentStreams = manager.ActiveSelection; ConsumerCount = manager.ConsumerCount; } // Possible at least in stand-alone mode return; } catch (OutOfConsumersException e) { // Remember CurrentStreams = e.RequestedSelection; ConsumerCount = e.Requested; available = e.Available; } // What we need int needed = ConsumerCount.Value - available; // Process all modes for (int i = 0; (needed > 0) && (i < disableOrder.Length); ++i) { ApplyDisable(disableOrder[i], StreamDisableMode.Self, ref needed, report); } }
public void SplitFiles() { // Prepare receiption var station = GetDefaultStation(); // Prepare selection var selection = new StreamSelection { Videotext = true, ProgramGuide = false }; // Add all selection.AC3Tracks.LanguageMode = LanguageModes.All; selection.MP2Tracks.LanguageMode = LanguageModes.All; selection.SubTitles.LanguageMode = LanguageModes.All; // Get a file name var tempFile = GetUniqueFile(); // Get the file name pattern var filePattern = Path.Combine(tempFile.DirectoryName, Path.GetFileNameWithoutExtension(tempFile.Name)); // Open it using (var streamManager = new SourceStreamsManager(Device, Profile, station.Source, selection)) { // Send to file streamManager.CreateStream(string.Format(FileNamePattern, filePattern, 0), station); // Process for (int i = 0; i++ < 3; Thread.Sleep(10000)) { // Delay - first and last will have only half the size Thread.Sleep(10000); // New file Assert.IsTrue(streamManager.SplitFile(string.Format(FileNamePattern, filePattern, i))); } // Done streamManager.CloseStream(); // Report foreach (var file in streamManager.AllFiles) { Console.WriteLine(file); } } }
/// <summary> /// Beendet die Datenübertragung in den DirectShow Graphen und zusätzlich /// eine eventuell laufende Aufzeichnung. /// </summary> /// <param name="pictureOnly">Gesetzt, wenn die Aufzeichnung selbst weiter laufen soll.</param> private void StopReceivers(bool pictureOnly) { // Stop all consumers we registered Device.RemoveProgramGuideConsumer(ReceiveEPG); Device.SetConsumerState(VideoId, null); Device.SetConsumerState(AudioId, null); Device.SetConsumerState(TextId, null); // Restart videotext caching from scratch VideoText.Deactivate(true); // Partial mode if (pictureOnly) { return; } // Stop reader using (var reader = m_InfoReader) { // Forget m_InfoReader = null; // Enforce proper shutdown if (reader != null) { reader.Cancel(); } } // Reset flag m_HasPendingGroupInformation = false; // Stop portal parser if (null != ServiceParser) { // Stop it ServiceParser.Disable(); // Forget it ServiceParser = null; } // Stop recording, too using (SourceStreamsManager recording = RecordingStream) RecordingStream = null; }
/// <summary> /// Ermittelt eine möglicherweise eingeschränkte Datenstromauswahl. /// </summary> /// <param name="manager">Die Quelle, um die es geht.</param> /// <returns>Eine geeignete Auswahl.</returns> private StreamSelection GetOptimizedStreams(SourceStreamsManager manager) { // Not possible if (null == CurrentSelection) { return(null); } // What we want to record StreamSelection selection = new StreamSelection(); // Put it on selection.AC3Tracks.LanguageMode = LanguageModes.All; selection.MP2Tracks.LanguageMode = LanguageModes.All; selection.SubTitles.LanguageMode = LanguageModes.All; selection.ProgramGuide = true; selection.Videotext = true; // See if we are working on a limited device if (!Device.HasConsumerRestriction) { return(selection); } // Stop picture for a moment Device.SetConsumerState(VideoId, false); Device.SetConsumerState(AudioId, false); Device.SetConsumerState(TextId, false); // Require restart m_NeedRestart = true; // Create a brand new optimizer StreamSelectionOptimizer localOpt = new StreamSelectionOptimizer(); // Add the one stream localOpt.Add(CurrentSelection, selection); // Run the optimization localOpt.Optimize(); // Report result return(localOpt.GetStreams(0)); }
public void SplitFiles() { // Prepare receiption var station = GetDefaultStation(); // Prepare selection var selection = new StreamSelection { Videotext = true, ProgramGuide = false }; // Add all selection.AC3Tracks.LanguageMode = LanguageModes.All; selection.MP2Tracks.LanguageMode = LanguageModes.All; selection.SubTitles.LanguageMode = LanguageModes.All; // Get a file name var tempFile = GetUniqueFile(); // Get the file name pattern var filePattern = Path.Combine( tempFile.DirectoryName, Path.GetFileNameWithoutExtension( tempFile.Name ) ); // Open it using (var streamManager = new SourceStreamsManager( Device, Profile, station.Source, selection )) { // Send to file streamManager.CreateStream( string.Format( FileNamePattern, filePattern, 0 ), station ); // Process for (int i = 0; i++ < 3; Thread.Sleep( 10000 )) { // Delay - first and last will have only half the size Thread.Sleep( 10000 ); // New file Assert.IsTrue( streamManager.SplitFile( string.Format( FileNamePattern, filePattern, i ) ) ); } // Done streamManager.CloseStream(); // Report foreach (var file in streamManager.AllFiles) Console.WriteLine( file ); } }
/// <summary> /// Sucht eine Konfiguration der Teildatenströme, die eine Aufzeichnung aller Quellen /// eventuell mit Reduktion des Aufzeichnungsumfangs erlaubt. /// </summary> /// <param name="disableOrder">Die Liste der Aspekte, die ausgeblendet werden dürfen.</param> /// <returns>Die Anzahl der Quellen, die verwendet werden können.</returns> public int Optimize(params StreamDisableSelector[] disableOrder) { // No souces if (m_Sources.Count < 1) { return(m_Sources.Count); } // Total stream count int available; // No limit using (HardwareManager.Open()) { // Attach to the device Hardware device = m_Sources[0].Source.GetHardware(); // No limit at all if (!device.HasConsumerRestriction) { return(m_Sources.Count); } // Get all the active streams ushort[] activeStreams = device.GetActiveStreams(); // Ask for it available = device.Restrictions.ConsumerLimit.Value - activeStreams.Length; // None at all if (available < 1) { return(0); } // Stream managers in use List <SourceStreamsManager> managers = new List <SourceStreamsManager>(); try { // Create one by one for (int i = 0; i < m_Sources.Count; ++i) { // Attach SelectionInfo info = m_Sources[i]; // Create new manager SourceStreamsManager manager = info.Source.Open(info.OriginalStreams); // Remember for cleanupo managers.Add(manager); // See if source is available if (!manager.CreateStream(null)) { // Fake entry - will not be used info.CurrentStreams = info.OriginalStreams.Clone(); info.ConsumerCount = 0; } else { // Remember all we found info.CurrentStreams = manager.ActiveSelection; info.ConsumerCount = manager.ConsumerCount; } } // Whoo - can open it all as requested return(m_Sources.Count); } catch (OutOfConsumersException) { } finally { // Terminate all foreach (SourceStreamsManager manager in managers) { manager.Dispose(); } } // First try to make sure that each source can be opened in stand-alone mode foreach (SelectionInfo info in m_Sources) { info.Optimize(disableOrder, Report); } // Now simulate starting all - will try to get most out of the first one and so on for (int ixStream = 0; ixStream < m_Sources.Count; ixStream++) { // Attach to the item SelectionInfo current = m_Sources[ixStream]; // See how many additional streams will be needed int needed = current.ConsumerCount.Value - available; // Try to free some for (int ixDisable = 0; (needed > 0) && (ixDisable < disableOrder.Length);) { // Load the next option StreamDisableSelector disable = disableOrder[ixDisable++]; // Apply self current.ApplyDisable(disable, StreamDisableMode.Self, ref needed, Report); // Apply higher priorized for (int ixHigher = ixStream; (needed > 0) && (ixHigher-- > 0);) { m_Sources[ixHigher].ApplyDisable(disable, StreamDisableMode.Higher, ref needed, Report); } } // Should not be startet - we find no way to provide a proper subset of streams if (needed > 0) { return(ixStream); } // Back to what is left available = -needed; } // Not possible return(m_Sources.Count); } }
/// <summary> /// Beginnt oder beendet eine Aufzeichnung. /// <seealso cref="SetDirectory"/> /// </summary> public override void StartRecording() { // See if recording is running if (IsRecording) { // Stop it using (SourceStreamsManager manager = RecordingStream) RecordingStream = null; // Force restart m_NeedRestart = true; // Restart silently RestartStreams(); // Show up ShowMessage( Properties.Resources.RecordingFinished, Properties.Resources.RecordingTitle, true ); // Done return; } // No channel if (null == CurrentSelection) return; // Must have directory if (string.IsNullOrEmpty( LocalInfo.RecordingDirectory )) { // Ask user SetDirectory(); // No directory at all if (string.IsNullOrEmpty( LocalInfo.RecordingDirectory )) return; } // Create the name string filename = string.Format( "{0:yyyy-MM-dd HH-mm-ss} {1}.ts", DateTime.Now, StationName ); // Cleanup foreach (char bad in Path.GetInvalidFileNameChars()) filename = filename.Replace( bad, '_' ); // Extras filename = filename.Replace( '&', '_' ); // Create the target RecordingStream = CurrentSelection.Open( GetOptimizedStreams( null ) ); // Use for reconfigure if (Device.HasConsumerRestriction) RecordingStream.BeforeRecreateStream += GetOptimizedStreams; // Start it RecordingStream.CreateStream( Path.Combine( LocalInfo.RecordingDirectory, filename ) ); // Restart silently RestartStreams(); // Enable multicast broadcast if (!string.IsNullOrEmpty( StreamInfo.BroadcastIP ) && (StreamInfo.BroadcastPort > 0)) RecordingStream.StreamingTarget = string.Format( "*{0}:{1}", StreamInfo.BroadcastIP, StreamInfo.BroadcastPort ); // Show up ShowMessage( Properties.Resources.RecordingStarted, Properties.Resources.RecordingTitle, true ); }
/// <summary> /// Ermittelt eine möglicherweise eingeschränkte Datenstromauswahl. /// </summary> /// <param name="manager">Die Quelle, um die es geht.</param> /// <returns>Eine geeignete Auswahl.</returns> private StreamSelection GetOptimizedStreams( SourceStreamsManager manager ) { // Not possible if (null == CurrentSelection) return null; // What we want to record StreamSelection selection = new StreamSelection(); // Put it on selection.AC3Tracks.LanguageMode = LanguageModes.All; selection.MP2Tracks.LanguageMode = LanguageModes.All; selection.SubTitles.LanguageMode = LanguageModes.All; selection.ProgramGuide = true; selection.Videotext = true; // See if we are working on a limited device if (!Device.HasConsumerRestriction) return selection; // Stop picture for a moment Device.SetConsumerState( VideoId, false ); Device.SetConsumerState( AudioId, false ); Device.SetConsumerState( TextId, false ); // Require restart m_NeedRestart = true; // Create a brand new optimizer StreamSelectionOptimizer localOpt = new StreamSelectionOptimizer(); // Add the one stream localOpt.Add( CurrentSelection, selection ); // Run the optimization localOpt.Optimize(); // Report result return localOpt.GetStreams( 0 ); }
/// <summary> /// Beendet die Datenübertragung in den DirectShow Graphen und zusätzlich /// eine eventuell laufende Aufzeichnung. /// </summary> /// <param name="pictureOnly">Gesetzt, wenn die Aufzeichnung selbst weiter laufen soll.</param> private void StopReceivers( bool pictureOnly ) { // Stop all consumers we registered Device.RemoveProgramGuideConsumer( ReceiveEPG ); Device.SetConsumerState( VideoId, null ); Device.SetConsumerState( AudioId, null ); Device.SetConsumerState( TextId, null ); // Restart videotext caching from scratch VideoText.Deactivate( true ); // Partial mode if (pictureOnly) return; // Stop reader using (var reader = m_InfoReader) { // Forget m_InfoReader = null; // Enforce proper shutdown if (reader != null) reader.Cancel(); } // Reset flag m_HasPendingGroupInformation = false; // Stop portal parser if (null != ServiceParser) { // Stop it ServiceParser.Disable(); // Forget it ServiceParser = null; } // Stop recording, too using (SourceStreamsManager recording = RecordingStream) RecordingStream = null; }
public void ReportPCR() { // Prepare receiption var station = GetDefaultStation(); // Prepare selection var selection = new StreamSelection { Videotext = false, ProgramGuide = false }; // Add all selection.AC3Tracks.LanguageMode = LanguageModes.Selection; selection.SubTitles.LanguageMode = LanguageModes.Selection; selection.MP2Tracks.LanguageMode = LanguageModes.Primary; // Get a file name var tempFile = GetUniqueFile(); // Collected PCR data var pcrData = new Dictionary <long, TimeSpan>(); // Minium TimeSpan?minPCR = null; // Open it using (var streamManager = new SourceStreamsManager(Device, Profile, station.Source, selection)) { // Attach PCR handler streamManager.OnWritingPCR += (path, position, packet) => { // Test Assert.AreEqual(tempFile.FullName, path); // Get the PCR TimeSpan pcr = Manager.GetPCR(packet); // Remember minimum if (!minPCR.HasValue) { minPCR = pcr; } // Remember pcrData.Add(position, pcr); }; // Send to file streamManager.CreateStream(tempFile.FullName, station); // Process Thread.Sleep(10000); // Done streamManager.CloseStream(); } // Must have some Assert.IsTrue(minPCR.HasValue); // Report foreach (var pair in pcrData.OrderBy(p => p.Key)) { Console.WriteLine("{0:000000000}\t{1}\t{2}", pair.Key, pair.Value, pair.Value - minPCR.Value); } }
/// <summary> /// Beginnt oder beendet eine Aufzeichnung. /// <seealso cref="SetDirectory"/> /// </summary> public override void StartRecording() { // See if recording is running if (IsRecording) { // Stop it using (SourceStreamsManager manager = RecordingStream) RecordingStream = null; // Force restart m_NeedRestart = true; // Restart silently RestartStreams(); // Show up ShowMessage(Properties.Resources.RecordingFinished, Properties.Resources.RecordingTitle, true); // Done return; } // No channel if (null == CurrentSelection) { return; } // Must have directory if (string.IsNullOrEmpty(LocalInfo.RecordingDirectory)) { // Ask user SetDirectory(); // No directory at all if (string.IsNullOrEmpty(LocalInfo.RecordingDirectory)) { return; } } // Create the name string filename = string.Format("{0:yyyy-MM-dd HH-mm-ss} {1}.ts", DateTime.Now, StationName); // Cleanup foreach (char bad in Path.GetInvalidFileNameChars()) { filename = filename.Replace(bad, '_'); } // Extras filename = filename.Replace('&', '_'); // Create the target RecordingStream = CurrentSelection.Open(GetOptimizedStreams(null)); // Use for reconfigure if (Device.HasConsumerRestriction) { RecordingStream.BeforeRecreateStream += GetOptimizedStreams; } // Start it RecordingStream.CreateStream(Path.Combine(LocalInfo.RecordingDirectory, filename)); // Restart silently RestartStreams(); // Enable multicast broadcast if (!string.IsNullOrEmpty(StreamInfo.BroadcastIP) && (StreamInfo.BroadcastPort > 0)) { RecordingStream.StreamingTarget = string.Format("*{0}:{1}", StreamInfo.BroadcastIP, StreamInfo.BroadcastPort); } // Show up ShowMessage(Properties.Resources.RecordingStarted, Properties.Resources.RecordingTitle, true); }