暂时记录,还有很多需要改善的地方一直没弄好,比如不知道怎么对上正确的播放速度。

  有一些多余的代码,不用在意。

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <windows.h>
#include <Mmreg.h>
#include <mmeapi.h>
#include <Windows.h>
#include <fftw3.h>
#include <math.h> extern "C" {
#include "libavcodec/avcodec.h"
#include "libavutil/opt.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
#include "libavutil/mathematics.h"
} #pragma comment(lib, "C:/Program Files/ffmpeg/lib/avcodec.lib")
#pragma comment(lib, "C:/Program Files/ffmpeg/lib/avformat.lib")
#pragma comment(lib, "C:/Program Files/ffmpeg/lib/avutil.lib")
#pragma comment(lib, "C:/Program Files/ffmpeg/lib/avdevice.lib")
#pragma comment(lib, "C:/Program Files/ffmpeg/lib/swresample.lib") #pragma comment(lib, "Winmm.lib")
#pragma comment(lib, "C:/fftw/libfftw3-3.lib")
#pragma comment(lib, "C:/fftw/libfftw3f-3.lib")
#pragma comment(lib, "C:/fftw/libfftw3l-3.lib") // #pragma comment(lib, "C:/opencv-4.1.2/build/install/x64/vc16/lib/opencv_world412d.lib") #pragma warning(disable:4996) #define RATE 44100
#define PIPE 2
#define PI 3.1415926
#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
#define AV_CODEC_MAX_AUDIO_FRAME_SIZE 16384
#define MAX_AUDIO_FRAME_SIZE 320000
#define SECOND 35 int decode_audio_file(HWAVEOUT hWavO, WAVEHDR whr, WAVEHDR whr2, const char* filename)
{
av_register_all();
avformat_network_init(); AVFormatContext* format = avformat_alloc_context();
if (avformat_open_input(&format, filename, NULL, NULL) != 0) {
fprintf(stderr, "Could not open file '%s'\n", filename);
return -1;
}
if (avformat_find_stream_info(format, NULL) < 0) {
fprintf(stderr, "Could not retrieve stream info from file '%s'\n", filename);
return -1;
} av_dump_format(format, 0, filename, false); // Find the index of the first audio stream
int stream_index = -1;
for (int i = 0; i < format->nb_streams; i++)
{
if (format->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
stream_index = i;
break;
}
}
if (stream_index == -1)
{
fprintf(stderr, "Could not retrieve audio stream from file '%s'\n", filename);
return -1;
}
AVStream* stream = format->streams[stream_index]; // find & open codec
AVCodecContext* codec = stream->codec;
if (avcodec_open2(codec, avcodec_find_decoder(codec->codec_id), NULL) < 0)
{
fprintf(stderr, "Failed to open decoder for stream #%u in file '%s'\n", stream_index, filename);
return -1;
} // prepare to read data
AVPacket * packet = (AVPacket*)av_malloc(sizeof(AVPacket));
av_init_packet(packet); AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16; int out_channels_layout = AV_CH_LAYOUT_STEREO;
int out_channels = av_get_channel_layout_nb_channels(out_channels_layout);
int out_buffer_size = av_samples_get_buffer_size(NULL, out_channels, codec->frame_size, out_sample_fmt, 1);
PBYTE buffer = (uint8_t*)av_malloc(MAX_AUDIO_FRAME_SIZE * 2); AVFrame* frame = av_frame_alloc();
if (!frame)
{
fprintf(stderr, "Error allocating the frame\n");
return -1;
}
// prepare resampler
struct SwrContext* swr = swr_alloc(); av_opt_set_int(swr, "in_channel_count", codec->channels, 0);
av_opt_set_int(swr, "out_channel_count", 2, 0);
av_opt_set_int(swr, "in_channel_layout", av_get_default_channel_layout(codec->channels), 0);
av_opt_set_int(swr, "out_channel_layout", out_channels_layout, 0);
av_opt_set_int(swr, "in_sample_rate", codec->sample_rate, 0);
av_opt_set_int(swr, "out_sample_rate", codec->sample_rate, 0);
av_opt_set_sample_fmt(swr, "in_sample_fmt", codec->sample_fmt, 0);
av_opt_set_sample_fmt(swr, "out_sample_fmt", out_sample_fmt, 0);
swr_init(swr);
if (!swr_is_initialized(swr)) {
fprintf(stderr, "Resampler has not been properly initialized\n");
return -1;
} whr.lpData = (LPSTR)buffer;
whr.dwBufferLength = out_buffer_size;
waveOutPrepareHeader(hWavO, &whr, sizeof(whr)); whr2.lpData = (LPSTR)buffer;
whr2.dwBufferLength = out_buffer_size;
waveOutPrepareHeader(hWavO, &whr2, sizeof(whr2)); // iterate through frames
while (av_read_frame(format, packet) >= 0) {
if (packet->stream_index == stream_index)
{
int gotFrame;
if (avcodec_decode_audio4(codec, frame, &gotFrame, packet) < 0) {
break;
}
if (gotFrame > 0)
{
int frame_count = swr_convert(swr, &buffer,
MAX_AUDIO_FRAME_SIZE,
(const uint8_t**)frame->data,
frame->nb_samples); for (int i = 0; i < codec->sample_rate * SECOND; i++)
{
waveOutWrite(hWavO, &whr, sizeof(whr));
} for (int i = 0; i < codec->sample_rate * SECOND; i++)
{
waveOutWrite(hWavO, &whr2, sizeof(whr2));
}
}
}
av_free_packet(packet);
} // clean up
av_free(buffer);
av_frame_free(&frame);
swr_free(&swr);
avcodec_close(codec);
avformat_free_context(format); return 0;
} int audio_decode(/*const char * outfilename, */HWAVEOUT hWavO, WAVEHDR whr, WAVEHDR whr2, const char * filename)
{
AVFormatContext* pFormatCtx;
AVCodecContext* pCodecCtx;
AVCodec* pCodec;
AVPacket* packet;
uint8_t* out_buffer;
AVFrame* pFrame;
int audioStream;
int got_picture;
int index = 0;
struct SwrContext* au_convert_ctx; //FILE* pFile = pFile = fopen(outfilename, "wb"); av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context(); if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) {
printf("Couldn't open input stream.\n");
return -1;
}
// Retrieve stream information
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
printf("Couldn't find stream information.\n");
return -1;
}
// Dump valid information onto standard error
av_dump_format(pFormatCtx, 0, filename, false); // Find the first audio stream
audioStream = -1;
for (int i = 0; i < pFormatCtx->nb_streams; i++)
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
audioStream = i;
break;
} if (audioStream == -1) {
printf("Didn't find a audio stream.\n");
return -1;
} // Get a pointer to the codec context for the audio stream
pCodecCtx = pFormatCtx->streams[audioStream]->codec; // Find the decoder for the audio stream
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
printf("Codec not found.\n");
return -1;
} // Open codec
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
printf("Could not open codec.\n");
return -1;
} packet = (AVPacket*)av_malloc(sizeof(AVPacket));
av_init_packet(packet); //Out Audio Param
uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO;
//nb_samples: AAC-1024 MP3-1152
int out_nb_samples = pCodecCtx->frame_size;
AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
int out_sample_rate = pCodecCtx->sample_rate;
int out_channels = av_get_channel_layout_nb_channels(out_channel_layout);
//Out Buffer Size
int out_buffer_size = av_samples_get_buffer_size(NULL, out_channels, out_nb_samples, out_sample_fmt, 1); out_buffer = (uint8_t*)av_malloc(MAX_AUDIO_FRAME_SIZE * 2);
pFrame = av_frame_alloc(); //FIX:Some Codec's Context Information is missing
int64_t in_channel_layout = av_get_default_channel_layout(pCodecCtx->channels);
//Swr au_convert_ctx = swr_alloc();
au_convert_ctx = swr_alloc_set_opts(au_convert_ctx,
out_channel_layout,
out_sample_fmt,
out_sample_rate,
in_channel_layout,
pCodecCtx->sample_fmt,
pCodecCtx->sample_rate, 0, NULL);
swr_init(au_convert_ctx); whr.lpData = (LPSTR)out_buffer;
whr.dwBufferLength = out_buffer_size;
waveOutPrepareHeader(hWavO, &whr, sizeof(whr)); whr2.lpData = (LPSTR)out_buffer;
whr2.dwBufferLength = out_buffer_size;
waveOutPrepareHeader(hWavO, &whr2, sizeof(whr2));
//waveOutSetPlaybackRate(hWavO, 0x8000); 本来想用来调节播放速率 但用了之后发现只能变声,不知道为啥 while (av_read_frame(pFormatCtx, packet) >= 0) {
if (packet->stream_index == audioStream) {
int ret = avcodec_decode_audio4(pCodecCtx, pFrame, &got_picture, packet);
if (ret < 0) {
printf("Error in decoding audio frame.\n");
return -1;
}
if (got_picture > 0) {
swr_convert(au_convert_ctx, &out_buffer,
MAX_AUDIO_FRAME_SIZE, (const uint8_t**)pFrame->data,
pFrame->nb_samples);
#if SHOW
printf("index:%5d\t pts:%lld\t packet size:%d\n", index, packet->pts, packet->size);
#endif //fwrite(out_buffer, 1, out_buffer_size, pFile); for (int i = 0; i < pCodecCtx->sample_rate * SECOND; i++)
{
waveOutWrite(hWavO, &whr, sizeof(whr));
} for (int i = 0; i < pCodecCtx->sample_rate * SECOND; i++)
{
waveOutWrite(hWavO, &whr2, sizeof(whr2));
} index++;
} }
av_free_packet(packet);
} swr_free(&au_convert_ctx); //fclose(pFile); av_free(out_buffer);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
} void GenerateAudio(HWAVEOUT hWavO, WAVEHDR whr)
{
double freq[] = { 261.625, 293.664, 329.627, 349.228, 391.995, 440, 493.883, 523.251 };
PBYTE buffer = new BYTE[RATE * SECOND];
for (int j = 0; j < 8; j++)
{
double w = (2 * PI) / freq[j];
for (int i = 0; i < RATE * SECOND; i++)
{
buffer[i] = 127 + 127 * std::sin(w * i);
} whr.lpData = (LPSTR)buffer;
whr.dwBufferLength = RATE * SECOND;
waveOutPrepareHeader(hWavO, &whr, sizeof(whr));
for (int i = 0; i < RATE; i++)
waveOutWrite(hWavO, &whr, sizeof(whr));
}
delete[] buffer;
} int main()
{
WAVEHDR whr, whr2;
WAVEFORMATEX wfx;
HWAVEOUT hWavO; wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nSamplesPerSec = RATE;
wfx.nChannels = PIPE;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = PIPE * wfx.wBitsPerSample / 8;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
wfx.cbSize = 0; if (waveOutOpen(&hWavO, WAVE_MAPPER, &wfx, NULL, 0, CALLBACK_NULL) != MMSYSERR_NOERROR)
std::cout << "出错"; whr.dwLoops = 1;
whr.dwFlags = 0;
whr2.dwLoops = 1;
whr2.dwFlags = 0; //GenerateAudio(hWavO, whr);
//audio_decode(hWavO, whr, whr2, "E:/CloudMusic/xxx.mp3");
decode_audio_file(hWavO, whr, whr2, "E:/CloudMusic/xxx.mp3"); waveOutUnprepareHeader(hWavO, &whr, sizeof(whr));
waveOutUnprepareHeader(hWavO, &whr2, sizeof(whr2));
waveOutClose(hWavO);
return 0;
}

  

win api + ffmpeg 播放 mp3 音乐的更多相关文章

  1. Android命令行播放MP3音乐

    /*************************************************************************** * Android命令行播放MP3音乐 * 说 ...

  2. Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)

    项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ...

  3. 在C语言控制台程序中播放MP3音乐

    游戏没有声音多单调. 这里做一个简单的范例,用 mciSendString 函数播放 MP3 格式的音乐,先看看代码吧: // 编译该范例前,请把 background.mp3 放在项目文件夹中 // ...

  4. CentOS 6.x 播放 mp3 音乐 —— 成功

    参考:http://blog.chinaunix.net/uid-14735472-id-3472898.html centos 6.x  添加 rpmforge 源--- CentOS 6.x 安装 ...

  5. 实现微信浏览器自动播放MP3音乐

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. Android应用开发--MP3音乐播放器代码实现(一)

    需求1:将内存卡中的MP3音乐读取出来并显示到列表当中 1.   从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3Info对象 2.   迭代List集合,把每一个Mp3 ...

  7. 博客中 Flex4/Flash mp3音乐播放器实例 含演示地址

    要求 必备知识 本文要求基本了解 Adobe Flex编程知识和JAVA基础知识. 开发环境 MyEclipse10/Flash Builder4.6/Flash Player11及以上 演示地址 演 ...

  8. VC用MCI播放mp3等音乐文件

    VC播放mp3等音乐文件,可以使用MCI.MCI ( Media Control Interface ) ,即媒体控制接口,向基于Windows操作系统的应用程序提供了高层次的控制媒体设备接口的能力. ...

  9. 推荐美丽的flash网页MP3音乐播放器

    文章来源:PHP开发学习门户 地址:http://www.phpthinking.com/archives/491 在网页制作中.假设想在网页中插入mp3音乐来增添网页的互动感,提升用户体验度,这个时 ...

随机推荐

  1. 服务器的公网ip 和内网ip

    原文地址:https://zhidao.baidu.com/question/814783729071869532.html 服务器公网ip 可以用于域名解析ip,服务器远程登录ip,是最主要的服务器 ...

  2. 牛客网 —— 爱奇艺2020校招C++方向笔试题 总结

    错了5,6个,主要集中在数据库和操作系统上.    C++还需要提高熟练度. 总结 第6题: 折半查找树:根据二分查找构造得到的树,它一定是一个二叉排序树,是一个特殊的二叉排序树.  (接近于平衡二叉 ...

  3. 摇一摇—微信7.0.8版本audio无法自动播放问题

    近日有一个项目出现audio无法自动播放,查看原因才发现是微信版本更新为7.0.8版本,需要有交互行为,第一次播放需要用户手动点击一下,无法使用DOM中的play()进行直接播放操作,那怎么办呢? 通 ...

  4. C#索引器学习笔记

    本笔记摘抄自:https://www.cnblogs.com/ArmyShen/archive/2012/08/27/2659405.html,记录一下学习过程以备后续查用. 索引器允许类或者结构的实 ...

  5. C# 索引器的理解和使用

    概述 此部分内容引用自MSDN文档 使用索引器可以用类似于数组的方式为对象建立索引. get 取值函数返回值. set 取值函数分配值. this 关键字用于定义索引器. value 关键字用于定义 ...

  6. jQuery---html方法和text方法

    html方法和text方法 //html:innerHTML text:innerText console.log($("div").html());//<h3>我是标 ...

  7. knitr::kable实现结构化展示数据

    一般做检验,直接会summary结果,通常情况下,会看到很多很多,口区~ 如何提取有用的信息,然后结构化展示数据呢? kable函数了. 我先给出学长给我的一部分,回头整理好了再补充 culture_ ...

  8. 【巨杉数据库SequoiaDB】巨杉Tech | 四步走,快速诊断数据库集群状态

    1.背景 SequoiaDB 巨杉数据库是一款金融级分布式数据库,包括了分布式 NewSQL.分布式文件系统与对象存储.与高性能 NoSQL 三种存储模式,分别对应分布式在线交易.非结构化数据和内容管 ...

  9. eclipse中创建了web项目,src下创建子目录是平级的情况

    1.在以下可设置不同的视图 windows->show view菜单 ->点Other......    然后在搜索框里输入你想要的视图 2.在Project Explorer下创建的包看 ...

  10. 51Nod 1091 线段的重叠 (贪心)

    X轴上有N条线段,每条线段包括1个起点和终点.线段的重叠是这样来算的,[10 20]和[12 25]的重叠部分为[12 20]. 给出N条线段的起点和终点,从中选出2条线段,这两条线段的重叠部分是最长 ...