// avcodec_sample_audio.cpp // A small sample program that shows how to use libavformat and libavcodec to // read audio from a file. // // Use // // g++ -o avcodec_sample_audio avcodec_sample_audio.cpp -lavformat -lavcodec -lz // // to build (assuming libavformat and libavcodec are correctly installed on // your system). // // Run using // // avcodec_sample_audio myvideofile.mpg // // to extract audio track from the file and write samples to a file, // further play that file with smth. #include #include #include #include bool GetNextFrame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int audioStream, uint8_t* out_buf, int* out_size) { static AVPacket packet; static int bytesRemaining=0; static uint8_t *rawData; static bool fFirstTime=true; int bytesDecoded; // First time we're called, set packet.data to NULL to indicate it // doesn't have to be freed if(fFirstTime) { fFirstTime=false; packet.data=NULL; } // Decode packets until we have decoded a complete frame while(true) { // Work on the current packet until we have decoded all of it while(bytesRemaining > 0) { // Decode the next chunk of data bytesDecoded=avcodec_decode_audio(pCodecCtx, (short*)out_buf, out_size, rawData, bytesRemaining); // Was there an error? if(bytesDecoded < 0) { fprintf(stderr, "Error while decoding frame\n"); return false; } bytesRemaining-=bytesDecoded; rawData+=bytesDecoded; // Did we finish the current frame? Then we can return if(*out_size>0) return true; } // Read the next packet, skipping all packets that aren't for this // stream do { // Free old packet if(packet.data!=NULL) av_free_packet(&packet); // Read new packet if(av_read_packet(pFormatCtx, &packet)<0) goto loop_exit; } while(packet.stream_index!=audioStream); bytesRemaining=packet.size; rawData=packet.data; } loop_exit: // Decode the rest of the last frame bytesDecoded=avcodec_decode_audio(pCodecCtx, (short*)out_buf, out_size, rawData, bytesRemaining); // Free last packet if(packet.data!=NULL) av_free_packet(&packet); return *out_size>0; } void SaveFrame(const uint8_t* buffer, int size, int iFrame) { FILE *pFile; char szFilename[100]; int y; // Open file sprintf(szFilename, "/home/stalker/Desktop/frames/frame%d.jpg", iFrame); pFile=fopen(szFilename, "wb"); if(pFile==NULL) return; // Write pixel data fwrite(buffer, 1, size, pFile); // Close file fclose(pFile); } int main(int argc, char *argv[]) { AVFormatContext *pFormatCtx; int i, audioStream; AVCodecContext *pCodecCtx; AVCodec *pCodec; int out_size; uint8_t *out_buf; // Register all formats and codecs av_register_all(); // Open video file if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0) return -1; // Couldn't open file // Retrieve stream information if(av_find_stream_info(pFormatCtx)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error dump_format(pFormatCtx, 0, argv[1], false); // Find the first audio stream audioStream=-1; for(i=0; inb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) { audioStream=i; break; } if(audioStream==-1) return -1; // Didn't find a audio stream // 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) return -1; // Codec not found // Open codec if(avcodec_open(pCodecCtx, pCodec)<0) return -1; // Could not open codec // Read audio samples and save them to disk out_buf = (uint8_t*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); while(GetNextFrame(pFormatCtx, pCodecCtx, audioStream, out_buf, &out_size)) { } free (out_buf); // Close the codec avcodec_close(pCodecCtx); // Close the video file av_close_input_file(pFormatCtx); return 0; }