ffmpeg把pcm封装为wav

ops/2024/10/18 7:47:53/

note

1.wav格式中,音频数据未经过压缩,直接封装即可

2.对于编码器的选择,应选择和pcm裸数据一致的编码器(本次实际不须编码)

version

#define LIBSWRESAMPLE_VERSION_MAJOR 2

#define LIBSWRESAMPLE_VERSION_MINOR 9

#define LIBSWRESAMPLE_VERSION_MICRO 100

#define LIBAVCODEC_VERSION_MINOR 31

#define LIBAVCODEC_VERSION_MICRO 102

code

void CFfmpegOps::MuxPCMToWAV(const char* pcm_file, const char* wav_file)
{const AVOutputFormat* out_fmt = nullptr;AVFormatContext* fmt_ctx = nullptr;const AVCodec* codec = nullptr;AVCodecContext* codec_ctx = nullptr;AVStream* avstream = nullptr;AVPacket* avpacket = nullptr;AVFrame* avframe = nullptr;int ret = -1;FILE* in_fp = nullptr;int sample_fmt_is_planar = 0;size_t n = 0;int frame_data_bytes = 0;codec = avcodec_find_encoder(AV_CODEC_ID_PCM_F32LE);if (!codec){printf("avcodec_find_encoder error\n");goto END;}codec_ctx = avcodec_alloc_context3(codec);if (!codec_ctx){printf("avcodec_alloc_context3 error\n");goto END;}codec_ctx->sample_fmt = AV_SAMPLE_FMT_FLT;  // f32lecodec_ctx->sample_rate = 44100;codec_ctx->channel_layout = AV_CH_LAYOUT_STEREO;codec_ctx->channels = av_get_channel_layout_nb_channels(codec_ctx->channel_layout);ret = avcodec_open2(codec_ctx, codec, nullptr);if (ret < 0){printf("avcodec_open2 error(%s)\n", GetFfmpegERR(ret));goto END;}printf("frame_size:%d\n", codec_ctx->frame_size);avframe = av_frame_alloc();if (!avframe){printf("av_frame_alloc error\n");goto END;}avframe->format = AV_SAMPLE_FMT_FLT;avframe->sample_rate = 44100;avframe->channel_layout = AV_CH_LAYOUT_STEREO;avframe->channels = av_get_channel_layout_nb_channels(avframe->channel_layout);avframe->nb_samples = 1024;ret = av_frame_get_buffer(avframe, 0);if (ret < 0){printf("av_frame_get_buffer error(%s)\n", GetFfmpegERR(ret));goto END;}ret = av_samples_get_buffer_size(nullptr, avframe->channels,avframe->nb_samples,(AVSampleFormat)(avframe->format),1);if (ret < 0){printf("av_samples_get_buffer_size error(%s)\n", GetFfmpegERR(ret));goto END;}frame_data_bytes = ret;avpacket = av_packet_alloc();if (!avpacket){printf("av_packet_alloc error\n");goto END;}in_fp = fopen(pcm_file, "rb");if (!in_fp){printf("fopen error\n");goto END;}ret = avformat_alloc_output_context2(&fmt_ctx, nullptr, nullptr, wav_file);if (ret < 0){printf("avformat_alloc_output_context2 error(%s)\n", GetFfmpegERR(ret));goto END;}out_fmt = fmt_ctx->oformat;avstream = avformat_new_stream(fmt_ctx, codec);if (!avstream){printf("avformat_new_stream error\n");goto END;}ret = avcodec_parameters_from_context(avstream->codecpar, codec_ctx);if (ret < 0){printf("avcodec_parameters_from_context error(%s)\n", GetFfmpegERR(ret));goto END;}ret = avio_open(&(fmt_ctx->pb), wav_file, AVIO_FLAG_READ_WRITE);if (ret < 0){printf("avio_open error(%s)\n", GetFfmpegERR(ret));goto END;}ret = avformat_write_header(fmt_ctx, nullptr);if (ret < 0){printf("avformat_write_header error(%s)\n", GetFfmpegERR(ret));goto END;}while (1){if (feof(in_fp)){break;}sample_fmt_is_planar = av_sample_fmt_is_planar((AVSampleFormat)(avframe->format));if (sample_fmt_is_planar){n = fread(avframe->data[0], sizeof(uint8_t), frame_data_bytes / 2, in_fp);if ((int)n != (frame_data_bytes / 2)){printf("n != (frame_data_bytes / 2)\n");}n = fread(avframe->data[1], sizeof(uint8_t), frame_data_bytes / 2, in_fp);if ((int)n != (frame_data_bytes / 2)){printf("n != (frame_data_bytes / 2)\n");}}else{n = fread(avframe->data[0], sizeof(uint8_t), frame_data_bytes, in_fp);if ((int)n != frame_data_bytes){printf("n != (frame_data_bytes)\n");}}ret = avcodec_send_frame(codec_ctx, avframe);if (ret < 0){if (ret == AVERROR(EAGAIN)){printf("read output first\n");}else{printf("avcodec_send_frame error(%s)\n", GetFfmpegERR(ret));break;}}while (1){ret = avcodec_receive_packet(codec_ctx, avpacket);if (ret < 0){if (ret == AVERROR(EAGAIN)){printf("send input first\n");break;}else{printf("avcodec_receive_packet error(%s)\n", GetFfmpegERR(ret));break;}}ret = av_write_frame(fmt_ctx, avpacket);if (ret < 0){printf("av_write_frame error(%s)\n", GetFfmpegERR(ret));av_packet_unref(avpacket);goto END;}av_packet_unref(avpacket);}}ret = avcodec_send_frame(codec_ctx, nullptr);while (1){ret = avcodec_receive_packet(codec_ctx, avpacket);if (ret < 0){if (ret == AVERROR(EAGAIN)){printf("send input first\n");break;}else{printf("avcodec_receive_packet error(%s)\n", GetFfmpegERR(ret));break;}}ret = av_write_frame(fmt_ctx, avpacket);if (ret < 0){printf("av_write_frame error(%s)\n", GetFfmpegERR(ret));av_packet_unref(avpacket);goto END;}av_packet_unref(avpacket);}ret = av_write_trailer(fmt_ctx);if (ret < 0){printf("av_write_trailer error(%s)\n", GetFfmpegERR(ret));goto END;}END:if (fmt_ctx){avformat_free_context(fmt_ctx);fmt_ctx = nullptr;}if (in_fp){fclose(in_fp);in_fp = nullptr;}if (avframe){av_frame_free(&avframe);avframe = nullptr;}if (avpacket){av_packet_free(&avpacket);avpacket = nullptr;}if (codec_ctx){avcodec_free_context(&codec_ctx);codec_ctx = nullptr;}
}

performance


http://www.ppmy.cn/ops/84773.html

相关文章

【常见开源库的二次开发】基于openssl的加密与解密——SHA算法源码解析(六)

目录 一、SHA-1算法分析&#xff1a; 1.1 Merkle Tree可信树 1.2 源码实现&#xff1a; 1.3 哈希计算功能 1.4 两种算法的区别&#xff1a; 1.4.1 目的 1.4.2 实现机制 1.4.3 输出 1.4.4 应用场景&#xff1a; 1.4 运行演示&#xff1a; 二、SHA-2算法分析&#xff1a; 2.1哈…

在线教育数仓项目(数据采集部分1)

文章目录 数据仓库概念项目需求及架构设计项目需求分析系统数据流程设计框架版本选型集群规模估算集群资源规划设计 数据生成模块目标数据页面事件曝光启动播放错误 数据埋点主流埋点方式&#xff08;了解&#xff09;埋点数据上报时机埋点数据日志结构 服务器和JDK准备服务器准…

VUE 基础(一)

(直接在vscode上运行就可以&#xff0c;建一个html文件) 1 el的使用 Vue会管理el选项命中的元素及其内部的后代元素 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content…

AutoAgents: A Framework for Automatic AgentGeneration

https://arxiv.org/abs/2309.17288https://arxiv.org/abs/2309.17288 1.概述 大语言模型(LLM)已展现出作为通用任务解决智能体的卓越能力,其知识储备与技能水平令人瞩目。然而,在面对需要高度密集知识与复杂推理的任务时,如预防幻觉、采用深度思考策略、确保信息可信度以…

Java消失的数字

题目要求 数组nums包含从0到n的所有整数&#xff0c;但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗&#xff1f; 示例 1&#xff1a; 输入&#xff1a;[3,0,1] 输出&#xff1a;2 示例 2&#xff1a; 输入&#xff1a;[9,6,4,2,3,5,7,0,1] 输出&a…

【JS逆向课件:第十六课:Scrapy基础2】

ImagePipeLines的请求传参 环境安装&#xff1a;pip install Pillow USER_AGENT Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36需求&#xff1a;将图片的名称和详情页中图片的数据进行爬取&a…

CSS3 scale 适配

Scale适配&#xff0c;在前端开发中&#xff0c;特别是在CSS3中&#xff0c;主要指的是使用scale()函数对元素进行缩放处理&#xff0c;以适应不同的屏幕尺寸或达到特定的视觉效果。以下是对Scale适配的详细介绍&#xff1a; 一、基本概念 scale() 是CSS3中transform属性的一…

Vue 3 实现左侧列表点击跳转滚动到右侧对应区域的功能

使用 Vue 3 实现左侧列表点击跳转到右侧对应区域的功能 1. 引言 在这篇博客中&#xff0c;我们将展示如何使用 Vue 3 实现一个简单的页面布局&#xff0c;其中左侧是一个列表&#xff0c;点击列表项时&#xff0c;右侧会平滑滚动到对应的内容区域。这种布局在很多应用场景中都…