live555实现视频格式数据流化处理

该博客介绍了如何使用MPEG2TransportStreamIndexer进行视频流化,以便实现点播功能。通过打开.ts文件,创建索引,输出流化后的.tsx文件,实现视频数据的转换和输出。文章提供了详细的C++代码示例,包括打开输入文件、创建传输流过滤器、打开输出文件和开始播放等关键步骤。

MPEG2TransportStreamIndexer

MPEG2TransportStreamIndexer主要实现了对视频数据流化,要想实现对视频的点播,要同时具备.ts.tsx文件,MPEG2TransportStreamIndexer示例代码可以完成这个过程。

其中用到的类的继承关系如下:
在这里插入图片描述

ts流化需要四个主要的步骤,分别为:

  1. 打开要流化的视频文件
  2. 根据打开的文件创建index
  3. 打开流化之后文件的输出
  4. 开始每取一帧视频数据转换为流之后输出到输出文件中,重复直到文件结束

具体实现如下:

//
// 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

andrewbytecoder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值