6-Qt录制音频+USB摄像头推流

  1. 小白学习音视频(六)Qt录制音频+USB摄像头推流

小白学习音视频(六)Qt录制音频+USB摄像头推流

image

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

在上代码之前,我们来看下流程图,整个流程还是非常简单的。但是里面有很多的细节需要处理。

image

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

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

     char *outUrl = "rtmp://192.168.26.31/live";

    int ret = 0;
    int sampleRate = 44100;
    int channels = 2;
    int sampleByte = 2;
    int nbSample = 1024;
    ///打开摄像机
    XVideoCapture *xv = XVideoCapture::Get();
    if (!xv->Init(0))
    {
        cout << "open camera failed!" << endl;
        getchar();
        return -1;
    }
    cout << "open camera success!" << endl;
    xv->Start();

    ///1 qt音频开始录制
    XAudioRecord *ar = XAudioRecord::Get();
    ar->sampleRate = sampleRate;
    ar->channels = channels;
    ar->sampleByte = sampleByte;
    ar->nbSamples = nbSample;
    if (!ar->Init())
    {
        cout << "XAudioRecord Init failed!" << endl;
        getchar();
        return -1;
    }
    ar->Start();

    ///音视频编码类
    XMediaEncode *xe = XMediaEncode::Get();

    ///2 初始化格式转换上下文
    ///3 初始化输出的数据结构
    xe->in_width = xv->width;
    xe->in_height = xv->height;
    xe->out_width = xv->width;
    xe->out_height = xv->height;
    if (!xe->InitScale())
    {
        getchar();
        return -1;
    }
    cout << "初始化视频像素转换上下文成功!" << endl;

    ///2 音频重采样 上下文初始化
    xe->channels = channels;
    xe->nb_sample = nbSample;
    xe->sample_rate = sampleRate;
    xe->in_smaple_fmt = XSampleFMT::X_S16;
    xe->out_sample_fmt = XSampleFMT::X_FLATP;
    if (!xe->InitResample())
    {
        getchar();
        return -1;
    }
    ///4 初始化音频编码器
    if (!xe->InitAudioCode())
    {
        getchar();
        return -1;
    }

    ///初始化视频编码器
    if (!xe->InitVideoCodec())
    {
        getchar();
        return -1;
    }


    ///5 输出封装器和音频流配置
    //a 创建输出封装器上下文
    XRtmp *xr = XRtmp::Get(0);
    if (!xr->Init(outUrl))
    {
        getchar();
        return -1;
    }

    //添加视频流
    int vindex = 0;
    vindex = xr->AddStream(xe->vc);
    if (vindex<0)
    {
        getchar();
        return -1;
    }

    //b 添加音频流 
    int aindex = xr->AddStream(xe->ac);
    if (aindex<0)
    {
        getchar();
        return -1;
    }

    ///打开rtmp 的网络输出IO
    //写入封装头
    if (!xr->SendHead())
    {
        getchar();
        return -1;
    }
    //一次读取一帧音频的字节数
    for (;;)
    {
        //一次读取一帧音频
        XData ad = ar->Pop();
        XData vd = xv->Pop();
        if (ad.size <= 0 && vd.size <= 0)
        {
            QThread::msleep(1);
            continue;
        }

        //处理音频
        if (ad.size > 0)
        {
            //重采样源数据
            AVFrame *pcm = xe->Resample(ad.data);
            ad.Drop();
            AVPacket *pkt = xe->EncodeAudio(pcm);
            if (pkt)
            {
                ////推流
                if (xr->SendFrame(pkt,aindex))
                {
                    cout << "#" << flush;
                }
            }

        }

        //处理视频
        if (vd.size > 0) {
            AVFrame *yuv = xe->RGBToYUV(vd.data);
            vd.Drop();
            AVPacket *pkt = xe->EncodeVideo(yuv);
            if (pkt) {
                ////推流
                if (xr->SendFrame(pkt,vindex)) {
                    cout << "@" << flush;
                }
            }

        }

    }

    getchar();
    return app.exec();
}

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


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

文章标题:6-Qt录制音频+USB摄像头推流

文章字数:616

本文作者:刘世雄

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

最后更新:2020-07-09, 06:29:04

原始链接:http://lsxcpp.com/2020/07/09/6-Qt%E5%BD%95%E5%88%B6%E9%9F%B3%E9%A2%91+USB%E6%91%84%E5%83%8F%E5%A4%B4%E6%8E%A8%E6%B5%81/

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

目录