The FFMPEG project is huge and there are not many books for reference. Therefore, many people who have just learned FFMPEG often feel unable to start.
Here, I will upload the source code of a very simple audio player that I implemented in my own project) for memo and help beginners learn FFMPEG.
Although simple, the player almost includes all the necessary APIs for playing an audio using FFMPEG and outputting decoded audio using SDL.
Streaming media and other types of audio input are also supported.
The program uses the new FFMPEG class library, which is slightly different from the API functions of the earlier FFMPEG class library.
Platform use VC2010
Note:
1. After decoding, the audio data of PCM can be played using Audition.
2. the m4a and aac files can be played directly. Adjust the SDL audio frame size to 4608 for mp3 files. The default value is 4096 .)
3. You can also play the audio in the video.
Paste the program code:
/// FFMPEG + SDL audio decoding program // leixiao Hua // media University of China/Digital TV technology // leixiaohua1020@126.com //// # include <stdlib. h> # include <string. h> extern "C" {# include "libavcodec/avcodec. h "# include" libavformat/avformat. h "// SDL # include" sdl/SDL. h "# include" sdl/SDL_thread.h "}; # include" decoder. h "// # include" wave. h "// # define _ WAVE _ // global variable --------------------- 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 (this is a fixed 4096 ?) Callback Function Note: Why does mp3 play poorly? Len = 4096; audio_len = 4608; the difference between the two is 512! For this 512, you have to call the callback function again... M4a and aac do not have this problem (both are 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;} // character int decode_audio (char * no_use) {AVFormatContext * pFormatCtx; int I, audioStream; AVCodecContext * pCodecCtx; AVCodec * pCodec; char url [300] = {0}; strcpy (url, no_use ); // Register all available file formats and codecs av_register_all (); // support for network stream input avformat_network_init (); // initialize pF OrmatCtx = avformat_alloc_context (); // The parameter 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 information if (av_find_stream_info (pFormatCtx) <0) {printf (" Couldn't find stream information. \ n "); return-1;} // Dump valid information onto standard error av_dump_format (pFormatCtx, 0, url, false ); // Find the first audio stream audioStream =-1; for (I = 0; I <pFormatCtx-> nb_streams; I ++) // the original codec_type = CODEC_TYPE_AUDIO if (pForm AtCtx-> 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 stream pCodecCtx = pFormatCtx-> streams [audioStream]-> codec; // Find the decoder for the audio stream pCodec = avcodec_find_decoder (pCodecCtx-> codec_id); if (pCodec = NULL) {printf ("Codec not fo Und. \ n "); return-1;} // Open codec if (avcodec_open (pCodecCtx, pCodec) <0) {printf (" cocould not open codec. \ n "); return-1 ;} /********* For output file *********************/FILE * pFile; # ifdef _ WAVE _ pFile = fopen ("output.wav", "wb"); fseek (pFile, 44, SEEK_SET ); // reserved File Header position # else pFile = fopen ("output. pcm "," wb "); # endif // Open the time stamp file * pTSFile; pTSFile = fopen (" audio_time_stamp.txt "," wb "); If (pTSFile = NULL) {printf ("cocould not open output file. \ n "); return-1;} fprintf (pTSFile," Time Base: % d/% d \ n ", pCodecCtx-> time_base.num, pCodecCtx-> time_base.den ); /*** Write audio into file ****** // change the struct to AVPacket * packet = (AVPacket *) malloc (sizeof (AVPacket )); av_init_packet (packet); // audio and video decoding are more unified! // Add AVFrame * pFrame; pFrame = avcodec_alloc_frame (); // --------- SDL encode // initialize if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER )) {printf ("cocould not initialize SDL-% s \ n", SDL_GetError (); exit (1) ;}// struct, containing information about PCM Data SDL_AudioSpec wanted_spec; wanted_spec.freq = pCodecCtx-> sample_rate; wanted_spec.format = AUDIO_S16SYS; wanted_spec.channels = pCodec Ctx-> channels; wanted_spec.silence = 0; wanted_spec.samples = 1024; // play AAC, M4a, buffer size // wanted_spec.samples = 1152; // play MP3, in WMA, use wanted_spec.callback = fill_audio; wanted_spec.userdata = pCodecCtx; if (SDL_OpenAudio (& wanted_spec, NULL) <0) // step 2) open the audio device {printf ("can't open audio. \ n "); return 0;} // ------------------------------------------------------- printf (" Bit Rate % 3d \ n ", pFormatCtx-> bit_rate); pr Intf ("decoder name % s \ n", pCodecCtx-> codec-> long_name); printf ("time_base % d \ n", pCodecCtx-> time_base ); printf ("channels % d \ n", pCodecCtx-> channels); printf ("sample per second % d \ n", pCodecCtx-> sample_rate ); // The new version is no longer required. // short decompressed_audio_buf [(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3)/2]; // int struct; uint32_t ret, len = 0; int got_picture; int index = 0; while (av_read_frame (pFormatCtx, Packet)> = 0) {if (packet-> stream_index = audioStream) {// decompressed_audio_buf_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3)/2; // original avcodec_decode_audio2 // ret = avcodec_decode_audio4 (pCodecCtx, decompressed_audio_buf, // & decompressed_audio_buf_size, packet. data, packet. size); // change to ret = avcodec_decode_audio4 (pCodecCtx, pFrame, & got_picture, packet); if (ret <0) // if error len =-1 {printf ("Error in decoding audio frame. \ n "); exit (0);} if (got_picture> 0) {# if 1 printf (" index % 3d \ n ", index ); printf ("pts % 5d \ n", packet-> pts); printf ("dts % 5d \ n", packet-> dts ); printf ("packet_size % 5d \ n", packet-> size); // printf ("test % s \ n", rtmp-> m_inChunkSize ); # endif // write directly // Note: The data is data0 and the length is linesize0.] # if 1 fwrite (pFrame-> data [0], 1, pFrame-> linesize [0], pFile); // fwrite (pFrame, 1, got_picture, p File); // len + = got_picture; index ++; // fprintf (pTSFile, "% 4d, % 5d, % 8d \ n", index, decompressed_audio_buf_size, packet. pts); # endif} # if 1 // ------------------------------------------- // printf ("begin .... \ n "); // set audio data buffer, PCM data audio_chunk = (Uint8 *) pFrame-> data [0]; // set the Audio Data Length audio_len = pFrame-> linesize [0]; // audio_len = 4096; // when playing mp3, it will be smoother if it is changed to audio_len = 4096, but the voice changes! MP3 frame length 4608 // use a callback function 4096 byte buffer) playback is not complete, so use a callback function, resulting in Slow playback... // Set the initial playback position audio_pos = audio_chunk; // play back the audio data SDL_PauseAudio (0); // printf ("don't close, audio playing... \ n "); while (audio_len> 0) // wait until the audio data is played! SDL_Delay (1); // --------------------------------------- # endif} // Free the packet that was allocated by av_read_frame // av_free_packet (packet) has been modified );} // printf ("The length of PCM data is % d bytes. \ n ", len); # 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.wav Format. formatTag = 1; wh.format.wav Format. channels = pCodecCtx-> channels; wh.format.wav Format. samplesRate = pCodecCtx-> sample_rate; wh.format.wav Format. bitsPerSample = 16; calformat(wh.format.wav Format); // Calculate AvgBytesRate and BlockAlign memcpy (wh. data. dataID, "data", 4); wh. data. dataSize = len; fwrite (& wh, 1, sizeof (wh), pFile); # endif SDL_CloseAudio (); // disable the audio device // Close file fclose (pFile ); // Close the codec avcodec_close (pCodecCtx); // Close the video file av_close_input_file (pFormatCtx); return 0 ;}
The program prints the information of each frame.
Run:
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/1954202B1-0.jpg "title =" 20130829171426343.jpg" alt = "2017703371.jpg"/>
Path to the complete project file:
Http://down.51cto.com/data/949383
This article is from the "leixiao00001020 audio and video technology" blog, please be sure to keep this source http://leixiaohua1020.blog.51cto.com/3974648/1298616