windows 使用ffmpeg .a静态库:读取Wav音频并保存PCM

ffmpeg读取Wav音频并保存PCM(源代码保存成 c 文件):

cpp 复制代码
// test_ffmpeg.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

//#include <iostream>

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
//#pragma comment(lib, "libavdevice.a")
//#pragma comment(lib, "libavformat.a")
//#pragma comment(lib, "libavutil.a")
//#pragma comment(lib, "libavcodec.a")
//#pragma comment(lib, "libavfilter.a")
//#pragma comment(lib, "libswresample.a")
//#pragma comment(lib, "libswscale.a")

int main(int arvc, char*argv[]) {
    //av_register_all();
    printf("start...\n");
    AVFormatContext* formatCtx = NULL;
    const AVInputFormat* inputFmt = av_find_input_format(arvc > 1 ? argv[1] : "FLAC");

	int ret = 0;
	printf("format name: %s, long name; %s\n", inputFmt->name, inputFmt->long_name);
    // 打开输入流
    if ((ret = avformat_open_input(&formatCtx, "D:\\project\\ffmpeg-6.1.1\\test_in.wav", inputFmt, NULL)) != 0) {
        printf("Unable to open input stream: %s\n", av_err2str(ret));
        return -1;
    }

    // 查找音频流信息
    if (avformat_find_stream_info(formatCtx, NULL) < 0) {
        printf("Unable to find audio stream information: %s\n", av_err2str(ret));
        return -1;
    }

    // 寻找第一个音频流索引
    int audioStreamIndex = av_find_best_stream(formatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
    if (audioStreamIndex < 0) {
        printf("Unable to find audio stream: %s\n", av_err2str(ret));
        return -1;
    }

    //const AVCodecContext* codecCtx = formatCtx->streams[audioStreamIndex]->codec;
    AVCodecContext* pCodecCtx = avcodec_alloc_context3(NULL);
    if (pCodecCtx == NULL)
    {
        printf("Could not allocate AVCodecContext: %s\n", av_err2str(ret));
        return -1;
    }
    avcodec_parameters_to_context(pCodecCtx, formatCtx->streams[audioStreamIndex]->codecpar);

    // 打开解码器
    const AVCodec* codec = avcodec_find_decoder(pCodecCtx->codec_id);
    if (avcodec_open2(pCodecCtx, codec, NULL) < 0) {
        printf("Unable to open decoder: %s\n", av_err2str(ret));
        return -1;
    }

    // 创建输出文件
    FILE* outputFile = fopen("output.pcm", "wb");

    AVPacket packet;

	printf("start read frame...\n");
    while ((ret = av_read_frame(formatCtx, &packet)) == 0) {
        // 如果数据包是音频数据
        if (packet.stream_index == audioStreamIndex) {
            AVFrame* frame = av_frame_alloc();
            int gotFrame = 0;

			printf("read frame...index %d\n", audioStreamIndex);
            // 解码音频帧
            //avcodec_decode_audio4(pCodecCtx, frame, &gotFrame, &packet);
            if (avcodec_send_packet(pCodecCtx, &packet) < 0
                || (gotFrame = avcodec_receive_frame(pCodecCtx, frame)) < 0) {
                return -1;
            }

			printf("read frame...gotFrame = %d, frame size %d, frame pointer 0x%x\n", (ret), frame->linesize[0], frame->data[0]);
            if (gotFrame == 0) {
                // 处理解码后的音频数据,例如写入文件等
                fwrite(frame->data[0], 1, frame->linesize[0], outputFile);
            }

            av_frame_free(&frame);
        }

        //av_free_packet(&packet);
        av_packet_unref(&packet);
    }
	printf("read frame end. ret = %s\n", av_err2str(ret));

    fclose(outputFile);

    avformat_close_input(&formatCtx);
    return 0;
}

// 运行程序: Ctrl + F5 或调试 >"开始执行(不调试)"菜单
// 调试程序: F5 或调试 >"开始调试"菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到"项目">"添加新项"以创建新的代码文件,或转到"项目">"添加现有项"以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到"文件">"打开">"项目"并选择 .sln 文件

编译命令(使用windows 下的 MSYS2 UCRT64 工具):

bash 复制代码
gcc -c test.c -o test.o -I./ffmpeg-bin/include 

gcc -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Wl,--nxcompat,--dynamicbase -Wl,--high-entropy-va -Wl,--as-needed -Wl,--warn-common -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil  -Wl,--image-base,0x140000000 -o test_g test.o -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil  -lpsapi -lole32 -lstrmiids -luuid -loleaut32 -lshlwapi -lgdi32 -lm -latomic -lvfw32 -lm -latomic -lm -latomic -lz -lsecur32 -lws2_32 -liconv -lm -latomic -lmfuuid -lole32 -lstrmiids -lole32 -luser32 -lz -lm -latomic -lm -latomic -lm -luser32 -lbcrypt -latomic  -lole32 -lpsapi -lshell32

strip -o test_1.exe test_g.exe

# 使用upx压缩应用(需要windows终端执行)
upx.exe -9 -o test.exe test_1.exe

rm -rf test_g.exe test_1.exe

./test.exe
相关推荐
写bug的小屁孩1 小时前
前后端交互接口(三)
运维·服务器·数据库·windows·用户界面·qt6.3
hairenjing11233 小时前
在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序
android·人工智能·windows·macos·智能手机
EasyCVR5 小时前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
plmm烟酒僧6 小时前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
简鹿办公6 小时前
使用 FFmpeg 进行音视频转换的相关命令行参数解释
ffmpeg·简鹿视频格式转换器·ffmpeg视频转换
Jtti9 小时前
Windows系统服务器怎么设置远程连接?详细步骤
运维·服务器·windows
小奥超人9 小时前
PPT文件设置了修改权限,如何取消权?
windows·经验分享·microsoft·ppt·办公技巧
EasyCVR10 小时前
萤石设备视频接入平台EasyCVR多品牌摄像机视频平台海康ehome平台(ISUP)接入EasyCVR不在线如何排查?
运维·服务器·网络·人工智能·ffmpeg·音视频
runing_an_min10 小时前
ffmpeg 视频滤镜:屏蔽边框杂色- fillborders
ffmpeg·音视频·fillborders
hairenjing112318 小时前
使用 Mac 数据恢复从 iPhoto 图库中恢复照片
windows·stm32·嵌入式硬件·macos·word