- 浏览: 235846 次
- 性别:
- 来自: 南京
最新评论
-
baby8117628:
vc下mp3 IDv1和IDV2的读取 -
gezexu:
你好,我按照你的步骤一步步进行但是安装libvorbis的时候 ...
linux如何搭建强大的FFMPEG环境 -
ini_always:
帅哥,转载也把格式做好点,另外出处也要注明一下吧。。。
MP3文件格式解析
今天突发奇想,就在以前音频播放器(详细情况请看这里——http://blog.csdn.net/baymoon/archive/2006/11 /16/1388693.aspx)的基础上用ffmpeg写了个简单的多媒体播放器,这里把源代码贴出来,供大家参评;这里的多媒体播放,并没有用到什么很强大的音视频同步技术,而只是简单的使用了视频随着音频同步,想必你看了代码之后会有所悟的。。。不多说了,看代码。。。
/*************************************************************************** * main.cc * * Thu Nov 9 20:47:33 2006 * Copyright 2006 * Email lsosa.cs2c ****************************************************************************/ #include <avcodec.h> #include <avformat.h> #include <avutil.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <X11/Xlib.h> #include <sys/soundcard.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sched.h> #include <SDL/SDL.h> #define ALL_DEBUG #ifdef ALL_DEBUG #define AV_DEBUG #define AUDIO_DEBUG #endif //------------------------------------------------------------------------------ // manipulations for file int open_file (char *file_name, int mode) ...{ // open file file_name and return the file descriptor; int fd; if ((fd = open (file_name, mode)) < 0) ...{ fprintf (stderr, " Can't open %s! ", file_name); exit (-1); } return fd; } int set_audio (int fd, AVCodecContext * pCodecCtx) ...{ // set the properties of audio device with pCodecCtx; int i, err; /**//* 设置适当的参数,使得声音设备工作正常 */ /**//* 详细情况请参考Linux关于声卡编程的文档 */ i = 0; ioctl (fd, SNDCTL_DSP_RESET, &i); i = 0; ioctl (fd, SNDCTL_DSP_SYNC, &i); i = 1; ioctl (fd, SNDCTL_DSP_NONBLOCK, &i); // set sample rate; #ifdef AUDIO_DEBUG printf ("pCodecCtx->sample_rate:%d ", pCodecCtx->sample_rate); #endif i = pCodecCtx->sample_rate; if (ioctl (fd, SNDCTL_DSP_SPEED, &i) == -1) ...{ fprintf (stderr, "Set speed to %d failed:%s ", i, strerror (errno)); return (-1); } if (i != pCodecCtx->sample_rate) ...{ fprintf (stderr, "do not support speed %d,supported is %d ", pCodecCtx->sample_rate, i); return (-1); } // set channels; i = pCodecCtx->channels; #ifdef AUDIO_DEBUG printf ("pCodecCtx->channels:%d ", pCodecCtx->channels); #endif if ((ioctl (fd, SNDCTL_DSP_CHANNELS, &i)) == -1) ...{ fprintf (stderr, "Set Audio Channels %d failed:%s ", i, strerror (errno)); return (-1); } if (i != pCodecCtx->channels) ...{ fprintf (stderr, "do not support channel %d,supported %d ", pCodecCtx->channels, i); return (-1); } // set bit format; i = AFMT_S16_LE; if (ioctl (fd, SNDCTL_DSP_SETFMT, &i) == -1) ...{ fprintf (stderr, "Set fmt to bit %d failed:%s ", i, strerror (errno)); return (-1); } if (i != AFMT_S16_LE) ...{ fprintf (stderr, "do not support bit %d, supported %d ", AFMT_S16_LE, i); return (-1); } // set application buffer size; // i = (0x00032 << 16) + 0x000c; // 32 4kb buffer; // ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &i); i = 1; ioctl (fd, SNDCTL_DSP_PROFILE, &i); return 0; } void close_file (int fd) ...{ // close the file pointed by file descriptor fd; close (fd); } //------------------------------------------------------------------------------ // handle audio; void display_AVCodecContext(AVCodecContext *pCodecCtx)...{ // #define STDOUT stderr fprintf(STDOUT, "pCodecCtx->bit_rate:%d ", pCodecCtx->bit_rate); fprintf(STDOUT, "pCodecCtx->sample_rate:%d ", pCodecCtx->sample_rate); fprintf(STDOUT, "pCodecCtx->channels:%d ", pCodecCtx->channels); fprintf(STDOUT, "pCodecCtx->frame_size:%d ", pCodecCtx->frame_size); fprintf(STDOUT, "pCodecCtx->frame_number:%d ", pCodecCtx->frame_number); fprintf(STDOUT, "pCodecCtx->delay:%d ", pCodecCtx->delay); fprintf(STDOUT, "pCodecCtx->frame_bits:%d ", pCodecCtx->frame_bits); } // error if return -1; // success if return 0; // 这里要用到指向指针的指针,否则传不到值; int av_init (char *file_name, AVFormatContext ** pFormatCtx, AVCodecContext ** pAudioCodecCtx, int *p_audioStream, AVCodecContext ** pVideoCodecCtx, int *p_videoStream) ...{ // init the codec and format of input file file_name; int audioStream, i; int videoStream; AVCodec *pAudioCodec; AVCodec *pVideoCodec; // catch error assert(file_name != NULL); assert(*pFormatCtx != NULL); assert(*pAudioCodecCtx != NULL); // Register all formats and codecs av_register_all (); // open file if (av_open_input_file (pFormatCtx, file_name, NULL, 0, NULL) != 0)...{ // Couldn't open file fprintf (stderr, " Can't open %s! ", file_name); return -1; } // Retrieve stream information if (av_find_stream_info (*pFormatCtx) < 0)...{ // Couldn't find stream information return -1; } #ifdef AV_DEBUG // Dump information about file onto standard error dump_format (*pFormatCtx, 0, file_name, false); #endif // Find the first audio and video stream respectively audioStream = -1; videoStream = -1; for (i = 0; i < (*pFormatCtx)->nb_streams; i++)...{ if ((*pFormatCtx)->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) ...{ audioStream = i; }else if ((*pFormatCtx)->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)...{ videoStream = i; } } #ifdef AV_DEBUG // dump_stream_info(pFormatCtx); #endif // exclude error if (audioStream == -1)...{ // Didn't find a audio or video stream // return -1; printf("No Audio "); } if (videoStream == -1)...{ // Didn't find a audio or video stream // return -1; printf("No Video "); } // Get a pointer to the codec context for the audio stream *pAudioCodecCtx = (*pFormatCtx)->streams[audioStream]->codec; *pVideoCodecCtx = (*pFormatCtx)->streams[videoStream]->codec; // Find the decoder for the audio stream pAudioCodec = avcodec_find_decoder ((*pAudioCodecCtx)->codec_id); pVideoCodec = avcodec_find_decoder ((*pVideoCodecCtx)->codec_id); // if (pAudioCodec == NULL)...{ return -1; // Codec not found } if (pVideoCodec == NULL)...{ return -1; // Codec not found } // Open audio codec if (avcodec_open ((*pAudioCodecCtx), pAudioCodec) < 0)...{ return -1; // Could not open codec } // Open video codec if (avcodec_open ((*pVideoCodecCtx), pVideoCodec) < 0)...{ return -1; // Could not open codec } #ifdef AUDIO_DEBUG // printf ("pCodecCtx->sample_rate:%d, audioStream:%d ", (*pCodecCtx)->sample_rate, audioStream); // display_AVCodecContext(*pCodecCtx); #endif *p_audioStream = audioStream; *p_videoStream = videoStream; return 0; } void av_play (AVFormatContext * pFormatCtx, AVCodecContext * pAudioCodecCtx, int audioStream, AVCodecContext * pVideoCodecCtx, int videoStream) // AVCodecContext * pCodecCtx, int audioStream) ...{ // which was read from one frame; AVPacket packet; uint32_t len; uint8_t decompressed_audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; int decompressed_audio_buf_size; uint8_t * p_decompressed_audio_buf; int fd = -1; // audio file or test file? char filename[64] = "/dev/dsp"; int mode = O_WRONLY; // Video; AVFrame *pFrame; AVFrame *pFrameYUV; int frameFinished; /**////////// SDL initialization SDL_Surface *screen = SDL_SetVideoMode (pVideoCodecCtx->width, pVideoCodecCtx->height, 0, SDL_HWSURFACE); SDL_Overlay *overlay = SDL_CreateYUVOverlay (pVideoCodecCtx->width, pVideoCodecCtx->height, SDL_YV12_OVERLAY, screen); static SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = pVideoCodecCtx->width; rect.h = pVideoCodecCtx->height; /**/////////// // open audio file or written file // printf("fd:%d", fd); fd = open_file(filename, mode); // printf("fd:%d", fd); // set_audio(fd, pAudioCodecCtx); // printf("(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2=%d ", (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2); printf("AVCODEC_MAX_AUDIO_FRAME_SIZE=%d ", AVCODEC_MAX_AUDIO_FRAME_SIZE); // for a test // char test_file[256] = "my_pcm.pcm"; // fd = open_file(test_file, mode); #ifdef AV_DEBUG static int size = 0; #endif // // set the sched priority // 这是为了提高音频优先级;不晓得起作用没; int policy = SCHED_FIFO; sched_setscheduler(0, policy, NULL); // Allocate video frame pFrame = avcodec_alloc_frame (); // Allocate an AVFrame structure pFrameYUV = avcodec_alloc_frame (); if (pFrameYUV == NULL) return; // Set SDL events SDL_EventState (SDL_ACTIVEEVENT, SDL_IGNORE); SDL_EventState (SDL_MOUSEMOTION, SDL_IGNORE); // SDL_ShowCursor (SDL_ENABLE); int write_buf_size = 4196; int written_size; while ((av_read_frame (pFormatCtx, &packet) >= 0) && (SDL_PollEvent (NULL) == 0)) ...{ // Is this a packet from the audio stream? // 判断是否音频帧; if (packet.stream_index == audioStream) ...{ // Decode audio frame // 解码音频数据为pcm数据; len = avcodec_decode_audio (pAudioCodecCtx, (int16_t *)decompressed_audio_buf, &decompressed_audio_buf_size, // it is the decompressed frame in BYTES 解码后的数据大小,字节为单位; packet.data, packet.size ); // printf("len:%d, packet.size:%d ", len, packet.size); // printf("packet.pts:%d packet.dts:%d ", packet.pts, packet.dts); if ( len < 0 )...{ // if error len = -1 printf("+----- error in decoding audio frame "); // exit(0); } // audio_buf_info info; p_decompressed_audio_buf = decompressed_audio_buf; while ( decompressed_audio_buf_size > 0 )...{ // 解码后数据不为零,则播放之,为零,则; written_size = write(fd, p_decompressed_audio_buf, decompressed_audio_buf_size); if ( written_size == -1 )...{ // printf("error:decompressed_audio_buf_size:%d, decompressed_audio_buf_size:%d, %s ", decompressed_audio_buf_size, decompressed_audio_buf_size,strerror(errno)); // usleep(100); continue; } // printf("decompressed_audio_buf_size:%d, written_size:%d ", decompressed_audio_buf_size, written_size); decompressed_audio_buf_size -= written_size; p_decompressed_audio_buf += written_size; }// end while } else if (packet.stream_index == videoStream) ...{ // Decode video frame avcodec_decode_video (pVideoCodecCtx, pFrame, &frameFinished, packet.data, packet.size); // Did we get a video frame? if (frameFinished) ...{ // Convert the image from its native format to YUV, and display SDL_LockYUVOverlay (overlay); pFrameYUV->data[0] = overlay->pixels[0]; pFrameYUV->data[1] = overlay->pixels[2]; pFrameYUV->data[2] = overlay->pixels[1]; pFrameYUV->linesize[0] = overlay->pitches[0]; pFrameYUV->linesize[1] = overlay->pitches[2]; pFrameYUV->linesize[2] = overlay->pitches[1]; img_convert ((AVPicture *) pFrameYUV, PIX_FMT_YUV420P, (AVPicture *) pFrame, pVideoCodecCtx->pix_fmt, pVideoCodecCtx->width, pVideoCodecCtx->height); SDL_UnlockYUVOverlay (overlay); SDL_DisplayYUVOverlay (overlay, &rect); /**//// // SDL_Delay (33); } }// end if // Free the packet that was allocated by av_read_frame av_free_packet (&packet); }// end while of reading one frame; // Free the RGB image av_free (pFrameYUV); // Free the YUV frame av_free (pFrame); // for test lsosa // printf("size = %d ", size / 1024 / 1024 ); SDL_FreeYUVOverlay (overlay); close_file(fd); } void av_close (AVFormatContext * pFormatCtx, AVCodecContext * pAudioCodecCtx, AVCodecContext * pVideoCodecCtx) ...{ // close the file and codec // Close the codec avcodec_close (pAudioCodecCtx); // Close the codec avcodec_close (pVideoCodecCtx); // Close the video file av_close_input_file (pFormatCtx); } //------------------------------------------------------------------------------ int main (int argc, char **argv)...{ // AVFormatContext *pFormatCtx; int audioStream = -1; int videoStream = -1; AVCodecContext *pAudioCodecCtx; AVCodecContext *pVideoCodecCtx; // exclude the error about args; if ( argc != 2 )...{ printf("please give a file name "); exit(0); } // 注意:这里要用到指向指针的指针,是因为这个初始化函数需要对指针的地址进行改动, // 所以,只有这么做,才能达到目的; if ( av_init(argv[1], &pFormatCtx, &pAudioCodecCtx, &audioStream, &pVideoCodecCtx, &videoStream) < 0 )...{ // fprintf(stderr, "error when av_init "); } // play the audio file av_play(pFormatCtx, pAudioCodecCtx, audioStream, pVideoCodecCtx, videoStream); // close all the opend files av_close(pFormatCtx, pAudioCodecCtx, pVideoCodecCtx); }
发表评论
-
vc下mp3 IDv1和IDV2的读取
2010-01-25 10:52 2424/*这是修改后的代码,VC下读ID3v2 & ID3v ... -
ffmpeg提取音频播放器总结
2010-01-21 16:31 6037ffmpeg提取音频播放器总 ... -
ffmpeg开发指南
2010-01-20 17:26 3397ffmpeg 中的Libavformat 和 li ... -
linux下安装ffmpeg过程
2010-01-18 15:48 1905最近互联网视频共享的 ... -
【PNG overview】PNG专题!
2010-01-18 13:39 3398【PNG overview】PNG专题! 作者 鼯鼠 ... -
Big Endian 和 Little Endian
2010-01-18 13:29 1566Peter Lee 2008-04-20 一、字节序 ... -
MediaInfo开源工程
2010-01-18 13:22 2397一、简介 MediaInfo 用来 ... -
MP3文件格式解析
2010-01-18 10:58 3575MP3文件格式解析 Peter Lee 2008-06-0 ... -
LAME-mp3
2010-01-18 10:40 2051LAME - 压缩 MP3 的最佳利 ... -
FLV文件格式分析(图示讲解的清楚)
2010-01-14 15:56 5120FLV是一个二进制文件, ... -
我对FLV 文件格式的理解
2010-01-14 15:52 3386我对FLV 文件格式的理解 ----------------- ... -
常用的音频文件介绍
2010-01-13 10:56 1416MP3全称是动态影像专家压缩标准音频层面3(Moving Pi ... -
RTSP客户端的JAVA实现
2010-01-12 16:12 8369参考资料 1. 《RTSP简单命 ... -
国外嵌入式、音视频处理等重要网站
2010-01-08 10:07 2050嵌入式方面: 1.关于嵌入式开发的站点,提供非常多关于嵌入 ... -
RTSP点播——消息流程实例
2010-01-08 09:44 5128RTSP点播消息流程实例(客户端:VLC, RTSP服务器:L ... -
live555代码解读之三:SETUP和PLAY请求消息处理过程
2010-01-08 09:43 3480SETUP请求消息处理过程 ... -
live555代码解读之二:DESCRIBE请求消息处理过程
2010-01-08 09:42 3820ve555代码解读之二:DESCRIBE请求消息处理过程 ... -
live555代码解读之一:RTSP连接的建立过程
2010-01-08 09:42 4452TSPServer类用于构建一个RTSP服务器,该类同时在其内 ... -
live555源代码概述
2010-01-08 09:41 3898述 liveMedia项目(http://www ... -
浅议SDP(会话描述协议)
2010-01-04 15:25 3587因为最近常常使用到SDP(会话描述协议Session Desc ...
相关推荐
源代码中应包含音频解码模块,可能使用开源库如libcdio或ffmpeg。这部分代码会处理采样率转换、位深度转换和声道处理等任务,确保音频数据能在各种系统上正确播放。 3. **音频流处理**:解码后的音频数据需送入音频...
在本资源中,我们有一个使用易语言(e语言)编写的"mp3小型播放器"的源代码。这个播放器专为播放mp3格式的音频文件设计,对于学习易语言编程和音频处理的初学者来说,是一个非常有价值的实践项目。 首先,易语言的...
“video”可能是项目中的源代码或者资源文件夹,包含视频播放器所需的具体视频文件或相关配置。在这里,开发人员可能编写了处理视频流、控制播放、渲染视频帧以及响应用户交互的代码。QT的QVideoWidget或...
在实际开发中,开发者可以使用这些库文件与应用程序链接,通过FFmpeg的API实现多媒体处理功能。例如,你可以加载一个视频文件,提取其音频流,对音频进行编码或解码,甚至进行实时的视频编码和流传输。 总结起来,...
不过,具体的功能和限制需要查看该版本的文档或源代码来了解。 总的来说,FFmpeg是一个功能强大的多媒体处理工具,其预编译版本的提供使得用户无需自己编译,节省了时间和资源,能够快速地在各种平台上应用FFmpeg...
在这个项目中,我们看到的是一个基于ASP.NET的简单媒体播放器的设计与实现,它提供了源代码和相关论文,非常适合用作毕业设计、课程设计或者自我提升的学习材料。 在ASP.NET中,这个媒体播放器可能使用C#作为后端...
标题“Playflv.rar”暗示这是一个包含C#源代码的压缩包,可能是一个小型项目或库,用于处理FLV视频播放功能。以下是对这个主题的详细讲解: 首先,FLV是一种流行的网络视频格式,广泛用于在线流媒体服务。由于它在...
ffplay 是 FFmpeg 项目中的一个小型命令行播放器,它用C语言编写,展示了如何直接使用FFmpeg库来实现基本的多媒体播放功能。在这个精简版中,开发者可能已经去除了不必要的功能,使其更易于理解和学习。主要包含以下...
"c语言做的播放器源码"很可能是实际的源代码文件,可能包含了播放器的主程序和其他相关的函数库、头文件等。 C语言制作的播放器通常会涉及到以下几个关键知识点: 1. **文件I/O**:播放器需要读取音频或视频文件,...
在本文中,我们将深入探讨自制的小型音乐播放器的设计与实现,这是一款功能简单、代码精炼的工具,适合初学者学习编程和多媒体处理。 首先,我们来了解媒体播放器的基本功能。一个基本的音乐播放器通常包含以下组件...
MinGW是一个小型的GNU开发工具集,它包含了GCC(GNU Compiler Collection)和其他一些必要的库,如glibc和POSIX接口,允许开发者在Windows系统下使用GNU工具链来编译源代码。GCC支持多种编程语言,包括C、C++、...
总结,"zplayer" 是一个使用 C# 开发的轻量级媒体播放器,其设计可能结合了 C# 的面向对象特性、.NET Framework 的资源,以及媒体处理的底层技术,如 DirectX 或 FFmpeg,为用户提供一个简洁易用的媒体播放体验。
项目中的 "FFMPEG_VideoOcx" 可能是开发过程中生成的 ActiveX 控件的编译结果或者源代码文件夹,包含了实现以上功能的具体代码。开发者可能使用了 FFmpeg 的 API 来集成解码和播放功能,同时利用 MFC 的类库来处理...
"All-code-linux-libraries.rar"这个压缩包似乎包含了Linux系统中广泛使用的各种库的源代码,这对于学习、理解和调试Linux程序是非常有价值的。 首先,我们要了解库的分类。在Linux中,主要有两种类型的库:静态库...
在嵌入式Linux系统中,将MPlayer移植到设备上是一项关键任务,因为这使得用户能够在小型、低功耗的硬件上享受多媒体播放功能。MPlayer是一款强大的开源媒体播放器,支持多种视频和音频格式,它可以在各种操作系统上...
libavcodec是FFmpeg项目的一部分,是一个强大的多媒体处理库,主要用于视频和音频的编码和解码。通常,LCD驱动用于显示视频和图像,而libavcodec则负责处理这些媒体数据的编码和解码工作。将L2F50 LCD驱动与...
GCC通过将源代码转换为机器码,使得程序能够在Windows平台上运行。 2. **MSYS**:这是一个小型的Unix-like环境,它为MinGW提供了命令行工具,如bash shell、make工具等,使用户可以使用类似Unix的命令行语法进行...
开发者需要编写单元测试和集成测试,使用GDB等工具进行调试,确保代码的质量和性能。 通过深入理解这些知识点,开发者可以有效地修改、扩展和优化数码相框源码,以满足特定的需求和场景。无论是对个人项目还是商业...
1. **源码解析**:深入解析特定项目的源代码,包括代码结构、设计模式、编程技巧等,帮助读者理解并学习如何编写高效、可维护的代码。 2. **代码优化**:讲解如何通过改进代码结构、选择合适的算法、减少冗余操作等...