哎,喜欢偷懒,这边直接抄袭下雷神的代码。雷神是个值得敬佩的程序员。

vs代码下载链接:
https://pan.baidu.com/s/1c2dIuYk 密码:ld4b

/* *最简单的基于FFmpeg的音频播放器*Simplest FFmpeg Audio Player**雷霄骅 Lei Xiaohua*leixiaohua1020@126.com*中国传媒大学/数字电视技术*Communication University of China / Digital TV Technology*http://blog.csdn.net/leixiaohua1020**本程序实现了音频的解码和播放。**/
#include <stdlib.h>
#include <string.h>
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
//SDL
#include "sdl/SDL.h"
#include "sdl/SDL_thread.h"
};
#include "decoder.h"//#define _WAVE_//全局变量---------------------static  Uint8  *audio_chunk; static  Uint32  audio_len; static  Uint8  *audio_pos;
//-----------------/*  The audio function callback takes the following parameters: stream: A pointer to the audio buffer to be filled len: The length (in bytes) of the audio buffer (这是固定的4096?)回调函数注意:mp3为什么播放不顺畅?len=4096;audio_len=4608;两个相差512!为了这512,还得再调用一次回调函数。。。m4a,aac就不存在此问题(都是4096)!*/ void  fill_audio(void *udata,Uint8 *stream,int len){ /*  Only  play  if  we  have  data  left  */ if(audio_len==0) return; /*  Mix  as  much  data  as  possible  */ len=(len>audio_len?audio_len:len); SDL_MixAudio(stream,audio_pos,len,SDL_MIX_MAXVOLUME);audio_pos += len; audio_len -= len; }
//-----------------int decode_audio(char* no_use)
{AVFormatContext    *pFormatCtx;int             i, audioStream;AVCodecContext   *pCodecCtx;AVCodec          *pCodec;char url[300]={0};strcpy(url,no_use);av_register_all();//支持网络流输入ffavformat_network_init();//初始化pFormatCtx = avformat_alloc_context();//打开if(avformat_open_input(&pFormatCtx,url,NULL,NULL)!=0){printf("Couldn't open input stream.\n");return -1;}// Retrieve stream informationif(av_find_stream_info(pFormatCtx)<0){printf("Couldn't find stream information.\n");return -1;}// Dump valid information onto standard errorav_dump_format(pFormatCtx, 0, url, false);// Find the first audio streamaudioStream=-1;for(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 streampCodecCtx=pFormatCtx->streams[audioStream]->codec;// Find the decoder for the audio streampCodec=avcodec_find_decoder(pCodecCtx->codec_id);if(pCodec==NULL){printf("Codec not found.\n");return -1;}// Open codecif(avcodec_open2(pCodecCtx, pCodec,NULL)<0){printf("Could not open codec.\n");return -1;}FILE *pFile;
#ifdef _WAVE_pFile=fopen("output.wav", "wb");fseek(pFile, 44, SEEK_SET); //预留文件头的位置
#elsepFile=fopen("output1.pcm", "wb");
#endifAVPacket *packet=(AVPacket *)malloc(sizeof(AVPacket));av_init_packet(packet);AVFrame *pFrame;pFrame=avcodec_alloc_frame();//输出音频数据大小,一定小于输出内存。int out_linesize;//输出内存大小int out_buffer_size=av_samples_get_buffer_size(&out_linesize, pCodecCtx->channels,pCodecCtx->frame_size,pCodecCtx->sample_fmt, 1);uint8_t *out_buffer=new uint8_t[out_buffer_size];//---------SDL--------------------------------------//初始化if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {  printf( "Could not initialize SDL - %s\n", SDL_GetError()); exit(1);}//结构体,包含PCM数据的相关信息SDL_AudioSpec wanted_spec;wanted_spec.freq = pCodecCtx->sample_rate; wanted_spec.format = AUDIO_S16SYS; wanted_spec.channels = pCodecCtx->channels; wanted_spec.silence = 0; //wanted_spec.samples = 1024; //播放AAC,M4a,缓冲区的大小wanted_spec.samples = 1152; //播放MP3,WMA时候用wanted_spec.callback = fill_audio; wanted_spec.userdata = pCodecCtx; if (SDL_OpenAudio(&wanted_spec, NULL)<0)//步骤(2)打开音频设备 { printf("can't open audio.\n"); return 0; } //-----------------------------------------------------printf("Bitrate:\t %3d\n", pFormatCtx->bit_rate);printf("Decoder Name:\t %s\n", pCodecCtx->codec->long_name);printf("Channels:\t %d\n", pCodecCtx->channels);printf("Sample per Second\t %d \n", pCodecCtx->sample_rate);uint32_t ret,len = 0;int got_picture;int index = 0;struct SwrContext *au_convert_ctx;au_convert_ctx = swr_alloc();au_convert_ctx=swr_alloc_set_opts(au_convert_ctx,AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 44100,pCodecCtx->channel_layout,pCodecCtx->sample_fmt , pCodecCtx->sample_rate,0, NULL);swr_init(au_convert_ctx);while(av_read_frame(pFormatCtx, packet)>=0){if(packet->stream_index==audioStream){ret = avcodec_decode_audio4( pCodecCtx, pFrame,&got_picture, packet);if ( ret < 0 ) {printf("Error in decoding audio frame.\n");exit(0);}if ( got_picture > 0 ){
#if 1swr_convert(au_convert_ctx,&out_buffer, out_linesize,(const uint8_t **)pFrame->data , pFrame->nb_samples);printf("index:%5d\t pts %5d\n", index,packet->pts);
#endif//直接写入
#if 1fwrite(out_buffer, 1, out_linesize, pFile);
#endifindex++;}
#if 1//---------------------------------------//printf("begin....\n"); //设置音频数据缓冲,PCM数据audio_chunk = (Uint8 *) out_buffer; //设置音频数据长度audio_len = out_linesize;audio_len = 4096;//播放mp3的时候改为audio_len = 4096//则会比较流畅,但是声音会变调!MP3一帧长度4608//使用一次回调函数(4096字节缓冲)播放不完,所以还要使用一次回调函数,导致播放缓慢。。。//设置初始播放位置audio_pos = audio_chunk;//回放音频数据 SDL_PauseAudio(0);//printf("don't close, audio playing...\n"); while(audio_len>0)//等待直到音频数据播放完毕! SDL_Delay(1); //---------------------------------------
#endif}av_free_packet(packet);}#ifdef _WAVE_fseek(pFile, 0, SEEK_SET);struct WAVE_HEADER wh;memcpy(wh.header.RiffID, "RIFF", 4);wh.header.RiffSize = 36 + len;memcpy(wh.header.RiffFormat, "WAVE", 4);memcpy(wh.format.FmtID, "fmt ", 4);wh.format.FmtSize = 16;wh.format.wavFormat.FormatTag = 1;wh.format.wavFormat.Channels = pCodecCtx->channels;wh.format.wavFormat.SamplesRate = pCodecCtx->sample_rate;wh.format.wavFormat.BitsPerSample = 16;calformat(wh.format.wavFormat); //Calculate AvgBytesRate and BlockAlignmemcpy(wh.data.DataID, "data", 4);wh.data.DataSize = len;fwrite(&wh, 1, sizeof(wh), pFile);
#endifSDL_CloseAudio();//关闭音频设备 // Close filefclose(pFile);// Close the codecavcodec_close(pCodecCtx);// Close the video fileav_close_input_file(pFormatCtx);return 0;
}

相关文章

Android 音视频学习基础–1.1 音视频基础知识
Android 音视频学习基础–1.2 需要认识的一些工具
Android 音视频学习基础–1.3 主流的开源项目
Android 音视频学习基础–1.4 ffmpeg pcm输出
Android 音视频学习基础–1.5 ffmpeg yuv输出
Android 音视频学习基础–1.6 ffmpeg 简单视频播放器
Android 音视频学习基础–1.7 Android最简单的音频播放器
Android 音视频学习基础–1.8 Android最简单的音频播放器
Android 音视频学习基础–1.9 Android最简单的视频播放器
Android 音视频学习基础–1.10 Android自制简单音视频播放器

欢迎大家批评指正

Android media ---- 1.7.ffmpeg 简单音频播放器相关推荐

  1. Android 中封装优雅的 MediaPlayer 音频播放器,支持多个播放器

    Android 中封装优雅的 MediaPlayer 音频播放器,支持多个播放器实例的示例: public class AudioPlayer implements MediaPlayer.OnPre ...

  2. FFmpeg+SDL2音频播放器

    基于雷神最简单的音频播放器修改. /** * 最简单的基于FFmpeg的音频播放器 2 * Simplest FFmpeg Audio Player 2 * * 雷霄骅 Lei Xiaohua * l ...

  3. 使用FFMPEG实现音频播放器

    使用FFMPEG实现音频播放器 导言 因为公司项目的原因,要学习如何使用FFMPEG进行音频播放,折腾一圈发现,使用FFMPEG还真不是一件简单的事,更为可惜的是,当年在这方面的杰出人物-雷霄骅的英逝 ...

  4. ffmpeg提取音频播放器总结

    ffmpeg提取音频播放器总结:  一:简介  从编写音频播放器代码到完成播放器编写,测试,整整5天的时间,这时间还不算之前对 ffmpeg熟悉的时间,可以说是历经千辛万苦,终于搞出来了,虽然最终效果 ...

  5. 与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成...

    原文:与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成 [索引页] [源码下载] 与众不同 wi ...

  6. ffmpeg+sdl音频播放器

    主机环境:Windows XP SDL版本:SDL2-2.0.3 ffmpeg版本:ffmpeg.2.4 ffmpeg库版本:ffmpeg-20140916-git-b76d613-win32-dev ...

  7. Android MediaPlay的使用以及实现音频播放器

    一.MediaPlay状态机详解(MediaPlay的生命周期) MediaPlayer状态机如下图所示 1.Idle(闲置)状态与End(结束)状态 MediaPlayer 对象声明周期 : 从 I ...

  8. WIN32下使用DirectSound接口的简单音频播放器(支持wav和mp3)

    刚好最近接触了一些DirectSound,就写了一个小程序练练手,可以用来添加播放基本的wav和mp3音频文件的播放器.界面只是简单的GDI,dxsdk只使用了DirectSound8相关的接口. D ...

  9. 简单音频播放器java代码_Java实现简易音乐播放器

    //此程序实现mid.wav格式音频文件的播放 //暂时只实现了单曲播放功能 //选项>其它功能会后继添加 //Version 1.0 // @author Zha_yongchun // Em ...

最新文章

  1. Blender多米诺骨牌动画学习教程 The Impossible Domino Run in Blender
  2. R语言可视化包ggplot2绘制平滑曲线、回归线实战:geom_smooth() 函数
  3. lduan Exchange 2013 公共文件夹(十)
  4. 浏览器版本不支持页面示例 supper.html
  5. Windows消息:WM_USER与WM_APP的区别
  6. 怎么关超声_肋骨骨折——超声的优势
  7. php 验证真实姓名,支付宝转账到支付宝 验证真实姓名
  8. c++如何获取文件时间_3分钟短文 | PHP 如何优雅地获取文件扩展名?别再explode了
  9. 2014 ACM/ICPC Asia Regional Beijing Site
  10. 本地Apache服务器访问时502 Server dropped connection 错误解决方法
  11. 晶振工作原理与元件选型
  12. 挑筋(挑治)疗法——针挑治疗痔疮
  13. 我为什么学习设计模式
  14. linux usb有线网卡驱动_Linux下安装USB网卡驱动 | 学步园
  15. LMV324MTX单通道,双通道和四通道通用低电压轨至轨输出运算放大器TI
  16. Linux开发板网络直连电脑的设置方法
  17. 怎样把已经做好的网页传到网上去?
  18. js实现复仇者联盟点名器
  19. ChatGPT 团队有几个人?
  20. 商宝项目服务器,可照搬实施的商超高可用方案:proxmox + haproxy 等

热门文章

  1. Linux的gedit没有权限,Linux中gedit时遇到得错误及解决方法
  2. chroot构建ubunt文件系统 在rk1808 imx6q上测试过
  3. vs中项目的外部依赖项是什么意思
  4. 双轮平衡车实现自平衡功能
  5. 电源设计之buck变换(一)
  6. virtualbox 共享文件夹
  7. Bootstrap响应式框架,组件化开发
  8. Tomcat8源码分析系列-spring boot集成tomcat
  9. 2017丹东计算机成绩,丹东市2017年国民经济和社会发展统计公报
  10. SC8205A耐压20V双N 沟道增强型 MOS 场效应管