MPEG2TransportStreamIndexer
MPEG2TransportStreamIndexer主要实现了对视频数据流化,要想实现对视频的点播,要同时具备.ts和.tsx文件,MPEG2TransportStreamIndexer示例代码可以完成这个过程。
其中用到的类的继承关系如下:

将ts流化需要四个主要的步骤,分别为:
- 打开要流化的视频文件
- 根据打开的文件创建
index - 打开流化之后文件的输出
- 开始每取一帧视频数据转换为流之后输出到输出文件中,重复直到文件结束
具体实现如下:
//
// Created by andrew on 2021/6/17.
//
#include <iostream>
#include <liveMedia.hh>
#include <BasicUsageEnvironment.hh>
#include <cstring>
void afterPlaying(void* /*clientData*/) {
std::cout << "done" << std::endl;
exit(0);
}
class MPEG2TransportStreamIndex {
public:
MPEG2TransportStreamIndex() = default;
~MPEG2TransportStreamIndex() = default;
int32_t Init(const char* pProgramName, const char* pSzInputFilename, size_t filenameLen) {
// 设置用户环境变量
if (filenameLen < 4 || strcmp(&pSzInputFilename[filenameLen - 3], ".ts") != 0) {
*m_pEnv << "ERROR : input file name " << pSzInputFilename;
return -1;
}
TaskScheduler* pScheduler = BasicTaskScheduler::createNew();
m_pEnv = BasicUsageEnvironment::createNew(*pScheduler);
m_pProgramName = pProgramName;
m_pInputFilename = pSzInputFilename;
m_fileNameLen = filenameLen;
return 0;
}
int32_t OpenInputFile() {
m_pInput = ByteStreamFileSource::createNew(*m_pEnv, m_pInputFilename, TRANSPORT_PACKET_SIZE);
if (nullptr == m_pInput) {
*m_pEnv << "open input file failed .";
return -1;
}
return 0;
}
int32_t CreatTransportStreamFilter() {
m_pIndexer = MPEG2IFrameIndexFromTransportStream::createNew(*m_pEnv, m_pInput);
if (nullptr == m_pIndexer) {
return -1;
}
return 0;
}
int32_t OpenOutputFile() {
char *pSzOutputFilename = new char[m_fileNameLen + 2];
sprintf(pSzOutputFilename, "%sx", m_pInputFilename);
m_pOutput = FileSink::createNew(*m_pEnv, pSzOutputFilename);
if (nullptr == m_pOutput) {
return -1;
}
return 0;
}
void StartPlaying() {
*m_pEnv << "Start Writing index file " ;
// 将fSource传递给 output
m_pOutput->startPlaying(*m_pIndexer, afterPlaying, nullptr);
m_pEnv->taskScheduler().doEventLoop();
}
private:
UsageEnvironment *m_pEnv{};
const char *m_pProgramName{};
// 输入文件名和文件长度
const char *m_pInputFilename{};
int m_fileNameLen{};
FramedSource* m_pInput{};
FramedSource * m_pIndexer{};
MediaSink* m_pOutput{};
};
int main(int argc, char* argv[]) {
if (argc != 2) {
std::cout << "argc < 2" << std::endl;
return -1;
}
// 定义一个Mpeg解析类
MPEG2TransportStreamIndex mpeg2TransportStreamIndex;
int32_t ret = mpeg2TransportStreamIndex.Init(argv[0], argv[1], strlen(argv[1]));
if (0 != ret) {
std::cerr << "mpeg2TransportStreamIndex.Init failed." << std::endl;
return ret;
}
// 打开输入文件
ret = mpeg2TransportStreamIndex.OpenInputFile();
if (0 != ret) {
std::cerr << "mpeg2TransportStreamIndex.OpenInputFile failed." << std::endl;
return ret;
}
// 创建文件流
ret = mpeg2TransportStreamIndex.CreatTransportStreamFilter();
if (0 != ret) {
std::cerr << "mpeg2TransportStreamIndex.CreatTransportStreamFilter failed." << std::endl;
return ret;
}
// 打开输出文件
ret = mpeg2TransportStreamIndex.OpenOutputFile();
if (0 != ret) {
std::cerr << "mpeg2TransportStreamIndex.OpenOutputFile failed." << std::endl;
return ret;
}
// 开始执行事件循环
mpeg2TransportStreamIndex.StartPlaying();
return 0;
}
参考:
该博客介绍了如何使用MPEG2TransportStreamIndexer进行视频流化,以便实现点播功能。通过打开.ts文件,创建索引,输出流化后的.tsx文件,实现视频数据的转换和输出。文章提供了详细的C++代码示例,包括打开输入文件、创建传输流过滤器、打开输出文件和开始播放等关键步骤。
2820

被折叠的 条评论
为什么被折叠?



