/// <summary> /// Beendet die Aufzeichnung in eine Datei. /// </summary> public void CloseStream() { // Load using (var stream = m_TransportStream) { // Wipe out m_TransportStream = null; // Reset time LastActivationTime = null; // Forget current settings ActiveSelection = null; // Nothing more to do if (null == stream) return; // Increment file counter ++m_FileCount; // Stop EPG receiver Hardware.RemoveProgramGuideConsumer( DispatchEPG ); // Stop all consumers foreach (var consumer in m_Consumers) try { // Try to stop the individual stream Hardware.SetConsumerState( consumer, null ); } catch { // Ignore any error } // Forget consumers m_Consumers.Clear(); // Send all the rest to the file (if any) stream.Flush(); // Update byte count BytesBias += stream.Length; } }
/// <summary> /// Create a new PES packet manager. /// </summary> /// <param name="manager">The corresponding transport stream.</param> /// <param name="pid">The stream identifier of this package.</param> public Packet( Manager manager, int pid ) { // Remember m_Manager = manager; PID = pid; }
/// <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 Instanz und bindet sie an einen <i>Transport /// Stream</i>. /// </summary> /// <param name="tsFile">Der <i>Transport Stream</i>, zu dem noch keine /// <param name="audioName">Der ISO Name der Sprache.</param> /// Datenströme hinzugefügt wurden.</param> public PVASplitter(Manager tsFile, string audioName) { // Remember TransportStream = tsFile; // Open streams m_Video = TransportStream.AddVideo(255); m_Audio = TransportStream.AddAudio(audioName); // Register self for PTS guidance TransportStream.PVASplitter = this; // Create reader m_Worker = new Thread(new ThreadStart(Worker)); // Configure m_Worker.SetApartmentState(ApartmentState.MTA); // Run it m_Worker.Start(); }