static float MPEG1or2ProgramStreamFileDuration(UsageEnvironment& env, char const* fileName, unsigned& fileSize) { FramedSource* dataSource = NULL; float duration = 0.0; // until we learn otherwise fileSize = 0; // ditto do { // Open the input file as a 'byte-stream file source': ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(env, fileName); if (fileSource == NULL) break; dataSource = fileSource; fileSize = (unsigned)(fileSource->fileSize()); if (fileSize == 0) break; // Create a MPEG demultiplexor that reads from that source. MPEG1or2Demux* baseDemux = MPEG1or2Demux::createNew(env, dataSource, True); if (baseDemux == NULL) break; // Create, from this, a source that returns raw PES packets: dataSource = baseDemux->newRawPESStream(); // Read the first time code from the file: float firstTimeCode; if (!getMPEG1or2TimeCode(dataSource, *baseDemux, True, firstTimeCode)) break; // Then, read the last time code from the file. // (Before doing this, flush the demux's input buffers, // and seek towards the end of the file, for efficiency.) baseDemux->flushInput(); unsigned const startByteFromEnd = 100000; unsigned newFilePosition = fileSize < startByteFromEnd ? 0 : fileSize - startByteFromEnd; if (newFilePosition > 0) fileSource->seekToByteAbsolute(newFilePosition); float lastTimeCode; if (!getMPEG1or2TimeCode(dataSource, *baseDemux, False, lastTimeCode)) break; // Take the difference between these time codes as being the file duration: float timeCodeDiff = lastTimeCode - firstTimeCode; if (timeCodeDiff < 0) break; duration = timeCodeDiff; } while (0); Medium::close(dataSource); return duration; }
int main(int argc, char **argv) { // Begin by setting up our usage environment: TaskScheduler *scheduler = BasicTaskScheduler::createNew(); env = BasicUsageEnvironment::createNew(*scheduler); // Open the input file as a 'byte-stream file source': FramedSource *inputSource = ByteStreamFileSource::createNew(*env, inputFileName); if (inputSource == NULL) { *env << "Unable to open file \"" << inputFileName << "\" as a byte-stream file source\n"; exit(1); } // Create a MPEG demultiplexor that reads from that source. MPEG1or2Demux *baseDemultiplexor = MPEG1or2Demux::createNew(*env, inputSource); // Create, from this, a source that returns raw PES packets: MPEG1or2DemuxedElementaryStream *pesSource = baseDemultiplexor->newRawPESStream(); // And, from this, a filter that converts to MPEG-2 Transport Stream frames: FramedSource *tsFrames = MPEG2TransportStreamFromPESSource::createNew(*env, pesSource); // Open the output file as a 'file sink': MediaSink *outputSink = FileSink::createNew(*env, outputFileName); if (outputSink == NULL) { *env << "Unable to open file \"" << outputFileName << "\" as a file sink\n"; exit(1); } // Finally, start playing: *env << "Beginning to read...\n"; outputSink->startPlaying(*tsFrames, afterPlaying, NULL); env->taskScheduler().doEventLoop(); // does not return return 0; // only to prevent compiler warning }
void CProgramToTransportStreamRecorder::Initialize(wchar_t* fileNameOut) { LogDebug(L"CProgramToTransportStreamRecorder::Initialize %s", fileNameOut); m_BufferThreadActive=false; m_buffer.Clear(); m_inputSource = CMemoryStreamSource::createNew(*m_env, "",m_buffer); if (m_inputSource == NULL) { *m_env << "Unable to open memorystream as a byte-stream source\n"; return; } // Create a MPEG demultiplexor that reads from that source. MPEG1or2Demux* baseDemultiplexor = MPEG1or2Demux::createNew(*m_env, m_inputSource); // Create, from this, a source that returns raw PES packets: MPEG1or2DemuxedElementaryStream* pesSource = baseDemultiplexor->newRawPESStream(); // And, from this, a filter that converts to MPEG-2 Transport Stream frames: m_tsFrames = MPEG2TransportStreamFromPESSource::createNew(*m_env, pesSource); ((MPEG2TransportStreamFromPESSource*) m_tsFrames)->SetSourceType(m_iProgramType); m_outputSink = CFileSinkRecorder::createNew(*m_env, fileNameOut); if (m_outputSink == NULL) { *m_env << "Unable to open file \"" << fileNameOut << "\" as a file sink\n"; return; } m_buffer.Clear(); m_iPacketsToSkip=100; //StartBufferThread(); m_bSendVideoAudioObserverEvents = true; m_bStarting=true; m_bRunning=true; }