ffmpeg版本:ffmpeg-20160413-git-0efafc5

#include <stdio.h>
#include <stdlib.h>
#include <string.h> extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
#include "SDL.h"
}; #define MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio Uint32 audio_len;//音频数据大小
Uint8 *audio_pos;//指向音频数据的指针 //回调函数
void fill_audio(void *userdata, Uint8 *stream, int len)
{
//SDL 2.0
SDL_memset(stream, 0, len);
if (audio_len == 0)
{
return;
} len = (len > audio_len ? audio_len : len); SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
audio_pos += len;
audio_len -= len;
} int main(int argc, char* argv[])
{
//FFmpeg
AVFormatContext *pFormatCtx;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVPacket packet;
AVFrame *pFrame;
struct SwrContext *au_convert_ctx;
int got_picture;
int audioIndex; //SDL
uint8_t *out_buffer;
SDL_AudioSpec wanted_spec;
int index = 0; char filepath[1024] = "";
printf("Usage: player.exe *.mp3\n");
if (argc == 2)
{
strcpy(filepath, argv[1]);
}
else
{
printf("Could not find a audio file\n");
return -1;
} av_register_all(); pFormatCtx = avformat_alloc_context(); if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0)
{
printf("Couldn't open input stream.\n");
return -1;
} if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
{
printf("Couldn't find stream information.\n");
return -1;
} av_dump_format(pFormatCtx, -1, filepath, 0); audioIndex = -1;
for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
{
//AVStream->codec不推荐使用
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
{
audioIndex = i;
break;
}
}
if (audioIndex == -1)
{
printf("Didn't find a audio stream.\n");
return -1;
} //------------------------------------------------
//新版本:分配、填充AVCodecContext
pCodecCtx = avcodec_alloc_context3(NULL);
if (pCodecCtx == NULL)
{
printf("Could not allocate AVCodecContext\n");
return -1;
} if (avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[audioIndex]->codecpar) < 0)
{
printf("Could not initialize AVCodecContext\n");
return -1;
}
//------------------------------------------------ pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL)
{
printf("Codec not found.\n");
return -1;
} if (avcodec_open2(pCodecCtx, pCodec, NULL)<0)
{
printf("Could not open codec.\n");
return -1;
} //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 = 44100;
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(); //Init
if (SDL_Init(SDL_INIT_AUDIO))
{
printf("Could not initialize SDL - %s\n", SDL_GetError());
return -1;
}
//SDL_AudioSpec
wanted_spec.freq = out_sample_rate;
wanted_spec.format = AUDIO_S16SYS;
wanted_spec.channels = out_channels;
wanted_spec.silence = 0;
wanted_spec.samples = out_nb_samples;
wanted_spec.callback = fill_audio;
wanted_spec.userdata = pCodecCtx; if (SDL_OpenAudio(&wanted_spec, NULL) < 0)
{
printf("can't open audio.\n");
return -1;
} au_convert_ctx = swr_alloc();
au_convert_ctx = swr_alloc_set_opts(au_convert_ctx, out_channel_layout, out_sample_fmt, out_sample_rate,
pCodecCtx->channel_layout, pCodecCtx->sample_fmt, pCodecCtx->sample_rate, 0, NULL);
swr_init(au_convert_ctx); //Play
SDL_PauseAudio(0); while (av_read_frame(pFormatCtx, &packet) >= 0)
{
if (packet.stream_index == audioIndex)
{
if (avcodec_decode_audio4(pCodecCtx, pFrame, &got_picture, &packet) < 0)
{
printf("Error in decoding audio frame.\n");
return -1;
}
if (got_picture)
{
swr_convert(au_convert_ctx, &out_buffer, MAX_AUDIO_FRAME_SIZE, (const uint8_t **)pFrame->data, pFrame->nb_samples);
printf("index:%5d\t pts:%lld\t packet size:%d\n", index, packet.pts, packet.size);
index++;
} while (audio_len > 0)//Wait until finish
{
SDL_Delay(1);
} //Audio buffer length
audio_len = out_buffer_size;
audio_pos = (Uint8 *)out_buffer; }
av_packet_unref(&packet);
} swr_free(&au_convert_ctx);
SDL_CloseAudio();//Close SDL
SDL_Quit();
av_free(out_buffer);
avcodec_free_context(&pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}

FFMPEG学习----使用SDL构建音频播放器的更多相关文章

  1. 最简单的基于FFMPEG+SDL的音频播放器 ver2 (采用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...

  2. 最简单的基于FFMPEG+SDL的音频播放器 ver2 (採用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...

  3. FFMPEG学习----使用SDL构建视频播放器

    #include <stdio.h> #include <string.h> extern "C" { #include "libavcodec/ ...

  4. ffmpeg+SDL2实现的音频播放器V2.0(无杂音)

    1. 前言 目前为止,学习了并记录了ffmpeg+SDL2显示视频以及事件(event)的内容. 这篇中记录ffmpeg+SDL2播放音频,没加入事件处理. 接下来加入事件处理并继续学习音视频同步,再 ...

  5. 11.QT-ffmpeg+QAudioOutput实现音频播放器

    1.前言      由于QAudioOutput支持的输入数据必须是原始数据,所以播放mp3,WAV,AAC等格式文件,需要解封装后才能支持播放.      而在QT中,提供了QMediaPlayer ...

  6. IOS开发之简单音频播放器

    今天第一次接触IOS开发的UI部分,之前学OC的时候一直在模拟的使用Target-Action回调模式,今天算是真正的用了一次.为了熟悉一下基本控件的使用方法,和UI部分的回调,下面开发了一个特别简易 ...

  7. 基于c开发的全命令行音频播放器

    cmus是一个内置了音频播放器的强大的音乐文件管理器.用它的基于ncurses的命令行界面,你可以浏览你的音乐库,并从播放列表或队列中播放音乐,这一切都是在命令行下. Linux上安装cmus 首先, ...

  8. HTML5 音频播放器-Javascript代码(短小精悍)

    直接上干货咯! //HTML5 音频播放器 lzpong 2015/01/19 var wavPlayer = function () { if(window.parent.wavPlayer) re ...

  9. 【jquery】一款不错的音频播放器——Amazing Audio Player

    前段时间分享了一款视频播放器,点击这里.今天介绍一款不错的音频播放器——Amazing Audio Player. 介绍: Amazing Audio Player 是一个使用很方便的 Windows ...

随机推荐

  1. 更换EMC VNX系列存储故障硬盘的检查步骤

    更换EMC VNX系列存储故障硬盘的检查步骤 VNX1代(VNX5300,VNX5500,VNX5700,VNX7500和VNX2代(VNX5400,5600,5800和VNX7600,8000)有区 ...

  2. ObjectArx 使用消息钩子实现鼠标滚轮旋转实体

    测试结果: 实现方法:主要是程序注册一个消息函数:func,拦截鼠标滚轮触发的消息,需要注意的是,以写的方式处理实体时需要锁定文档.注册func的主要方法是:BOOL acedRegisterFilt ...

  3. Go数组和切片你不知道的区别

    开篇语 数组和切片是两种不同的数据结构,比较常见,在Go语言中同时存在,今天我们就一起来看看他们在使用方式上,原理上的一些区别? 数组 在Go语言中,数组是一种具有相同类型固定大小的一种数据结构. 我 ...

  4. linux下安装mysql5.7.25详细教程

    前言 最近项目上线,开始给用户测试了.搞下来好多台服务器,自然要装一个mysql的服务器.想想广大博友应该都会遇到如何装mysql的问题,就此分享,给大家一个安装指南.供大家以后安装的时候,提高效率, ...

  5. POJ 1458 Common Subsequence (动态规划)

    题目传送门 POJ 1458 Description A subsequence of a given sequence is the given sequence with some element ...

  6. PS/2的相关知识

    PS/2接口 很多微机上采用PS/2口来连接鼠标和键盘.PS/2接口与传统的键盘接口除了在接口外型.引脚有不同外,在数据传送格式上是相同的.现在很多主板用PS/2接口插座连接键盘,传统接口的键盘可以通 ...

  7. Java小白集合源码的学习系列:ArrayList

    ArrayList源码学习 本文基于JDK1.8版本,对集合中的巨头ArrayList做一定的源码学习,将会参考大量资料,在文章后面都将会给出参考文章链接,本文用以巩固学习知识. ArrayList的 ...

  8. js 极简获取表单 元素 !

    let s =[]; $.each($('#formSearch input'),(m,n)=>{s.push(n)}); //示例获取表单所有 input 下滑线分割的 name 集合.set ...

  9. vue超简单加载字体方法,解决scss难加载字体的问题

    vue超简单加载字体方法,解决scss难加载字体的问题 scss在加载字体方面一直不太好用,需要繁杂的配置才能达到想要的效果,这里说一种非常简单的方法 在App.vue的style标签下引入字体文件后 ...

  10. 【一头扎进Spring】 01 | 从 HelloWorld 开始看Spring

    Spring 是一个开源框架. Spring 为简化企业级应用开发而生. 使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能. Spring 是一个 IOC(DI ...