免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
[FFMPEG-2]最想實(shí)現(xiàn)的第一點(diǎn)一個功能-從mp3中提取pcm數(shù)據(jù),重采樣和加wav頭
關(guān)閉
關(guān)閉

2015-01-20 08:11:39CSDN-u0106734

忙了幾天終于實(shí)現(xiàn)了轉(zhuǎn)碼,但是只是轉(zhuǎn)碼還是不夠的,還想要進(jìn)行重采樣。同樣的還是要求助于萬能的google,找了一大堆代碼,再加上參考了官方的demo。折騰了兩天,終于搞定了。

大部分的代碼和轉(zhuǎn)碼的代碼差不多,多的地方是需要設(shè)置輸出的格式比如采樣率,聲道,bit_rate等信息。從輸入文件解碼得到數(shù)據(jù)之后要進(jìn)行重采樣的操作,然后保存重采樣之后的數(shù)據(jù)。一開始找了一個講解很詳細(xì)的博客,但是他是用的老版本,很多函數(shù)都廢棄了。后來又想起來官方的example,然后結(jié)合了一下終于搞出來了!因?yàn)槭腔趧e人的代碼修改的,所以代碼風(fēng)格和上一篇不怎么也一樣。

#include    <stdlib.h>#include    <stdio.h>#include    <string.h>#include    <math.h>#include     <stdint.h>#include     <libavutil/avutil.h>#include    <libavutil/attributes.h>#include    <libavutil/opt.h>#include    <libavutil/mathematics.h>#include    <libavutil/imgutils.h>#include    <libavutil/samplefmt.h>#include    <libavutil/timestamp.h>#include    <libavformat/avformat.h>#include    <libavcodec/avcodec.h>#include    <libswscale/swscale.h>#include    <libavutil/mathematics.h>#include    <libswresample/swresample.h>#include    <libavutil/channel_layout.h>#include    <libavutil/common.h>#include    <libavformat/avio.h>#include    <libavutil/file.h>#include    <libswresample/swresample.h>FILE *fin, *fout;#define SWR_CH_MAX 1024int ffmpeg_audio_decode(const char * inFile, const char * outFile,		int channel_num, int bit_rate, int sample_rate) {	av_register_all();	AVFrame* frame = av_frame_alloc();	if (!frame) {		fprintf(stderr, "Error allocating the frame");		return 1;	}	AVFormatContext* formatContext = NULL;	if (avformat_open_input(&formatContext, inFile, NULL, NULL) != 0) {		av_free(frame);		fprintf(stderr, "Error opening the file");		return 1;	}	if (avformat_find_stream_info(formatContext, NULL) < 0) {		av_free(frame);		avformat_close_input(&formatContext);		fprintf(stderr, "Error finding the stream info");		return 1;	}	AVStream* audioStream = NULL;	unsigned int i;	// Find the audio stream (some container files can have multiple streams in them)	for (i = 0; i < formatContext->nb_streams; ++i) {		if (formatContext->streams[i]->codec->codec_type				== AVMEDIA_TYPE_AUDIO) {			audioStream = formatContext->streams[i];			break;		}	}	if (audioStream == NULL) {		av_free(frame);		avformat_close_input(&formatContext);		fprintf(stderr, "Could not find any audio stream in the file");		return 1;	}	AVCodecContext* codecContext = audioStream->codec;	codecContext->codec = avcodec_find_decoder(codecContext->codec_id);	if (codecContext->codec == NULL) {		av_free(frame);		avformat_close_input(&formatContext);		fprintf(stderr, "Couldn't find a proper decoder");		return 1;	} else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0) {		av_free(frame);		avformat_close_input(&formatContext);		fprintf(stderr, "Couldn't open the context with the decoder");		return 1;	}	/*START*************************START***********************START*/	/*設(shè)置輸出格式,為了未來jni調(diào)用的簡單,所以都傳的int,反正是自己用的,直觀一些*/	int64_t outChannelLayout;	if (channel_num == 1) {		outChannelLayout = AV_CH_LAYOUT_MONO;	} else {		outChannelLayout = AV_CH_LAYOUT_STEREO;	}	enum AVSampleFormat outSampleFormat;	if (bit_rate == 32) {		outSampleFormat = AV_SAMPLE_FMT_S32;	} else {		outSampleFormat = AV_SAMPLE_FMT_S16;	}	int outSampleRate = sample_rate; //44100;	SwrContext* swrContext = swr_alloc_set_opts(NULL, outChannelLayout,			outSampleFormat, outSampleRate,			av_get_default_channel_layout(codecContext->channels),			codecContext->sample_fmt, codecContext->sample_rate, 0, NULL);	if (swrContext == NULL) {		av_free(frame);		avcodec_close(codecContext);		avformat_close_input(&formatContext);		fprintf(stderr, "Couldn't create the SwrContext");		return 1;	}	if (swr_init(swrContext) != 0) {		av_free(frame);		avcodec_close(codecContext);		avformat_close_input(&formatContext);		swr_free(&swrContext);		fprintf(stderr, "Couldn't initialize the SwrContext");		return 1;	}	/*END**************************END*************************END*/	fout = fopen(outFile, "wb+");	AVPacket packet;	av_init_packet(&packet);// Read the packets in a loop	while (av_read_frame(formatContext, &packet) == 0) {		if (packet.stream_index == audioStream->index) {			AVPacket decodingPacket = packet;			while (decodingPacket.size > 0) {				// Try to decode the packet into a frame				int frameFinished = 0;				int result = avcodec_decode_audio4(codecContext, frame,						&frameFinished, &decodingPacket);				if (result < 0 || frameFinished == 0) {					break;				}				unsigned char buffer[100000];				unsigned char* pointers[SWR_CH_MAX];				pointers[0] = &buffer[0];				//這個地方還不是很清楚,看官方的example感覺好復(fù)雜。尤其是參數(shù)。				int numSamplesOut = swr_convert(swrContext, pointers,						outSampleRate,						(const unsigned char**) frame->extended_data,						frame->nb_samples);				fwrite((short *) buffer, sizeof(short),						(size_t) numSamplesOut * channel_num, fout);				decodingPacket.size -= result;				decodingPacket.data += result;			}		}		av_free_packet(&packet);	}	// Clean up!	av_free(frame);	avcodec_close(codecContext);	avformat_close_input(&formatContext);	fclose(fout);	return 0;}int main() {	char *inFile = "ping.mp3";	char *outFile = "ping.wav";	fprintf(stderr, "res:%d/n",			ffmpeg_audio_decode(inFile, outFile, 2, 16, 44100));	return 0;}

代碼未經(jīng)充分測試,總感覺又一些問題。忘了加頭了,現(xiàn)在把頭加上。感覺自己寫的程序越來越不靠譜了!但是基本呢功能還是能實(shí)現(xiàn)的。

#include    <stdlib.h>#include    <stdio.h>#include    <string.h>#include    <math.h>#include 	<stdint.h>#include  	<libavutil/avutil.h>#include  	<libavutil/attributes.h>#include    <libavutil/opt.h>#include    <libavutil/mathematics.h>#include    <libavutil/imgutils.h>#include    <libavutil/samplefmt.h>#include    <libavutil/timestamp.h>#include    <libavformat/avformat.h>#include    <libavcodec/avcodec.h>#include    <libswscale/swscale.h>#include    <libavutil/mathematics.h>#include    <libswresample/swresample.h>#include    <libavutil/channel_layout.h>#include    <libavutil/common.h>#include    <libavformat/avio.h>#include    <libavutil/file.h>#include    <libswresample/swresample.h>FILE *fin, *fout;#define SWR_CH_MAX 1024typedef struct {	unsigned long samplerate;	unsigned int bits_per_sample;	unsigned int channels;	unsigned long total_samples;} WavHeader;int write_wav_header(unsigned char header[], WavHeader *wavHeader) {	//unsigned char header[44];	unsigned char* p = header;	unsigned int bytes = (wavHeader->bits_per_sample + 7) / 8;	float data_size = (float) bytes * wavHeader->total_samples;	unsigned long word32;	*p++ = 'R';	*p++ = 'I';	*p++ = 'F';	*p++ = 'F'; //RIFF 4	word32 = (unsigned long) data_size + (44 - 8);	*p++ = (unsigned char) (word32 >> 0);	*p++ = (unsigned char) (word32 >> 8);	*p++ = (unsigned char) (word32 >> 16);	*p++ = (unsigned char) (word32 >> 24); //數(shù)據(jù)長度 4+4	*p++ = 'W';	*p++ = 'A';	*p++ = 'V';	*p++ = 'E'; //WAVE 4+4+4	*p++ = 'f';	*p++ = 'm';	*p++ = 't';	*p++ = ' '; //fmt 4+4+4+4	*p++ = 0x10;	*p++ = 0x00;	*p++ = 0x00;	*p++ = 0x00; //16  4+4+4+4+4=20	*p++ = 0x01;	*p++ = 0x00; //1   4+4+4+4+4+2=22	*p++ = (unsigned char) (wavHeader->channels >> 0);	*p++ = (unsigned char) (wavHeader->channels >> 8); //聲道數(shù)   4+4+4+4+4+2+2=24	word32 = (unsigned long) (wavHeader->samplerate + 0.5);	*p++ = (unsigned char) (word32 >> 0);	*p++ = (unsigned char) (word32 >> 8);	*p++ = (unsigned char) (word32 >> 16);	*p++ = (unsigned char) (word32 >> 24); //采樣率   4+4+4+4+4+2+2+4=28	word32 = wavHeader->samplerate * bytes * wavHeader->channels;	*p++ = (unsigned char) (word32 >> 0);	*p++ = (unsigned char) (word32 >> 8);	*p++ = (unsigned char) (word32 >> 16);	*p++ = (unsigned char) (word32 >> 24); //每秒所需字節(jié)數(shù)  4+4+4+4+4+2+2+4=32	word32 = bytes * wavHeader->channels;	*p++ = (unsigned char) (word32 >> 0);	*p++ = (unsigned char) (word32 >> 8); // blockAlign(2個字節(jié)) 4+4+4+4+4+2+2+4+2=34	//每個采樣需要的字節(jié)數(shù),計(jì)算公式:聲道數(shù) * 每個采樣需要的bit  / 8	*p++ = (unsigned char) (wavHeader->bits_per_sample >> 0);	*p++ = (unsigned char) (wavHeader->bits_per_sample >> 8); //bitPerSample(2個字節(jié))4+4+4+4+4+2+2+4+2+2=36	//每個采樣需要的bit數(shù),一般為8或16	*p++ = 'd';	*p++ = 'a';	*p++ = 't';	*p++ = 'a'; //data 4+4+4+4+4+2+2+4+2+2+4=40	word32 = (unsigned long) data_size;	*p++ = (unsigned char) (word32 >> 0);	*p++ = (unsigned char) (word32 >> 8);	*p++ = (unsigned char) (word32 >> 16);	*p++ = (unsigned char) (word32 >> 24);	//size2(4個字節(jié))   4+4+4+4+4+2+2+4+2+2+4+4=44	// 錄音數(shù)據(jù)的長度,不包括頭部長度	return 0;}int ffmpeg_audio_decode(const char * inFile, const char * outFile,		int channel_num, int bit_rate, int sample_rate) {	av_register_all();	AVFrame* frame = av_frame_alloc();	if (!frame) {		fprintf(stderr, "Error allocating the frame");		return 1;	}	AVFormatContext* formatContext = NULL;	if (avformat_open_input(&formatContext, inFile, NULL, NULL) != 0) {		av_free(frame);		fprintf(stderr, "Error opening the file");		return 1;	}	if (avformat_find_stream_info(formatContext, NULL) < 0) {		av_free(frame);		avformat_close_input(&formatContext);		fprintf(stderr, "Error finding the stream info");		return 1;	}	AVStream* audioStream = NULL;	unsigned int i;	// Find the audio stream (some container files can have multiple streams in them)	for (i = 0; i < formatContext->nb_streams; ++i) {		if (formatContext->streams[i]->codec->codec_type				== AVMEDIA_TYPE_AUDIO) {			audioStream = formatContext->streams[i];			break;		}	}	if (audioStream == NULL) {		av_free(frame);		avformat_close_input(&formatContext);		fprintf(stderr, "Could not find any audio stream in the file");		return 1;	}	AVCodecContext* codecContext = audioStream->codec;	codecContext->codec = avcodec_find_decoder(codecContext->codec_id);	if (codecContext->codec == NULL) {		av_free(frame);		avformat_close_input(&formatContext);		fprintf(stderr, "Couldn't find a proper decoder");		return 1;	} else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0) {		av_free(frame);		avformat_close_input(&formatContext);		fprintf(stderr, "Couldn't open the context with the decoder");		return 1;	}	/*START*************************START***********************START*/	/*設(shè)置輸出格式,為了未來jni調(diào)用的簡單,所以都傳的int,反正是自己用的,直觀一些*/	int64_t outChannelLayout;	if (channel_num == 1) {		outChannelLayout = AV_CH_LAYOUT_MONO;	} else {		outChannelLayout = AV_CH_LAYOUT_STEREO;	}	enum AVSampleFormat outSampleFormat;	if (bit_rate == 32) {		outSampleFormat = AV_SAMPLE_FMT_S32;	} else {		outSampleFormat = AV_SAMPLE_FMT_S16;	}	int outSampleRate = sample_rate; //44100;	SwrContext* swrContext = swr_alloc_set_opts(NULL, outChannelLayout,			outSampleFormat, outSampleRate,			av_get_default_channel_layout(codecContext->channels),			codecContext->sample_fmt, codecContext->sample_rate, 0, NULL);	if (swrContext == NULL) {		av_free(frame);		avcodec_close(codecContext);		avformat_close_input(&formatContext);		fprintf(stderr, "Couldn't create the SwrContext");		return 1;	}	if (swr_init(swrContext) != 0) {		av_free(frame);		avcodec_close(codecContext);		avformat_close_input(&formatContext);		swr_free(&swrContext);		fprintf(stderr, "Couldn't initialize the SwrContext");		return 1;	}	/*END**************************END*************************END*/	fout = fopen(outFile, "wb+");	AVPacket packet;	av_init_packet(&packet);	double duration = (double) formatContext->duration / 1000.0 / 1000.0;	fprintf(stderr, "duration=%f/n", duration);	int total_sample = (int) duration * channel_num * sample_rate;	fprintf(stderr, "total_sample=%d/n", total_sample);	int count = 0;	fseek(fout,44, SEEK_SET);	while (av_read_frame(formatContext, &packet) == 0) {		if (packet.stream_index == audioStream->index) {			AVPacket decodingPacket = packet;			while (decodingPacket.size > 0) {				// Try to decode the packet into a frame				int frameFinished = 0;				int result = avcodec_decode_audio4(codecContext, frame,						&frameFinished, &decodingPacket);				if (result < 0 || frameFinished == 0) {					break;				}				unsigned char buffer[100000];				unsigned char* pointers[SWR_CH_MAX];				pointers[0] = &buffer[0];				//這個地方還不是很清楚,看官方的example感覺好復(fù)雜。尤其是參數(shù)。				int numSamplesOut = swr_convert(swrContext, pointers,						outSampleRate,						(const unsigned char**) frame->extended_data,						frame->nb_samples);				fwrite((short *) buffer, sizeof(short),						(size_t) numSamplesOut * channel_num, fout);				count += numSamplesOut* channel_num;				decodingPacket.size -= result;				decodingPacket.data += result;			}		}		av_free_packet(&packet);	}	fprintf(stderr, "count=%d/n", count);	unsigned char header[44];	WavHeader h;	h.bits_per_sample = bit_rate;	h.channels = channel_num;	h.samplerate = sample_rate;	h.total_samples = count;	write_wav_header(header, &h);	fseek(fout,0, SEEK_SET);	fwrite(&header, 1, 44, fout);	// Clean up!	av_free(frame);	avcodec_close(codecContext);	avformat_close_input(&formatContext);	fclose(fout);	return 0;}int main() {	char *inFile = "ping.mp3";	char *outFile = "ping.wav";	fprintf(stderr, "res:%d/n",			ffmpeg_audio_decode(inFile, outFile, 2, 16, 44100));	return 0;}




本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Scrcpy投屏原理淺析
實(shí)現(xiàn)ping命令的代碼
C語言::模擬實(shí)現(xiàn)strcmp函數(shù)
Linux下c基于openssl生成MD5的函數(shù)
點(diǎn)陣字體顯示系列之三:使用ncurses顯示漢字 | 遲思堂工作室
MSP430開發(fā)注意事項(xiàng)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服