基于雷神最简单的音频播放器修改。

/**
* 最简单的基于FFmpeg的音频播放器 2
* Simplest FFmpeg Audio Player 2
*
* 雷霄骅 Lei Xiaohua
* leixiaohua1020@126.com
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.csdn.net/leixiaohua1020
*
* 本程序实现了音频的解码和播放。
* 是最简单的FFmpeg音频解码方面的教程。
* 通过学习本例子可以了解FFmpeg的解码流程。
*
* 该版本使用SDL 2.0替换了第一个版本中的SDL 1.0。
* 注意:SDL 2.0中音频解码的API并无变化。唯一变化的地方在于
* 其回调函数的中的Audio Buffer并没有完全初始化,需要手动初始化。
* 本例子中即SDL_memset(stream, 0, len);
*
* This software decode and play audio streams.
* Suitable for beginner of FFmpeg.
*
* This version use SDL 2.0 instead of SDL 1.2 in version 1
* Note:The good news for audio is that, with one exception,
* it's entirely backwards compatible with 1.2.
* That one really important exception: The audio callback
* does NOT start with a fully initialized buffer anymore.
* You must fully write to the buffer in all cases. In this
* example it is SDL_memset(stream, 0, len);
*
* Version 2.0
*/
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define __STDC_CONSTANT_MACROSextern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
#include "SDL2/SDL.h"
#include "libavutil/audio_fifo.h"
};Uint32  audio_len;
Uint8  *audio_pos;
AVAudioFifo* audiofifo = NULL;void  fill_audio(void *udata, Uint8 *stream, int len){//SDL 2.0SDL_memset(stream, 0, len);if (audio_len == 0)return;len = (len>audio_len ? audio_len : len);    /*  Mix  as  much  data  as  possible  */SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);audio_pos += len;audio_len -= len;
}int main(int argc, char* argv[])
{AVFormatContext *pFormatCtx;int             i, audioStream;AVCodecContext  *pCodecCtx;AVCodec         *pCodec;AVPacket        *packet;AVFrame         *pFrame;SDL_AudioSpec wanted_spec;int ret;uint32_t len = 0;int got_picture;int index = 0;int64_t in_channel_layout;struct SwrContext *au_convert_ctx;FILE *pFile = NULL;char url[] = "rtmp://live.hkstv.hk.lxdns.com/live/hks";av_register_all();avformat_network_init();pFormatCtx = avformat_alloc_context();if (avformat_open_input(&pFormatCtx, url, 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, 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;}packet = (AVPacket *)av_malloc(sizeof(AVPacket));av_init_packet(packet);int out_framesize = 1024;//Out Audio Paramuint64_t out_channel_layout = AV_CH_LAYOUT_STEREO;//nb_samples: AAC-1024 MP3-1152int out_nb_samples = out_framesize;AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;int out_sample_rate = 44100;// pCodecCtx->sample_rate;int out_channels = av_get_channel_layout_nb_channels(out_channel_layout);//Out Buffer Sizeint out_buffer_size = av_samples_get_buffer_size(NULL, out_channels, out_nb_samples, out_sample_fmt, 1);uint8_t ** audio_data_buffer = NULL;audiofifo = av_audio_fifo_alloc(out_sample_fmt, out_channels, 1);pFrame = av_frame_alloc();if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {printf("Could not initialize SDL - %s\n", SDL_GetError());return -1;}//SDL_AudioSpecwanted_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;}//FIX:Some Codec's Context Information is missingin_channel_layout = av_get_default_channel_layout(pCodecCtx->channels);//Swrau_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);//PlaySDL_PauseAudio(0);AVFrame* audio_frame = av_frame_alloc();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");return -1;}if (got_picture > 0){av_samples_alloc_array_and_samples(&audio_data_buffer, NULL, out_channels, pFrame->nb_samples, out_sample_fmt, 1);int convert_size = swr_convert(au_convert_ctx, audio_data_buffer, pFrame->nb_samples,(const uint8_t**)pFrame->data, pFrame->nb_samples);ret = av_audio_fifo_realloc(audiofifo, av_audio_fifo_size(audiofifo) + convert_size);if (ret < 0){printf("av_audio_fifo_realloc error\n");return -1;}if (av_audio_fifo_write(audiofifo, (void **)audio_data_buffer, convert_size) < convert_size){printf("av_audio_fifo_write error\n");return -1;}while (av_audio_fifo_size(audiofifo) >= out_framesize){int frame_size = FFMIN(av_audio_fifo_size(audiofifo), out_framesize);audio_frame->nb_samples = frame_size;audio_frame->channel_layout =out_channel_layout;audio_frame->format = out_sample_fmt;audio_frame->sample_rate = out_sample_rate;av_frame_get_buffer(audio_frame, 0);if (av_audio_fifo_read(audiofifo, (void **)audio_frame->data, frame_size) < frame_size){printf("av_audio_fifo_read error\n");return -1;}if (wanted_spec.samples != frame_size){SDL_CloseAudio();out_nb_samples = frame_size;out_buffer_size = av_samples_get_buffer_size(NULL, out_channels, out_nb_samples, out_sample_fmt, 1);wanted_spec.samples = out_nb_samples;SDL_OpenAudio(&wanted_spec, NULL);}while (audio_len>0)//Wait until finishSDL_Delay(1);audio_len = out_buffer_size;audio_pos = *audio_frame->data;}}}av_free_packet(packet);}swr_free(&au_convert_ctx);SDL_CloseAudio();//Close SDLSDL_Quit();if (audiofifo)av_audio_fifo_free(audiofifo);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);return 0;
}

FFmpeg+SDL2音频播放器相关推荐

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

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

  2. Android media ---- 1.7.ffmpeg 简单音频播放器

    哎,喜欢偷懒,这边直接抄袭下雷神的代码.雷神是个值得敬佩的程序员. vs代码下载链接: https://pan.baidu.com/s/1c2dIuYk 密码:ld4b /* *最简单的基于FFmpe ...

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

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

  4. ffmpeg+sdl音频播放器

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

  5. FFmpeg+SDL2开发播放器遇到问题

    avformat_open_input异常,fmt_ctx返回空指针? 由于老版本ffmpeg缺少av_register_all();或filePath访问不了 AVFormatContext *fm ...

  6. FFMPEG+SDL2 实现播放器功能

    ffmpeg视频H264压缩,rtsp推流课程教学视频: https://edu.csdn.net/course/detail/27795 课件中里面提供源码可以直接下载运行! ----------- ...

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

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

  8. 最简单的基于FFMPEG+SDL的音频播放器

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

  9. 最简单的基于FFMPEG SDL的音频播放器

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! ==== ...

最新文章

  1. python基础学习22----协程
  2. mysql创建读写账号_mysql创建读写账号及服务相关优化配置
  3. 每日程序C语言39-不带头结点的头插法创建链表
  4. Java 数字数组随机数工具类 NumberUtils、ArrayUtils、RandomUtils用法
  5. 昨日搬至办公室的书籍
  6. 迪杰特斯拉算法的实现
  7. 学习笔记--asp.net主题和外观(转自msdn,仅为自己学习存储和有意读者使用)
  8. Office2021 安装MathType
  9. 一款访问远程Linux服务器的web SSH终端
  10. x86 x64 IA64的关系和区别
  11. java画哆啦A梦_java绘制哆啦A梦 超可爱
  12. 键盘按键发出声音,打不了字,提示启用筛选键
  13. 字节架构师:来说说 Kafka 的消费者客户端详解,你都搞懂了吗?
  14. 需要查询前一次该厂商,料号的单价, 这个sql语句很难写,你碰到过没有
  15. SQL零基础入门学习(九)
  16. 【uni-app高级实战】手把手带你学习一个纯实战复杂项目的开发1/100
  17. 2018-GaAN: Gated Attention Networks for Learning on Large and Spatiotemporal Graphs
  18. 河南信息统计学院微信公众平台API汇总
  19. 计算机开机黑屏90,终于晓得笔记本电脑开机黑屏检修步骤
  20. “以换代充”两轮电动车换电柜引关注

热门文章

  1. 学会继承、多态、封装(1)——Java实现宠物店(领养宠物)
  2. FPGA远程更新-在线升级
  3. 实验2 SQL 查询语句
  4. springmvc参数注入源码剖析源码扩展
  5. astropy常用命令 python天文绘图
  6. Closing non transactional SqlSession导致spring事务不生效
  7. IntelliJ IDEA的下载安装
  8. [保研经验]自动化所
  9. 网络工程师成长日记320-西安奥林巴斯项目回忆录
  10. jQuery_01入门