qt+ffmpeg 实现音视频播放(二)之音频播放

这篇具有很好参考价值的文章主要介绍了qt+ffmpeg 实现音视频播放(二)之音频播放。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、音频播放流程

1、打开音频文件

通过  avformat_open_input() 打开媒体文件并分配和初始化  AVFormatContext  结构体。

函数原型如下:
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);

参数说明:
- `ps`:指向 `AVFormatContext` 结构体指针的指针,用于存储打开的媒体文件的信息。
- `url`:要打开的媒体文件的 URL 或文件路径。
- `fmt`:指定输入格式,通常可以设置为 `NULL`,由 FFmpeg 根据文件内容自动检测。
- `options`:附加选项,可以传入一些额外的选项参数。

2、查找输入流信息

调用  avformat_find_stream_info()  函数将会读取媒体文件中的帧,解析它们的头部,
并填充 AVFormatContext 中的流信息,通过访问 AVFormatContext 的 streams 字段来获取每个流的详细信息。

函数原型如下:
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

参数说明:
- `ic`:指向已打开媒体文件的 `AVFormatContext` 结构体的指针。
- `options`:指向包含附加选项的 `AVDictionary` 指针。

3、查找流索引

使用 av_find_best_stream() 从媒体文件中找到最佳的流索引

函数原型如下:
int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream, int related_stream, AVCodec **decoder_ret, int flags);

参数说明:
- `ic`:指向已打开媒体文件的 `AVFormatContext` 结构体的指针。
- `type`:要查找的流类型,可以是 `AVMEDIA_TYPE_VIDEO`、`AVMEDIA_TYPE_AUDIO` 等。
- `wanted_stream`:期望的流索引,如果为负值,则表示没有特定的偏好。
- `related_stream`:相关流索引,用于查找与之相关的最佳流。
- `decoder_ret`:用于返回找到的解码器。
- `flags`:附加标志,可以用来指定额外的查找选项。

4、查找解码器

使用 avcodec_find_decoder() 查找符合指定解码器名称的解码器。

函数原型如下:
AVCodec *avcodec_find_decoder(enum AVCodecID id);

参数说明:
- `id`:要查找的解码器的 ID。

5、初始化解码上下文

调用  avcodec_alloc_context3()  函数会为特定的编解码器分配一个  AVCodecContext  结构体,并对其进行初始化。 AVCodecContext  结构体包含了编解码器的相关参数和状态信息,比如编解码器类型、解码参数、帧率等。

函数原型如下:
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
参数说明:
- `codec`:指定要使用的编解码器,可以通过 `avcodec_find_decoder()` 或其他方式获取。

6、获取解码参数

调用 `avcodec_parameters_to_context()` 函数可以方便地将 `AVCodecParameters` 结构体中的参数(如编解码器类型、帧率、分辨率等)复制到 `AVCodecContext` 结构体中,从而准备进行编解码操作。

函数原型如下:
int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par);

参数说明:
- `codec`:要填充参数的 `AVCodecContext` 结构体指针。
- `par`:包含编解码器参数的 `AVCodecParameters` 结构体指针。

7、打开解码器

调用 `avcodec_open2()` 函数可以打开并初始化指定的编解码器上下文,使其准备好进行编解码操作。

函数原型如下:
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
参数说明:
- `avctx`:要打开和初始化的编解码器上下文。
- `codec`:要使用的编解码器,可以通过 `avcodec_find_decoder()` 或其他方式获取。
- `options`:可选的字典参数,用于设置编解码器的选项。

打开解码器时可以使用多线程参数优化解码速度。

AVDictionary* opts = NULL;
//使用多线程解码
if (!av_dict_get(opts, "threads", NULL, 0))
    av_dict_set(&opts, "threads", "auto", 0);

8、创建音频重采样上下文

调用 `swr_alloc_set_opts()` 函数可以创建一个音频重采样上下文,并设置其参数。这个函数可以方便地指定输入和输出音频的通道布局、采样格式和采样率等参数。
 

函数原型如下:
struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
                                      int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
                                      int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate,
                                      int log_offset, void *log_ctx);
参数说明:
- `s`:要创建或设置参数的音频重采样上下文。如果传入非空指针,则会设置现有上下文的参数;如果传入空指针,则会创建一个新的上下文。
- `out_ch_layout`:输出音频的通道布局(channel layout)。
- `out_sample_fmt`:输出音频的采样格式(sample format)。
- `out_sample_rate`:输出音频的采样率(sample rate)。
- `in_ch_layout`:输入音频的通道布局。
- `in_sample_fmt`:输入音频的采样格式。
- `in_sample_rate`:输入音频的采样率。
- `log_offset`:日志输出偏移量。
- `log_ctx`:日志上下文。

9、初始化音频重采样上下文

调用 `swr_init()` 函数可以初始化音频重采样上下文,使其准备好进行音频重采样操作。


函数原型如下:
int swr_init(struct SwrContext *s);
参数说明:
- `s`: 要初始化的音频重采样上下文。

10、分配并初始化一个临时的帧和包

调用 `av_packet_alloc()` 函数可以分配一个 AVPacket 结构体,并返回指向该结构体的指针。AVPacket 结构体用于存储音视频数据,包括数据缓冲区、大小、时间戳等信息。

调用 `av_frame_alloc()` 函数可以分配一个 AVFrame 结构体,并返回指向该结构体的指针。AVFrame 结构体用于存储音视频帧的数据,包括像素数据、采样数据、时间戳等信息。
 

函数原型如下:

AVPacket *av_packet_alloc(void);
AVFrame *av_frame_alloc(void);

11、读取音视频源文件

调用 `av_read_frame()` 函数可以从输入文件或流中读取一帧音视频数据,并将其存储在 AVPacket 结构体中。

函数原型如下:
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
参数说明:
- `s`:输入文件或流的 AVFormatContext 上下文。
- `pkt`:存储读取到的音视频帧数据的 AVPacket 结构体。

12、发送音频数据到解码器

调用 `avcodec_send_packet()` 函数可以将 AVPacket 数据包发送给解码器进行解码。在发送完所有数据包后,需要调用 `avcodec_send_packet()` 传递一个空的 AVPacket 指针,以便告知解码器已经发送完所有数据。

函数原型如下:
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
参数说明:
- `avctx`:指向 AVCodecContext 结构体的指针,表示解码器上下文。
- `avpkt`:指向要发送给解码器的 AVPacket 数据包的指针。

13、从解码器接收解码后的音频数据

调用 `avcodec_receive_frame()` 函数可以从解码器中接收解码后的音视频帧数据,并将其存储在 AVFrame 结构体中。


函数原型如下:
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
参数说明:
- `avctx`:指向 AVCodecContext 结构体的指针,表示解码器上下文。
- `frame`:用于存储接收到的解码后的 AVFrame 帧数据的结构体。
 

14、进行音频重采样

调用 `swr_convert()` 函数可以将输入缓冲区中的音频数据进行重采样,并将结果存储到输出缓冲区中。

函数原型如下:
int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, const uint8_t **in, int in_count);
参数说明:
- `s`:指向 SwrContext 结构体的指针,表示音频重采样上下文。
- `out`:指向输出音频数据缓冲区的指针数组。
- `out_count`:输出缓冲区中的样本数。
- `in`:指向输入音频数据缓冲区的指针数组。
- `in_count`:输入缓冲区中的样本数。

15、播放音频

将重采样后的数据写入声卡中进行播放。

简洁流程如下:

qt ffmpeg播放,ffmpeg,音视频,Qt,qt,ffmpeg,音视频

其他重要API:
void av_dump_format(const AVFormatContext *ic, int index,
                    const char *url, int is_output);

 //可以将输入/输出文件的格式信息以人类可读的形式打印出来,包括流的详细信息、编解码器信息等。这对于调试和了解输入/输出文件的结构和信息非常有帮助。
参数说明:
- `ic`:指向 AVFormatContext 结构体的指针,表示要进行格式信息输出的输入/输出文件的 AVFormatContext。
- `index`:如果为非负值,表示要输出的流的索引;如果为负值,表示输出所有流信息。
- `url`:文件的 URL 或名称,在打印信息时会用到。
- `is_output`:如果为非零值,表示输出的是输出文件的格式信息;如果为 0,表示输出的是输入文件的格式信息。

int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align);

//计算出存储指定数量音频样本所需的缓冲区大小。这个函数通常用于动态分配音频样本数据缓冲区的场景。
参数说明:
- `linesize`:指向存储每个通道数据大小的数组的指针。
- `nb_channels`:音频通道数。
- `nb_samples`:每个通道中的音频样本数。
- `sample_fmt`:音频样本格式,使用 AVSampleFormat 枚举类型。
- `align`:对齐方式,通常为 0。

AVFormatContext *avformat_alloc_context(void);

//用于分配内存并返回一个初始化后的 AVFormatContext 结构体指针。

AVFormatContext 结构体里面有一个重要的参数 interrupt_callback.callback ,用来设置回调函数。当调用av_read_frame或avformat_find_stream_info会阻塞执行很长时间的时候,只要设置该回调函数返回 1 ,那么就会不再阻塞,立即返回。

二、代码例程

音頻播放:点击跳转

視頻播放:点击跳转

觉得有帮助的话,打赏一下呗。。

qt ffmpeg播放,ffmpeg,音视频,Qt,qt,ffmpeg,音视频           qt ffmpeg播放,ffmpeg,音视频,Qt,qt,ffmpeg,音视频文章来源地址https://www.toymoban.com/news/detail-855313.html

到了这里,关于qt+ffmpeg 实现音视频播放(二)之音频播放的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 项目实战——Qt实现FFmpeg音视频转码器

    本文记录使用 Qt 实现 FFmepg 音视频转码器项目的开发过程。 1、首先创建一个 Qt 项目,选择 MSVC2017 32bit 作为其编译器 2、将 FFmpeg 相关库及源文件拷贝到当前目录下 3、注释 prepare_app_arguments 函数(这里方便后面我们运行时可以指定相应的转码参数) 4、将所需的一些 dll 动态库

    2024年01月23日
    浏览(46)
  • 使用Qt进行音视频播放

      Qt对音视频的播放和控制,相机拍照,收音机等多媒体应用提供了强大的支持。Qt5使用了全新的Qt Multimedia模块来实现多媒体应用,而原来Qt4中用于实现多媒体功能的Phonon模块已经被移除。   新的Qt Multimedia模块提供了丰富的接口,使读者可以轻松地使用平台的多媒体功

    2024年02月03日
    浏览(27)
  • Qt音视频开发38-ffmpeg视频暂停录制的设计

    基本上各种播放器提供的录制视频接口,都是只有开始录制和结束录制两个,当然一般用的最多的也是这两个接口,但是实际使用过程中,还有一种可能需要中途暂停录制,暂停以后再次继续录制,将中间部分视频不需要录制,跳过这部分不需要的视频,而且录制的视频文件

    2023年04月20日
    浏览(45)
  • Qt之基于QMediaPlayer的音视频播放器(支持常见音视频格式)

    Qt自带了一个Media Player的例子,如下图所示: 但是运行这个例子机会发现,连最基本的MP4格式视频都播放不了。因为QMediaPlayer是个壳(也可以叫框架),依赖本地解码器,视频这块默认基本上就播放个MP4,甚至连MP4都不能播放,如果要支持其他格式需要下载k-lite或者LAVFilter

    2024年02月02日
    浏览(41)
  • Qt音视频开发40-ffmpeg采集桌面并录制

    之前用ffmpeg打通了各种视频文件和视频流以及本地摄像头设备的采集,近期有个客户需求要求将整个桌面屏幕采集下来,并可以录制保存成MP4文件,以前也遇到过类似的需求,由于没有搞过,也没有精力去摸索和测试,所以也就一直耽搁着,近期刚好这个需求又来了,定下心

    2023年04月25日
    浏览(43)
  • 音视频开发系列(10):基于qt的音频推流

    今天分享一下利用qt录制音频,然后再利用ffmpeg推流到nginx服务器,最后再利用vlc进行拉流的demo。 首先介绍一下如何利用qt来进行音频的录制,qt的音频录制主要利用qt的QAudioFormat先进行音频信息的配置。主要需要配置以下的信息: 然后使用QAudioDeviceInfo来获取是否支持改设置

    2024年02月02日
    浏览(39)
  • Qt 多媒体音频模拟按钮发音(音视频启动)

    ## 项目演示 平台 :windows或者ubuntu  要求 :平台需要支持音频播放功能 文件格式 :.wav 可以使用剪映生成,音频部分,我这里是简短的音乐 # Qt 多媒体简介 Qt QSound是Qt框架中的一个类,用于播放音频文件。它可以在Qt应用程序中实现简单的音频播放功能,包括播放、暂停和停

    2024年02月03日
    浏览(38)
  • Qt/C++音视频开发50-不同ffmpeg版本之间的差异处理

    ffmpeg的版本众多,从2010年开始计算的项目的话,基本上还在使用的有ffmpeg2/3/4/5/6,最近几年版本彪的比较厉害,直接4/5/6,大版本之间接口有一些变化,特别是一些废弃接口被彻底删除了,而网络上的各种文章几乎都是ffmpeg3左右为主的,所以本人在写这个全功能播放组件的时

    2024年02月14日
    浏览(35)
  • Qt音视频开发41-文件推流(支持网页和播放器播放并切换进度)

    本功能最初也是有一些人提过类似的需求,就是能不能将本地的音视频文件,通过纯Qt程序推流出去,然后用户可以直接在网页上播放,也可以用各种播放器播放,然后还可以任意切换播放进度,其实说白了就是个文件服务器,用户通过网络地址访问以后,告诉对方当前是媒

    2024年02月01日
    浏览(46)
  • FFmpeg 播放器实现音视频同步的三种方式

    我们基于 FFmpeg 利用 OpenGL ES 和 OpenSL ES 分别实现了对解码后视频和音频的渲染,本文将实现播放器的最后一个重要功能:音视频同步。 老人们经常说, 播放器对音频和视频的播放没有绝对的静态的同步,只有相对的动态的同步,实际上音视频同步就是一个“你追我赶”的过

    2024年02月06日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包