/// <summary> /// Erzeugt einen Aufzeichnungskontext für eine Quelle. /// </summary> /// <param name="selection">Die Informationen zur Quelle.</param> /// <param name="streams">Die gewünschten Aufzeichnungsparameter.</param> /// <returns>Eine Kontrollinstanz für die Aufzeichnung. Diese muss mittels <see cref="IDisposable.Dispose"/> /// freigegeben werden.</returns> public static SourceStreamsManager Open(this SourceSelection selection, StreamSelection streams) { // Validate if (selection == null) { throw new ArgumentNullException("selection"); } else { return(selection.Source.Open(selection.GetHardware(), selection.GetLeafProfile(), streams)); } }
/// <summary> /// Erzeugt eine Kopie dieser Auswahlbeschreibung. /// </summary> /// <returns>Die gewünschte Kopie.</returns> public StreamSelection Clone() { // Create core StreamSelection clone = new StreamSelection(); // Fill clone.AC3Tracks.Languages.AddRange( AC3Tracks.Languages ); clone.MP2Tracks.Languages.AddRange( MP2Tracks.Languages ); clone.SubTitles.Languages.AddRange( SubTitles.Languages ); clone.AC3Tracks.LanguageMode = AC3Tracks.LanguageMode; clone.MP2Tracks.LanguageMode = MP2Tracks.LanguageMode; clone.SubTitles.LanguageMode = SubTitles.LanguageMode; clone.ProgramGuide = ProgramGuide; clone.Videotext = Videotext; // Report return clone; }
/// <summary> /// Erzeugt eine Kopie dieser Auswahlbeschreibung. /// </summary> /// <returns>Die gewünschte Kopie.</returns> public StreamSelection Clone() { // Create core StreamSelection clone = new StreamSelection(); // Fill clone.AC3Tracks.Languages.AddRange(AC3Tracks.Languages); clone.MP2Tracks.Languages.AddRange(MP2Tracks.Languages); clone.SubTitles.Languages.AddRange(SubTitles.Languages); clone.AC3Tracks.LanguageMode = AC3Tracks.LanguageMode; clone.MP2Tracks.LanguageMode = MP2Tracks.LanguageMode; clone.SubTitles.LanguageMode = SubTitles.LanguageMode; clone.ProgramGuide = ProgramGuide; clone.Videotext = Videotext; // Report return(clone); }
/// <summary> /// Erzeugt eine neue Verwaltung. /// </summary> /// <param name="hardware">Das Gerät, auf dem die zugehörige Quellgruppe gerade aktiv ist.</param> /// <param name="profile">Optional das Geräteprofil mit der zugehörigen Senderliste.</param> /// <param name="source">Die Quelle, die zu betrachten ist.</param> /// <param name="selection">Die zu betrachtenden Datenströme.</param> /// <exception cref="ArgumentNullException">Ein Parameter wurde nicht angegeben.</exception> public SourceStreamsManager(Hardware hardware, Profile profile, SourceIdentifier source, StreamSelection selection) { // Validate if (null == hardware) { throw new ArgumentNullException("hardware"); } if (null == source) { throw new ArgumentNullException("source"); } if (null == selection) { throw new ArgumentNullException("selection"); } // Remember all StreamSelection = selection; Hardware = hardware; Profile = profile; Source = source; }
/// <summary> /// Beginnt die Aufzeichnung in einen <i>Transport Stream</i> - optional als /// Datei. /// </summary> /// <param name="nextPID">Die erste Datenstromkennung (PID), die in der Aufzeichnungsdatei verwendet werden darf.</param> /// <param name="recreate">Gesetzt, wenn ein Neustart aufgrund veränderter Nutzdatenströme erforderlich wurde.</param> /// <exception cref="ArgumentException">Eine Aufzeichnung der angegebenen Quelle ist nicht möglich.</exception> private void CreateStream( short nextPID, bool recreate ) { // Try to get the full name var filePath = m_OriginalPath; if (filePath != null) if (m_FileCount > 0) { // Split off the parts var name = Path.GetFileNameWithoutExtension( filePath ); var dir = Path.GetDirectoryName( filePath ); var ext = Path.GetExtension( filePath ); // Construct new name filePath = Path.Combine( dir, $"{name} - {m_FileCount}{ext}" ); } // Try to decrypt if (m_Decrypting = m_OriginalSettings.IsEncrypted) try { // Process Hardware.Decrypt( Source ); } catch { // Ignore any error m_Decrypting = false; } // Type of the video EPG.StreamTypes? videoType; // Video first if (m_OriginalSettings.VideoStream == 0) videoType = null; else videoType = (m_OriginalSettings.VideoType == VideoTypes.H264) ? EPG.StreamTypes.H264 : EPG.StreamTypes.Video13818; // Get the buffer size var bufferSize = (FileBufferSizeChooser == null) ? null : FileBufferSizeChooser( videoType ); // Create the new stream m_TransportStream = new Manager( filePath, nextPID, bufferSize.GetValueOrDefault( Manager.DefaultBufferSize ) ); // Attach PCR sink m_TransportStream.OnWritingPCR = m_WritePCRSink; // Report of the actually selected streams StreamSelection result = new StreamSelection(); // Cleanup on any error try { // Video first if (videoType.HasValue) AddConsumer( m_OriginalSettings.VideoStream, StreamTypes.Video, m_TransportStream.AddVideo( (byte) videoType.Value ) ); // Select audio ProcessAudioSelection( AudioTypes.MP2, result.MP2Tracks, StreamSelection.MP2Tracks ); ProcessAudioSelection( AudioTypes.AC3, result.AC3Tracks, StreamSelection.AC3Tracks ); // Videotext if (StreamSelection.Videotext) if (0 != m_OriginalSettings.TextStream) { // Register AddConsumer( m_OriginalSettings.TextStream, StreamTypes.VideoText, m_TransportStream.AddTeleText() ); // Remember result.Videotext = true; } // Subtitle streams var subtitles = new Dictionary<ushort, List<EPG.SubtitleInfo>>(); // Preset mode result.SubTitles.LanguageMode = LanguageModes.All; // All audio // Subtitles foreach (var subtitle in m_OriginalSettings.Subtitles) { // Check for primary if (StreamSelection.SubTitles.LanguageMode == LanguageModes.Primary) { // Attach to the list AddSubtitleInformation( subtitle, subtitles ); // Copy over result.SubTitles.LanguageMode = LanguageModes.Primary; // Remember result.SubTitles.Languages.Add( subtitle.Language ); // Done break; } // Standard selection if (StreamSelection.SubTitles.Contains( subtitle.Language )) { // Attach to the list AddSubtitleInformation( subtitle, subtitles ); // Remember result.SubTitles.Languages.Add( subtitle.Language ); } else { // At least one is excluded result.SubTitles.LanguageMode = LanguageModes.Selection; } } // Clear flag if no audio is used if (LanguageModes.All == result.SubTitles.LanguageMode) if (result.SubTitles.Languages.Count < 1) result.SubTitles.LanguageMode = LanguageModes.Selection; // Process all subtitles foreach (var current in subtitles) AddConsumer( current.Key, StreamTypes.SubTitle, m_TransportStream.AddSubtitles( current.Value.ToArray() ) ); // See if program guide is requested bool epg = StreamSelection.ProgramGuide; // May want to disable if (epg) if ((Hardware.Profile != null) && Hardware.Profile.DisableProgramGuide) epg = false; else if (Profile != null) if (Profile.GetFilter( Source ).DisableProgramGuide) epg = false; // EPG if (epg) { // Activate dispatch m_TransportStream.SetEPGMapping( Source.Network, Source.TransportStream, Source.Service ); // Start it Hardware.AddProgramGuideConsumer( DispatchEPG ); // Remember result.ProgramGuide = true; } // Counter int started = 0; try { // Start all foreach (var consumer in m_Consumers) try { // Forward Hardware.SetConsumerState( consumer, true ); // Count it ++started; } catch (OutOfConsumersException) { // Translate throw new OutOfConsumersException( m_Consumers.Count, started ) { RequestedSelection = result }; } } catch { // Detach EPG Hardware.RemoveProgramGuideConsumer( DispatchEPG ); // Cleanup on all errors foreach (var consumer in m_Consumers) try { // Remove Hardware.SetConsumerState( consumer, null ); } catch { // Ignore any error } // Forward throw; } // Remember path if (filePath != null) m_AllFiles.Add( new FileStreamInformation { FilePath = filePath, VideoType = m_OriginalSettings.VideoType } ); // Remember the time LastActivationTime = DateTime.UtcNow; } catch { // Simply forget m_TransportStream.Dispose(); m_TransportStream = null; // Forward throw; } // Get the next free PID NextStreamIdentifier = m_TransportStream.NextPID; // Remember the streams we use ActiveSelection = result; // Attach to clients var createNotify = OnCreatedStream; // Report if (createNotify != null) createNotify( this ); }
/// <summary> /// Erzeugt eine neue Verwaltung. /// </summary> /// <param name="hardware">Das Gerät, auf dem die zugehörige Quellgruppe gerade aktiv ist.</param> /// <param name="profile">Optional das Geräteprofil mit der zugehörigen Senderliste.</param> /// <param name="source">Die Quelle, die zu betrachten ist.</param> /// <param name="selection">Die zu betrachtenden Datenströme.</param> /// <exception cref="ArgumentNullException">Ein Parameter wurde nicht angegeben.</exception> public SourceStreamsManager( Hardware hardware, Profile profile, SourceIdentifier source, StreamSelection selection ) { // Validate if (null == hardware) throw new ArgumentNullException( "hardware" ); if (null == source) throw new ArgumentNullException( "source" ); if (null == selection) throw new ArgumentNullException( "selection" ); // Remember all StreamSelection = selection; Hardware = hardware; Profile = profile; Source = source; }
/// <summary> /// Beginnt die Aufzeichnung in einen <i>Transport Stream</i> - optional als /// Datei. /// </summary> /// <param name="nextPID">Die erste Datenstromkennung (PID), die in der Aufzeichnungsdatei verwendet werden darf.</param> /// <param name="recreate">Gesetzt, wenn ein Neustart aufgrund veränderter Nutzdatenströme erforderlich wurde.</param> /// <exception cref="ArgumentException">Eine Aufzeichnung der angegebenen Quelle ist nicht möglich.</exception> private void CreateStream(short nextPID, bool recreate) { // Try to get the full name var filePath = m_OriginalPath; if (filePath != null) { if (m_FileCount > 0) { // Split off the parts var name = Path.GetFileNameWithoutExtension(filePath); var dir = Path.GetDirectoryName(filePath); var ext = Path.GetExtension(filePath); // Construct new name filePath = Path.Combine(dir, $"{name} - {m_FileCount}{ext}"); } } // Try to decrypt if (m_Decrypting = m_OriginalSettings.IsEncrypted) { try { // Process Hardware.Decrypt(Source); } catch { // Ignore any error m_Decrypting = false; } } // Type of the video EPG.StreamTypes?videoType; // Video first if (m_OriginalSettings.VideoStream == 0) { videoType = null; } else { videoType = (m_OriginalSettings.VideoType == VideoTypes.H264) ? EPG.StreamTypes.H264 : EPG.StreamTypes.Video13818; } // Get the buffer size var bufferSize = (FileBufferSizeChooser == null) ? null : FileBufferSizeChooser(videoType); // Create the new stream m_TransportStream = new Manager(filePath, nextPID, bufferSize.GetValueOrDefault(Manager.DefaultBufferSize)); // Attach PCR sink m_TransportStream.OnWritingPCR = m_WritePCRSink; // Report of the actually selected streams StreamSelection result = new StreamSelection(); // Cleanup on any error try { // Video first if (videoType.HasValue) { AddConsumer(m_OriginalSettings.VideoStream, StreamTypes.Video, m_TransportStream.AddVideo((byte)videoType.Value)); } // Select audio ProcessAudioSelection(AudioTypes.MP2, result.MP2Tracks, StreamSelection.MP2Tracks); ProcessAudioSelection(AudioTypes.AC3, result.AC3Tracks, StreamSelection.AC3Tracks); // Videotext if (StreamSelection.Videotext) { if (0 != m_OriginalSettings.TextStream) { // Register AddConsumer(m_OriginalSettings.TextStream, StreamTypes.VideoText, m_TransportStream.AddTeleText()); // Remember result.Videotext = true; } } // Subtitle streams var subtitles = new Dictionary <ushort, List <EPG.SubtitleInfo> >(); // Preset mode result.SubTitles.LanguageMode = LanguageModes.All; // All audio // Subtitles foreach (var subtitle in m_OriginalSettings.Subtitles) { // Check for primary if (StreamSelection.SubTitles.LanguageMode == LanguageModes.Primary) { // Attach to the list AddSubtitleInformation(subtitle, subtitles); // Copy over result.SubTitles.LanguageMode = LanguageModes.Primary; // Remember result.SubTitles.Languages.Add(subtitle.Language); // Done break; } // Standard selection if (StreamSelection.SubTitles.Contains(subtitle.Language)) { // Attach to the list AddSubtitleInformation(subtitle, subtitles); // Remember result.SubTitles.Languages.Add(subtitle.Language); } else { // At least one is excluded result.SubTitles.LanguageMode = LanguageModes.Selection; } } // Clear flag if no audio is used if (LanguageModes.All == result.SubTitles.LanguageMode) { if (result.SubTitles.Languages.Count < 1) { result.SubTitles.LanguageMode = LanguageModes.Selection; } } // Process all subtitles foreach (var current in subtitles) { AddConsumer(current.Key, StreamTypes.SubTitle, m_TransportStream.AddSubtitles(current.Value.ToArray())); } // See if program guide is requested bool epg = StreamSelection.ProgramGuide; // May want to disable if (epg) { if ((Hardware.Profile != null) && Hardware.Profile.DisableProgramGuide) { epg = false; } else if (Profile != null) { if (Profile.GetFilter(Source).DisableProgramGuide) { epg = false; } } } // EPG if (epg) { // Activate dispatch m_TransportStream.SetEPGMapping(Source.Network, Source.TransportStream, Source.Service); // Start it Hardware.AddProgramGuideConsumer(DispatchEPG); // Remember result.ProgramGuide = true; } // Counter int started = 0; try { // Start all foreach (var consumer in m_Consumers) { try { // Forward Hardware.SetConsumerState(consumer, true); // Count it ++started; } catch (OutOfConsumersException) { // Translate throw new OutOfConsumersException(m_Consumers.Count, started) { RequestedSelection = result }; } } } catch { // Detach EPG Hardware.RemoveProgramGuideConsumer(DispatchEPG); // Cleanup on all errors foreach (var consumer in m_Consumers) { try { // Remove Hardware.SetConsumerState(consumer, null); } catch { // Ignore any error } } // Forward throw; } // Remember path if (filePath != null) { m_AllFiles.Add(new FileStreamInformation { FilePath = filePath, VideoType = m_OriginalSettings.VideoType }); } // Remember the time LastActivationTime = DateTime.UtcNow; } catch { // Simply forget m_TransportStream.Dispose(); m_TransportStream = null; // Forward throw; } // Get the next free PID NextStreamIdentifier = m_TransportStream.NextPID; // Remember the streams we use ActiveSelection = result; // Attach to clients var createNotify = OnCreatedStream; // Report if (createNotify != null) { createNotify(this); } }
/// <summary> /// Erzeugt einen Aufzeichnungskontext für eine Quelle. /// </summary> /// <param name="source">Die Informationen zur Quelle.</param> /// <param name="hardware">Das zu verwendende Gerät.</param> /// <param name="profile">Opetional ein Geräteprofil mit der zugehörigen Senderliste.</param> /// <param name="streams">Die gewünschten Aufzeichnungsparameter.</param> /// <returns>Eine Kontrollinstanz für die Aufzeichnung. Diese muss mittels <see cref="IDisposable.Dispose"/> /// freigegeben werden.</returns> public static SourceStreamsManager Open(this SourceIdentifier source, Hardware hardware, Profile profile, StreamSelection streams) { // Forward return(new SourceStreamsManager(hardware, profile, source, streams)); }