Qt+rtsp+ffmpeg 播放声音

Qt+rtsp+ffmpeg播放声音

#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();
}

可以进行下载:

https://download.csdn.net/download/qq_18286031/12737328

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值