FFMPEG音视频开发: 完成摄像头、桌面本地录制与rtmp推流(windows)

简介: FFMPEG音视频开发: 完成摄像头、桌面本地录制与rtmp推流(windows)

一、基本介绍

该软件里推流和视频保存使用FFMPEG库完成,界面框架采用QT,视频和音频可以同步推流和录制,FFMPEG本身支持跨平台编译开发,QT也支持跨平台,在Android、Linux、windows都运行良好,只需要在不同平台编译对应的ffmpeg库即可,逻辑代码部分通用。

该源码在2021年完成了新版本的更新,支持桌面推流和视频录制,效果图在文章的第四章可以查看。

二、windows下软件运行效果

(1)主界面效果

image.png

(2)保存视频到本地,设置录制间隔为10秒一个视频

image.png

(3)推流视频到B站,必须保证RTMP地址是有效的,如果地址无效软件会自动退出

image.png

image.png

三、核心代码

代码里除了FFMEG代码之外,主要的核心代码是摄像头颜色转换代码,因为不同的摄像头输出的原始格式不一样,代码里还需要做颜色转换。

void VideoReadThread_0::slotOnProbeFrame(const QVideoFrame &frame)
{
   QVideoFrame cloneFrame(frame);
   cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
  // qDebug()<<"height:"<<cloneFrame.height();
  // qDebug()<<"width:"<<cloneFrame.width();
   //qDebug()<<"bytesPerLine:"<<cloneFrame.bytesPerLine();
   //qDebug()<<"mappedBytes:"<<cloneFrame.mappedBytes();
   //qDebug()<<"pixelFormat:"<<cloneFrame.pixelFormat();
   unsigned char rgb_buffer[VIDEO_WIDTH*VIDEO_HEIGHT*3];
   if(cloneFrame.pixelFormat()==QVideoFrame::Format_NV21)
   {
        NV21_TO_RGB24(cloneFrame.bits(),rgb_buffer,cloneFrame.width(),cloneFrame.height());
   }
   else if(cloneFrame.pixelFormat()==QVideoFrame::Format_YUYV)
   {
       yuyv_to_rgb(cloneFrame.bits(),rgb_buffer,cloneFrame.width(),cloneFrame.height());
   }
   else if(cloneFrame.pixelFormat()==QVideoFrame::Format_RGB24)
   {
        memcpy(rgb_buffer,cloneFrame.bits(),sizeof(rgb_buffer));
   }
   else if(cloneFrame.pixelFormat()==QVideoFrame::Format_BGR24)
   {
        memcpy(rgb_buffer,cloneFrame.bits(),sizeof(rgb_buffer));
   }
   else if(cloneFrame.pixelFormat()==QVideoFrame::Format_Jpeg)
   {
   }
   else
   {
       qDebug("当前格式编码为%1,暂时不支持转换.\n");
   }
    //加载图片数据
    QImage image(rgb_buffer,
                       cloneFrame.width(),
                       cloneFrame.height(),
                       QImage::Format_RGB888);
    if(cloneFrame.pixelFormat()==QVideoFrame::Format_BGR24)
    {
        image=image.rgbSwapped(); //BGR格式转RGB
        image=image.mirrored(false, true);
    }
    if(cloneFrame.pixelFormat()==QVideoFrame::Format_Jpeg)
    {
        image.loadFromData((const uchar *)cloneFrame.bits(),cloneFrame.mappedBytes());
    }
    //绘制图片水印
    QDateTime dateTime(QDateTime::currentDateTime());
    //时间效果: 2020-03-05 16:25::04 周一
    QString qStr="";
    qStr+=dateTime.toString("yyyy-MM-dd hh:mm:ss ddd");
    QPainter pp(&image);
    QPen pen = QPen(Qt::white);
    pp.setPen(pen);
    pp.drawText(QPointF(0,20),qStr);
    //提取RGB数据
    unsigned char *p=rgb_buffer;
    for(int i=0;i<image.height();i++)
    {
        for(int j=0;j<image.width();j++)
        {
            QRgb rgb=image.pixel(j,i);
            *p++=qRed(rgb);
            *p++=qGreen(rgb);
            *p++=qBlue(rgb);
        }
    }
    videoaudioencode_0.video_encode_mutex.lock();
    RGB24_TO_YUV420(rgb_buffer,image.width(),image.height(),video_yuv420p_buff);
    videoaudioencode_0.video_encode_mutex.unlock();
    videoaudioencode_0.video_WaitConditon.wakeAll();
    emit VideoDataOutput(image); //发送信号
    cloneFrame.unmap();
}

xxx.pro工程文件代码:

QT       += core gui
QT       += multimediawidgets
QT       += xml
QT       += multimedia
QT       += network
QT       += widgets
QT       += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
    Color_conversion.cpp \
    audio_video_encode_0.cpp \
    ffmpeg_code.cpp \
    main.cpp \
    widget.cpp
HEADERS += \
    Color_conversion.h \
    audio_video_encode_0.h \
    config.h \
    ffmpeg_code.h \
    widget.h
FORMS += \
    widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RC_ICONS=log.ico
win32
{
    message('运行win32版本')
    INCLUDEPATH+=$$PWD/ffmpeg-win32-shared-dll/include
    LIBS+=$$PWD/ffmpeg-win32-shared-dll/bin/av*
    LIBS+=$$PWD/ffmpeg-win32-shared-dll/bin/sw*
    LIBS+=$$PWD/ffmpeg-win32-shared-dll/bin/pos*
}
RESOURCES += \
    image.qrc

四、更新版本界面

image.png

image.png

目录
相关文章
|
2月前
|
Linux 虚拟化 iOS开发
VMware Remote Console 13.0.1 for macOS, Linux, Windows - vSphere 虚拟机控制台的桌面客户端
VMware Remote Console 13.0.1 for macOS, Linux, Windows - vSphere 虚拟机控制台的桌面客户端
470 0
VMware Remote Console 13.0.1 for macOS, Linux, Windows - vSphere 虚拟机控制台的桌面客户端
|
8月前
|
XML 存储 搜索推荐
Omnissa Dynamic Environment Manager 2503 - 个性化动态 Windows 桌面环境管理
Omnissa Dynamic Environment Manager 2503 - 个性化动态 Windows 桌面环境管理
143 7
Omnissa Dynamic Environment Manager 2503 - 个性化动态 Windows 桌面环境管理
|
4月前
|
搜索推荐 虚拟化 Windows
Omnissa Dynamic Environment Manager 2506 - 个性化动态 Windows 桌面环境管理
Omnissa Dynamic Environment Manager 2506 - 个性化动态 Windows 桌面环境管理
102 0
|
5月前
|
Linux 虚拟化 iOS开发
VMware Remote Console 13.0.0 for macOS, Linux, Windows - vSphere 虚拟机控制台的桌面客户端
VMware Remote Console 13.0.0 for macOS, Linux, Windows - vSphere 虚拟机控制台的桌面客户端
1157 0
VMware Remote Console 13.0.0 for macOS, Linux, Windows - vSphere 虚拟机控制台的桌面客户端
|
缓存 监控 计算机视觉
视频监控笔记(三):opencv结合ffmpeg获取rtsp摄像头相关信息
本文介绍了如何使用OpenCV结合FFmpeg获取RTSP摄像头信息,包括网络架构、视频监控系统组成、以及如何读取和显示网络摄像头视频流。
519 1
|
Linux Apache C++
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt
该文介绍了如何在Windows环境下为FFmpeg集成SRT协议支持库libsrt。首先,需要安装Perl和Nasm,然后编译OpenSSL。接着,下载libsrt源码并使用CMake配置,生成VS工程并编译生成srt.dll和srt.lib。最后,将编译出的库文件和头文件按照特定目录结构放置,并更新环境变量,重新配置启用libsrt的FFmpeg并进行编译安装。该过程有助于优化直播推流的性能,减少卡顿问题。
464 2
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt
|
安全 Windows
电脑进入桌面后操作无响应?不妨试试禁用Windows Search服务
电脑进入桌面后操作无响应?不妨试试禁用Windows Search服务
|
API Windows
MASM32编程获取Windows当前桌面主题名
MASM32编程获取Windows当前桌面主题名
|
编解码 Linux 计算机视觉
python 调用ffmpeg使用usb摄像头录制视频,输出h264格式,自动获取摄像头的最佳帧率和最大画面尺寸
使用 Python 调用 FFmpeg 进行 USB 摄像头视频录制,需先确保安装 FFmpeg 和 Python 的 `subprocess` 模块。代码示例展示了如何自动获取摄像头的最佳帧率和最大分辨率,然后录制视频。首先通过 FFmpeg 列出摄像头格式获取信息,解析出帧率和分辨率,选择最优值。之后调用 FFmpeg 命令录制视频,设置帧率、分辨率等参数。注意 `/dev/video0` 是 Linux 的摄像头设备路径,Windows 系统需相应调整。代码中未直接实现自动获取最佳参数,通常需要借助其他库如 OpenCV。
|
缓存 Shell Windows
Windows 清理C盘空间,将桌面,文档等移D盘
Windows 清理C盘空间,将桌面,文档等移D盘
593 0