ffmpeg音频编码

以mp3编码为例,编解码库中提供了两种音频编码api,下面分别给出两个api的用法。好啦,废话不多说,贴出代码供参考。

void audio_encode(const char * inputfilename,const char *outputfilename) {
	AVCodec *codec;
	AVCodecContext *c = NULL;
	int frame_size, out_size, outbuf_size;
	FILE * fin, *fout;
	short *samples;
	uint8_t *outbuf;
	int numberframe = 0;
	int size = 0;
	int FRAME_READ = 0;
       
	printf("Audio encoding\n");
        av_register_all();
	/* find the MP3 encoder */
	codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
	if (!codec) {
		fprintf(stderr, "codec not found\n");
		exit(1);
	}

	c = avcodec_alloc_context();

	/* put sample parameters */
	c->bit_rate = 64000;
      c->sample_rate = 44100;
	c->channels = 2;
	c->sample_fmt = AV_SAMPLE_FMT_S16;

	

	/* open it */
	if (avcodec_open(c, codec) < 0) {
		fprintf(stderr, "could not open codec\n");
		exit(1);
	}

	/* the codec gives us the frame size, in samples */
	frame_size = c->frame_size;
	samples = malloc(frame_size * 2 * c->channels); 

	FRAME_READ = frame_size * 2 * c->channels;

	outbuf_size = 10000;
	outbuf = malloc(outbuf_size);

	fin = fopen(inputfilename, "rb+");
	if (!fin) {
		fprintf(stderr, "could not open %s\n", inputfilename);
		exit(1);
	}

	fout = fopen(outputfilename, "wb");
	if (!fout) {
		fprintf(stderr, "could not open %s\n", outputfilename);
		exit(1);
	}
	for (;;) {
		size = fread(samples, 1, FRAME_READ, fin);
		if (size == 0) {
			break;
		}
		/* encode the samples */
		out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
		fwrite(outbuf, 1, out_size, fout);
		numberframe++;
		printf("save frame %d\n", numberframe);

	}
	fclose(fout);
	free(outbuf);
	free(samples);

	avcodec_close(c);
	av_free(c);
	printf("audio encode finish...");
}


上面程序中用到的音频编码api已经过时了,官方文档中不建议使用,下面看看新的编码api。


static void audio_encode_example(const char *output_filename,const char *input_filename) {
	AVCodec *codec;
	AVCodecContext *c = NULL;
	AVFrame *frame;
	AVPacket pkt;
	int i,ret, got_output;
	int buffer_size;
	FILE *fout, *fin;
	uint8_t *samples;
	int numberframe = 0;

	printf("Encode audio file %s\n", output_filename);
        av_register_all();
	/* find the MP3 encoder */
	codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
	if (!codec) {
		fprintf(stderr, "Codec not found\n");
		exit(1);
	}

	c = avcodec_alloc_context3(codec);

	/* put sample parameters */
	c->bit_rate = 64000;
	c->sample_rate = 44100;
	c->channels = 2;

	
	c->sample_fmt = AV_SAMPLE_FMT_S16;
	

	/* select other audio parameters supported by the encoder */

	c->channel_layout = select_channel_layout(codec);
	

	/* open it */
	if (avcodec_open2(c, codec, NULL ) < 0) {
		fprintf(stderr, "Could not open codec\n");
		exit(1);
	}

	fout = fopen(output_filename, "wb");
	if (!fout) {
		fprintf(stderr, "Could not open %s\n", output_filename);
		exit(1);
	}

	fin = fopen(input_filename, "rb");
	if (!fin) {
		fprintf(stderr, "Could not open %s\n", input_filename);
		exit(1);
	}

	/* frame containing input raw audio */
	frame = avcodec_alloc_frame();
	if (!frame) {
		fprintf(stderr, "Could not allocate audio frame\n");
		exit(1);
	}

	frame->nb_samples = c->frame_size;
	frame->format = c->sample_fmt;
	frame->channel_layout = c->channel_layout;

	/* the codec gives us the frame size, in samples,
	 * we calculate the size of the samples buffer in bytes */
	buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
			c->sample_fmt, 0);
	samples = av_malloc(buffer_size);
	if (!samples) {
		fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
				buffer_size);
		exit(1);
	}
	/* setup the data pointers in the AVFrame */
	ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
			(const uint8_t*) samples, buffer_size, 0);
	if (ret < 0) {
		fprintf(stderr, "Could not setup audio frame\n");
		exit(1);
	}

	for (;;) {

		av_init_packet(&pkt);
		pkt.data = samples;
		pkt.size = fread(samples, 1, buffer_size, fin);
		if (pkt.size == 0) {
			break;
		}

		ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
		if (ret < 0) {
			fprintf(stderr, "Error encoding audio frame\n");
			exit(1);
		}
		if (got_output) {
			fwrite(pkt.data, 1, pkt.size, fout);
			av_free_packet(&pkt);
			numberframe++;
			printf("save frame %d\n", numberframe);
		}

	}

	/* get the delayed frames */
	for (got_output = 1; got_output; i++) {
	  av_init_packet(&pkt);
		pkt.size=1024;
		ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
		if (ret < 0) {
			fprintf(stderr, "Error encoding frame\n");
			exit(1);
		}

		if (got_output) {
			fwrite(pkt.data, 1, pkt.size, fout);
			av_free_packet(&pkt);
		}
	}
	fclose(fout);
	fclose(fin);
	av_freep(&samples);
	avcodec_free_frame(&frame);
	avcodec_close(c);
	av_free(c);
	printf("audio encode finish...");
}




PS:水平有限,如以上内容有误,欢迎指正!

### 水平衡方程计算水源涵养方法平衡方程的核心在于描述定时间和空间范围内水分的质守恒关系。具体而言,在某区域内,输入的水减去输出的水等于系统内蓄水的变化[^1]。 #### 公式表示 水平衡方程通常可以表达为: \[ \Delta S = P - (E + R) \] 其中: - \( \Delta S \): 系统内的蓄水变化; - \( P \): 输入到系统的降水; - \( E \): 蒸散发(蒸发和植物蒸腾作用总和); - \( R \): 输出的地表径流或地下排水流。 此公式适用于不同尺度的空间范围以及时间周期,可用于估算生态系统的水源涵养能力[^3]。 #### 数据需求与处理 为了应用上述公式,需要收集并分析以下数据: 1. **降水数据** (\(P\)):可以通过气象站点观测或者卫星遥感反演获得。 2. **蒸散数据** (\(E\)):可基于地面测模型模拟或遥感技术获取。 3. **径流数据** (\(R\)):可通过河流监测站记录得到实际流出。 通过这些基础数据代入公式即可求得某时段内区域的净储水变化(\(ΔS\))[^2]。如果目标是评估长期平均状态下的稳定条件,则假设\( ΔS ≈ 0\) ,从而简化成: \[ P ≈ E + R \] 此时,剩余未被消耗掉的部分即代表了潜在可供储存利用的有效水资源——也就是所谓的“水源涵养”。 ```python def water_balance(P, E, R): """ Calculate the change in storage using the water balance equation. Parameters: P : float or array-like Precipitation input. E : float or array-like Evapotranspiration output. R : float or array-like Runoff output. Returns: delta_S : float or numpy.ndarray Change in storage over time period considered. """ import numpy as np # Ensure inputs are arrays for element-wise operations if necessary P = np.asarray(P) E = np.asarray(E) R = np.asarray(R) # Compute Delta S according to Water Balance Equation delta_S = P - (E + R) return delta_S ``` 以上函数实现了基本的水平衡运算逻辑,可以根据给定参数快速得出结果。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值