SDL 与 FFMPEG 音乐播放器开发(4)——使用FFMPEG库解码
来源:互联网 发布:mac 固态硬盘windows10 编辑:程序博客网 时间:2024/06/05 06:27
首先说一下压缩这件事,压缩其实就是以一种更省空间的方法存储文件,甚至有时会为了省下空间而放弃某些文件信息。音频、视频、图片这三大媒体类文件,为了传输与存储的方便,压缩就必不可少,发展至今,可以说已经有一套比较标准的媒体文件格式,其中蕴含了不少先人的智慧,每一样都包涵了他们很长一段时间的努力。
如果要想精通他们的解析和转换,并不是什么简单的事。不过有时这并不是我们希望研究的方向,于是我们可以引用FFMPEG解码库,使用它的方法,可以解码大多主流音频格式,而不必深究每个文件格式(因为别人已经帮你研究好了)。
首先这里以在VS上开发为例,你首先要引用FFMPEG的LIB文件,在项目属性->配置属性->连接器->输入的附加依赖项中,加入你要链接的LIB文件。并在项目的头文件当中include其头文件。
#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"
然后就是库中方法的使用
<span style="white-space:pre"></span>AVFormatContext*pFormatCtx;int <span style="white-space:pre"></span>i, audioStream;AVCodecContext*pCodecCtx;AVCodec*pCodec;char url[300] = { 0 };strcpy(url, (const char*)filePath);//Register all available file formats and codecs
<span style="white-space: pre;"></span>av_register_all();
//init ,getcontextpFormatCtx = avformat_alloc_context();//有参数avdic//if(avformat_open_input(&pFormatCtx,url,NULL,&avdic)!=0){if (avformat_open_input(&pFormatCtx, url, NULL, NULL) != 0){printf("Couldn't open file.\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++)//原为codec_type==CODEC_TYPE_AUDIOif (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_open(pCodecCtx, pCodec) < 0){printf("Could not open codec.\n");return -1;}
以上是检测能否打开音频(其实视频也行)文件,并检查它是不是有信息。最后转存文件,并找到、打开解码器。然后我们得存储转码好的文件。
<span style="white-space:pre"></span>FILE *pFile;char buf[256];sprintf(buf, "output/%soutput.pcm", filePath);
if (fopen(buf, "rb+"))//如果output文件已经存在,说明音频文件已经进行过解码,返回0。{return 0;}
pFile = fopen(buf, "wb");//如果不存在就以创建并写入的形式打开
/*** Write audio into file ******///把结构体改为指针AVPacket *packet = (AVPacket *)malloc(sizeof(AVPacket));av_init_packet(packet);AVFrame*pFrame;pFrame = avcodec_alloc_frame();
</pre><pre name="code" class="cpp"><pre name="code" class="cpp"><span style="white-space:pre"></span>uint32_t ret, len = 0;int got_picture;while (av_read_frame(pFormatCtx, packet) >= 0){if (packet->stream_index == audioStream){//将packet读取为Frameret = avcodec_decode_audio4(pCodecCtx, pFrame,&got_picture, packet);if (ret < 0) // if error len = -1{printf("Error in decoding audio frame.\n");exit(0);}//写入output.pcmif (got_picture > 0){fwrite(pFrame->data[0], 1, pFrame->linesize[0], pFile);}}// Free the packet that was allocated by av_read_frame//已改av_free_packet(packet);}// Close filefclose(pFile);// Close the codecavcodec_close(pCodecCtx);// Close the video fileav_close_input_file(pFormatCtx);return 0;
新建输出文件,并将解码所得写入文件之中,最后关闭设备。解码完成,我们成功将音频文件输出为PCM文件。PCM文件播放相关代码我在前面几篇都有提及,总之进行解码之后就可以对PCM文件进行播放,当然,如果想边解码边播放,可以新建多个线程进行解码并播放,SDL也将Thread封装为SDL_Thread,使用起来较为简单,下一节我会说关于SDL_Thread的使用。
以及大家可以联系我125650971@qq.com
0 0
- SDL 与 FFMPEG 音乐播放器开发(4)——使用FFMPEG库解码
- SDL 与 FFMPEG 音乐播放器开发(1)
- SDL 与 FFMPEG 音乐播放器开发(2)——混播多个音频
- SDL 与 FFMPEG 音乐播放器开发(3)——改变音量、跳转
- 使用FFMPEG解码和OpenAL播放音乐
- 使用 FFmpeg 开发播放器基础--使用 ffmpeg 解码视频文件
- 使用FFmpeg&SDL开发音视频播放器
- 使用FFmpeg&SDL开发音视频播放器
- 使用ffmpeg+SDL的简单播放器
- ffmpeg+SDL+windows 视频播放器的开发(三)
- SDL播放ffmpeg解码的AAC
- Android平台上使用SDL官方demo播放视频(使用ffmpeg最新版解码)
- Android平台上使用SDL官方demo播放视频(使用ffmpeg最新版解码)
- Android平台上使用SDL官方demo播放视频(使用ffmpeg最新版解码)
- 使用OpenAL和FFMPEG解码并播放音乐
- FFmpeg+SDL视频播放器—图形界面版学习笔记
- FFMPEG+SDL简单播放器
- FFMPEG+SDL简单播放器
- mysql数据库的数据备份和恢复
- 黑马程序员--C语言自学笔记---14static、extern、文件
- WebStorm开发Nodejs环境搭建,包括破解最新的WebStom11破解
- VirtualBox下安装虚拟机的分辨率问题
- 51单片机存储器小结
- SDL 与 FFMPEG 音乐播放器开发(4)——使用FFMPEG库解码
- Linux poll机制分析
- P09 (**) 把连续重复的列表元素打包为子列表
- Android上使用OpenCV处理图像
- NXZFW项目总结(二)
- 使用AndroidAnnotations框架优雅地实现ListView功能例子
- 极客必备之C++ 定时器
- 黑马程序员--C语言自学笔记---15C语言版通讯录
- apache常用模块介绍