7-代码重构,使用多线程采集数据推流

  1. 小白学习音视频(七)代码重构,使用多线程采集数据推流

小白学习音视频(七)代码重构,使用多线程采集数据推流

image

关注微信号:cpp手艺人,获取更多文章

这次主要就是对代码进行重构,先贴上流程图。

image

接下来,就是具体的代码:

void XController::run()
{
    long long beginTime = GetCurTime();
    while (!isExit)
    {
        //一次读取一帧音频
        XData ad = XAudioRecord::Get()->Pop();
        XData vd = XVideoCapture::Get()->Pop();
        if (ad.size<=0 && vd.size<=0)
        {
            msleep(1);
            continue;
        }
        //处理音频
        if (ad.size > 0)
        {
            ad.pts = ad.pts - beginTime;

            //重采样源数据
            XData pcm = XMediaEncode::Get()->Resample(ad);
            ad.Drop();
            XData pkt = XMediaEncode::Get()->EncodeAudio(pcm);
            if (pkt.size > 0)
            {
                ////推流
                if (XRtmp::Get()->SendFrame(pkt,aindex))
                {
                    cout << "#" << flush;
                }
            }
        }
        //处理视频
        if (vd.size > 0)
        {
            vd.pts = vd.pts - beginTime;
            XData yuv = XMediaEncode::Get()->RGBToYUV(vd);
            vd.Drop();
            XData pkt = XMediaEncode::Get()->EncodeVideo(yuv);
            if (pkt.size> 0)
            {
                ////推流
                if (XRtmp::Get()->SendFrame(pkt,vindex))
                {
                    cout << "@" << flush;
                }
            }
        }
    }
}


//设定美颜参数
bool XController::Set(std::string key, double val)
{
    XFilter::Get()->Set(key, val);
    return true;
}
bool XController::Start()
{
    ///1 设置磨皮过滤器
    XVideoCapture::Get()->AddFilter(XFilter::Get());
    cout << "1 设置磨皮过滤器" << endl;
    ///2 打开相机
    if (camIndex >= 0)
    {
        if (!XVideoCapture::Get()->Init(camIndex))
        {
            err = "2打开系统相机失败";
            cout << err << endl;
            return false;
        }
    }
    else if (!inUrl.empty())
    {
        if (!XVideoCapture::Get()->Init(inUrl.c_str()))
        {
            err = "2打开";
            err += inUrl;
            err += "相机失败";
            cout << err << endl;
            return false;
        }
    }
    else
    {
        err = "2请设置相机参数";
        cout << err << endl;
        return false;
    }
    cout << "2相机打开成功" << endl;

    ///3 qt音频开始录制
    if (!XAudioRecord::Get()->Init())
    {
        err = "3录音设备打开失败";
        cout << err << endl;
        return false;
    }
    cout << "3录音设备打开成功" << endl;

    ///11 启动音视频录制线程
    XAudioRecord::Get()->Start();
    XVideoCapture::Get()->Start();

    ///音视频编码类
    ///4 初始化格式转换上下文
    ///初始化输出的数据结构
    XMediaEncode::Get()->in_width = XVideoCapture::Get()->width;
    XMediaEncode::Get()->in_height = XVideoCapture::Get()->height;
    XMediaEncode::Get()->out_width = XVideoCapture::Get()->width;
    XMediaEncode::Get()->out_height = XVideoCapture::Get()->height;
    if (!XMediaEncode::Get()->InitScale())
    {
        err = "4视频像素格式转换打开失败!";
        cout << err << endl;
        return false;
    }
    cout << "4视频像素格式转换打开成功!" << endl;
    ///5 音频重采样 上下文初始化
    XMediaEncode::Get()->channels = XAudioRecord::Get()->channels;
    XMediaEncode::Get()->nb_sample = XAudioRecord::Get()->nbSamples;
    XMediaEncode::Get()->sample_rate = XAudioRecord::Get()->sampleRate;
    if (!XMediaEncode::Get()->InitResample())
    {
        err = "5音频重采样上下文初始化失败!";
        cout << err << endl;
        return false;
    }
    cout << "5音频重采样上下文初始化成功!" << endl;
    ///6初始化音频编码器
    if (!XMediaEncode::Get()->InitAudioCode())
    {
        err = "6初始化音频编码器失败!";
        cout << err << endl;
        return false;
    }
    ///7初始化视频编码器
    if (!XMediaEncode::Get()->InitVideoCodec())
    {
        err = "7初始化视频频编码器失败!";
        cout << err << endl;
        return false;
    }
    cout << "7音视频编码器初始化成功!" << endl;
    /// 8创建输出封装器上下文
    if (!XRtmp::Get()->Init(outUrl.c_str()))
    {
        err = "8创建输出封装器上下文失败!";
        cout << err << endl;
        return false;
    }
    cout << "8创建输出封装器上下文成功!" << endl;

    ///9 添加音视频流
    vindex = XRtmp::Get()->AddStream(XMediaEncode::Get()->vc);
    aindex = XRtmp::Get()->AddStream(XMediaEncode::Get()->ac);
    if (vindex < 0 || aindex < 0)
    {
        err = "9添加音视频流失败!";
        cout << err << endl;
        return false;
    }
    cout << "9添加音视频流成功!" << endl;

    ///10 发送封装头
    if (!XRtmp::Get()->SendHead())
    {
        err = "10 发送封装头失败!";
        cout << err << endl;
        return false;
    }
    XAudioRecord::Get()->Clear();
    XVideoCapture::Get()->Clear();
    XDataThread::Start();
    return true;
}
void XController::Stop()
{
    XDataThread::Stop();
    XAudioRecord::Get()->Stop();
    XVideoCapture::Get()->Stop();
    XMediaEncode::Get()->Close();
    XRtmp::Get()->Close();
    camIndex = -1;
    inUrl = "";
    return;
}

XController::XController()
{
}


XController::~XController()
{
}

项目地址:https://github.com/MingYueRuYa/FFmpeg-RTMP


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 635672377@qq.com

文章标题:7-代码重构,使用多线程采集数据推流

文章字数:963

本文作者:刘世雄

发布时间:2020-07-30, 14:28:16

最后更新:2020-07-30, 08:59:08

原始链接:http://lsxcpp.com/2020/07/30/7-%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84%EF%BC%8C%E4%BD%BF%E7%94%A8%E5%A4%9A%E7%BA%BF%E7%A8%8B%E9%87%87%E9%9B%86%E6%95%B0%E6%8D%AE%E6%8E%A8%E6%B5%81/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录