首页 > 其他分享 >Qt+rtsp+ffmpeg 播放声音

Qt+rtsp+ffmpeg 播放声音

时间:2023-08-16 19:46:32浏览次数:44  
标签:ffmpeg Qt frame rtsp ret sample av NULL out


#include <QtCore/QCoreApplication>
#include <QtMultimedia/QAudioFormat>
#include <QtMultimedia/QAudioOutput>
#include <QtCore/QFile>
#include <iostream>
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
#include "libavfilter/avfilter.h"
#include "libavutil/avutil.h"
 
#ifdef __cplusplus
};
#endif // __cplusplus
 
 
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avfilter.lib")
#pragma comment(lib, "swscale.lib")
#pragma comment(lib, "swresample.lib")
 
#define MAX_AUDIO_FRAME_SIZE    (19200)
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QAudioFormat audioFormat;
    audioFormat.setSampleRate(44100);
    audioFormat.setChannelCount(2);
    audioFormat.setSampleSize(16);
    audioFormat.setCodec("audio/pcm");
    audioFormat.setByteOrder(QAudioFormat::LittleEndian);
    audioFormat.setSampleType(QAudioFormat::UnSignedInt);
    QAudioOutput* audio = new QAudioOutput(audioFormat);
    QIODevice* io = audio->start();
    int size = audio->periodSize();
    if (size <= 0)
    {
        return -1;
    }
    int ret = -1;
    std::string strUrl = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
    strUrl = "rtsp://192.168.13.100:8554/sht.mp3";
    AVDictionary *opts = NULL;
    av_dict_set(&opts, "buffer_size", "1024000", 0);
    av_dict_set(&opts, "max_delay", "50000", 0);
    av_dict_set(&opts, "stimeout", "200000000", 0);
    av_dict_set(&opts, "rtsp_transport", "tcp", 0);
    AVFormatContext* ifmtCtx = NULL;
    int out_buffer_size;
    AVFrame* pFrame_Resample = av_frame_alloc();
    AVFrame* frame = av_frame_alloc();
    AVCodecContext* pACodecCtx = NULL;
    struct SwrContext *pSwrCtx = NULL;
    do
    {
        if (ret = avformat_open_input(&ifmtCtx, strUrl.c_str(), 0, &opts) < 0)
        {
            av_log(NULL, AV_LOG_ERROR, "Could not open input stream file '%s'\n", strUrl.c_str());
            break;
        }
        ret = avformat_find_stream_info(ifmtCtx, NULL);
        if (ret < 0)
        {
            av_log(NULL, AV_LOG_ERROR, "avformat_find_stream_info fail!\n");
            break;
        }
        int nAStreamIndex = -1;
        nAStreamIndex = av_find_best_stream(ifmtCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
        av_dump_format(ifmtCtx, 0 ,strUrl.c_str(), 0);
        pACodecCtx = ifmtCtx->streams[nAStreamIndex]->codec;
        AVCodec* pCodec = avcodec_find_decoder(pACodecCtx->codec_id);
        if (avcodec_open2(pACodecCtx, pCodec, NULL) < 0)
        {
            av_log(NULL, AV_LOG_ERROR, "Error open codec!\n");
            break;
        }
        uint8_t* out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE);
        uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO;
        enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
        enum AVSampleFormat in_sample_fmt = pACodecCtx->sample_fmt;
        int in_sample_rate = pACodecCtx->sample_rate;
        int out_sample_rate = 44100;
        int in_channels = pACodecCtx->channels;
        int out_channels = av_get_channel_layout_nb_channels(out_channel_layout);
        int in_channel_layout = av_get_default_channel_layout(pACodecCtx->channels);
        pSwrCtx = swr_alloc();
        pSwrCtx = swr_alloc_set_opts(NULL, out_channel_layout, out_sample_fmt, out_sample_rate,
            in_channel_layout, in_sample_fmt, in_sample_rate, 0, NULL);
        ret = swr_init(pSwrCtx);
        if (ret < 0)
        {
            av_log(NULL, AV_LOG_ERROR, "swr init fail!\n");
            break;
        }
        AVPacket pkt;
        av_init_packet(&pkt);
        //AVRational rt = { 1, in_sample_rate };
        while (1)
        {
            ret = av_read_frame(ifmtCtx, &pkt);
            if (ret < 0)
            {
                break;
            }
            if (pkt.stream_index != nAStreamIndex)
            {
                av_packet_unref(&pkt);
                continue;
            }
            ret = avcodec_send_packet(pACodecCtx, &pkt);
            if (ret < 0)
            {
                av_packet_unref(&pkt);
                av_log(NULL, AV_LOG_ERROR, "Error sending a packet!\n");
            }
            else
            {
                while (ret >= 0)
                {
                    ret = avcodec_receive_frame(pACodecCtx, frame);
                    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
                    {
                        ret = -1;
                        break;
                    }
                    else if (ret < 0)
                    {
                        av_log(NULL, AV_LOG_ERROR, "Error dufing decoding!\n");
                        ret = -1;
                        break;
                    }
                    if (pFrame_Resample->nb_samples != frame->nb_samples)
                    {
                        pFrame_Resample->pts = frame->pts;
                        //double second = frame->pts * av_q2d(rt);
                        pFrame_Resample->nb_samples = av_rescale_rnd(swr_get_delay(pSwrCtx, out_sample_rate) + frame->nb_samples,
                            out_sample_rate, in_sample_rate, AV_ROUND_UP);
                        av_samples_fill_arrays(pFrame_Resample->data, pFrame_Resample->linesize, out_buffer, out_channels,
                            pFrame_Resample->nb_samples, out_sample_fmt, 0);
                    }
                    int len = swr_convert(pSwrCtx, pFrame_Resample->data, pFrame_Resample->nb_samples, (const uint8_t**)frame->data, frame->nb_samples);
                    out_buffer_size = len * out_channels * av_get_bytes_per_sample(out_sample_fmt);
                    char *buf = (char *)out_buffer;
                    int len2 = out_buffer_size;
                    while (1)
                    {
                        if (len2 <= 0)
                        {
                            break;
                        }
                        if (len2 <= size)
                        {
                            io->write(buf, len2);
                            len2 -= len2;
                        }
                        else
                        {
                            io->write(buf, size);
                            len2 -= size;
                            buf += size;
                        }
                    }
                }
            }
            av_packet_unref(&pkt);
        }
        av_frame_free(&frame);
    } while (0);
 
    if (pACodecCtx != NULL)
    {
        avcodec_close(pACodecCtx);
    }
    if (ifmtCtx != NULL)
    {
        avformat_close_input(&ifmtCtx);
    }
    if (pFrame_Resample != NULL)
    {
        av_frame_free(&pFrame_Resample);
    }
    if (pSwrCtx != NULL)
    {
        swr_free(&pSwrCtx);
    }
 
    return a.exec();
}

标签:ffmpeg,Qt,frame,rtsp,ret,sample,av,NULL,out
From: https://www.cnblogs.com/kn-zheng/p/17636028.html

相关文章

  • 基于pyqt5的简易目标检测UI
    没选图像的时候:被否决的一个系统,也不过多介绍了,留个记录吧,之后可以看看优化一下,也不白写代码。代码:fromultralyticsimportYOLOfromPyQt5.QtWidgetsimportQApplication,QMainWindow,QFileDialog,QLabel,QPushButton,QHBoxLayout,QVBoxLayout,QWidgetfromPyQt5.......
  • 【QT】tr()的作用
    函数tr()全名是QObject::tr(),被它处理的字符串可以使用工具提取出来翻译成其他语言,也就是做国际化使用。只要记住,Qt的最佳实践:如果你想让你的程序国际化的话,那么,所有用户可见的字符串都要使用QObject::tr()!但是,为什么我们没有写QObject::tr(),而仅仅是tr(......
  • 树莓派Raspbian安装PYQT5
     安装PYQT5.(树莓派Raspbian下pip3installPyQt5是无法正常安装的。)https://zhuanlan.zhihu.com/p/498682983 准备工作。pipinstallwheelsudoapt-getupdate Pip3installsip可直接用官方仓库安装。 sudoaptinstall-ypython3-pyqt5额外组件sudoaptin......
  • [Multimedia][ffmpeg] 音频音量获取
    ffmpeg-i~/media/test.mp4-filter_complexvolumedetect-c:vcopy-fnull/dev/null...[Parsed_volumedetect_0@0x7f83a481c000]n_samples:23887872[Parsed_volumedetect_0@0x7f83a481c000]mean_volume:-16.7dB[Parsed_volumedetect_0@0x7f83a481c000]......
  • ThingsKit物联网平台模拟网关+子设备MQTT接入
    准备工作MQTTX设备模拟工具下载MQTTX是由EMQ开发的一款开源跨平台MQTT5.0桌面客户端,它兼容macOS,Linux以及Windows系统。MQTTX的用户界面UI采用聊天式设计,使得操作逻辑更加简明直观。它支持用户快速创建和保存多个MQTT连接,便于测试MQTT/MQTTS连接,以及MQTT消息的订阅和发布。M......
  • ThingsKit物联网平台模拟直连设备MQTT接入
    准备工作MQTTX设备模拟工具下载MQTTX是由EMQ开发的一款开源跨平台MQTT5.0桌面客户端,它兼容macOS,Linux以及Windows系统。MQTTX的用户界面UI采用聊天式设计,使得操作逻辑更加简明直观。它支持用户快速创建和保存多个MQTT连接,便于测试MQTT/MQTTS连接,以及MQTT消息的订阅和发布。M......
  • Windows上使用FFmpeg实现本地视频推送模拟海康协议rtsp视频流
    场景Nginx搭建RTMP服务器+FFmpeg实现海康威视摄像头预览:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/121202130上面记录的是使用FFmpeg拉取海康协议摄像头的rtsp流并推流到流媒体服务器。如果在其它业务场景下需要本地的视频文件模拟海康的rtsp流协议格式进行......
  • QT交叉编译环境
      原文:https://www.jianshu.com/p/d4ad988635211PC端安装Qtsudoapt-getinstallqtcreator将安装全套的Qt开发环境,可以在PC端进行qt开发。2安装交叉编译工具链Ubuntu14.04的Qt版本为5.2.1,16.04的Qt版本为5.5.1,高版本Qt库可以向下兼容运行低版本工具链编译的程序,......
  • 简单理解QT中的信号和槽
    信号和槽信号和槽之间的连接,实现对象间的通信。信号是一个发出的动作或事件。槽是对应的响应动作。一个信号可以关联多个槽函数,信号也可以连接信号使用信号槽,类必须继承QObject。在类的定义开头需要添加宏定义Q_OBJECT实现方式通过函数指针连接connect(sen......
  • ffmpeg 之 sdl
    使用ffmpeg解码视频渲染到sdl窗口前言使用ffmpeg解码视频并渲染视频到窗口,网上是有不少例子的,但是大部分例子的细节都不是很完善,比如资源释放、flush解码缓存、多线程优化等都没有。特别是想要快速搭建一个demo时,总是要重新编写不少代码,比较不方便,所以在这里提供一个完善的例子,......