ffmpeg解码音频数据时,进行重采样(即改变文件原有的采样率)

我们使用ffmpeg解码音频的时候,往往需要改变原音频的采样率,即需要重采样。

比如一音乐文件的采样率22050,而播放端往往是固定的采样率,比如44100。在这种情况下,如果把解码出来的数据直接播放,会产生快进的效果。这个时候就需要对解码出来的数据作一次重采样,将数据转化为44100采样率下的数据,才能正确播放。

ffmpeg提供了一组用来重采样的API,主要如下:

/**
 *  Initialize audio resampling context.
 *
 * @param output_channels  number of output channels
 * @param input_channels   number of input channels
 * @param output_rate      output sample rate
 * @param input_rate       input sample rate
 * @param sample_fmt_out   requested output sample format
 * @param sample_fmt_in    input sample format
 * @param filter_length    length of each FIR filter in the filterbank relative to the cutoff frequency
 * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
 * @param linear           if 1 then the used FIR filter will be linearly interpolated
                           between the 2 closest, if 0 the closest will be used
 * @param cutoff           cutoff frequency, 1.0 corresponds to half the output sampling rate
 * @return allocated ReSampleContext, NULL if error occured
 */
ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
                                        int output_rate, int input_rate,
                                        enum AVSampleFormat sample_fmt_out,
                                        enum AVSampleFormat sample_fmt_in,
                                        int filter_length, int log2_phase_count,
                                        int linear, double cutoff);

int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples);

/**
 * Free resample context.
 *
 * @param s a non-NULL pointer to a resample context previously
 *          created with av_audio_resample_init()
 */
void audio_resample_close(ReSampleContext *s);


函数av_audio_resample_init()用来初始化重采样的参数,前4个参数很好理解;后6个参数基本上是使用缺省参数,分别为:

AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16,16, 10, 0, 1
函数audio_resample()用来重采样,前3个参数都好理解,最后一个参数是指“原数据的采样个数”,而不是input的bytes数。该函数的返回值也是采样个数,不过是重采样之后的。

函数audio_resample_close()用来清理重采样时分配的资源。

相关代码如下:

初始化

	// need to do re-sample
	if (m_codec_ctx->sample_rate != m_out_samplerate)
	{
		LOGW("%s, need re-sample, initialize re-sample engine! out channels:%d, out sample rate:%d hz, in channels:%d, in sample rate:%d",__FUNCTION__, 2, m_out_samplerate, m_codec_ctx->channels, m_codec_ctx->sample_rate);
		m_resample_engine = av_audio_resample_init(	2, m_codec_ctx->channels, m_out_samplerate, m_codec_ctx->sample_rate, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16, 16, 10, 0, 1);
	}

重采样代码

frame_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
memset(m_audio_buff, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
decoded_len = avcodec_decode_audio3(m_codec_ctx, (short *)m_audio_buff, &frame_size, &m_avpkt);
LOGI("%s, current decoded size:%d", __FUNCTION__, decoded_len);
if (decoded_len > 0)
{
	m_avpkt.size -= decoded_len;
	m_avpkt.data += decoded_len;

	decoded_audio_len = frame_size;
	valid_data_pointer = m_audio_buff;

	// need to re-sample
	if (m_resample_engine)
	{
		// convert byte to short
		int after_resampled_len = 0;
		int before_resampled_len = frame_size/(2 * m_codec_ctx->channels);
		memset(m_audio_resampled_buff, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
		after_resampled_len = audio_resample(m_resample_engine, (short *)m_audio_resampled_buff, (short *)m_audio_buff, before_resampled_len);
		LOGI("%s, re-sampled! length in:%d, length out:%d", __FUNCTION__, before_resampled_len, after_resampled_len);
		decoded_audio_len = after_resampled_len * 2 * 2;	//convert short to byte, and 2 channels
		valid_data_pointer = m_audio_resampled_buff;
	}

      	memcpy(buff+copied_len, valid_data_pointer, decoded_audio_len);
      	copied_len += decoded_audio_len;
      	LOGI("%s, copy1, %d bytes has copied to output buff, total:%d!", __FUNCTION__, decoded_audio_len, copied_len);                                                                                                                        }

释放代码

if (m_resample_engine)
{
	audio_resample_close(m_resample_engine);
	m_resample_engine = 0;
}

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 你可以使用 ffmpeg 命令来查看音频文件采样率。具体操作如下: 打开终端(Linux 或 macOS)或命令提示符(Windows),输入以下命令: ``` ffmpeg -i input_audio_file ``` 其中,`input_audio_file` 是你要查看的音频文件名。执行该命令后,ffmpeg 会输出该音频文件的详细信息,包括采样率。在输出信息中,你可以找到类似下面这样的一行: ``` Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s ``` 其中的 `44100 Hz` 就是该音频文件采样率。如果该音频文件有多个音频流,你需要指定要查看的音频流编号。例如,要查看第二个音频流的采样率,可以使用以下命令: ``` ffmpeg -i input_audio_file -map 0:a:1 -af "pan=mono|c0=c1" -f null - ``` 其中,`-map 0:a:1` 指定要查看第二个音频流。`-af "pan=mono|c0=c1"` 将音频流转换为单声道,以便输出到终端。`-f null -` 表示将输出重定向到空设备,以避免输出到终端。 ### 回答2: 要查看音频文件的真实采样率,可以使用FFmpeg提供的命令行工具。下面是一种方法: 1. 打开终端或命令行界面。 2. 使用以下命令格式来查看音频文件采样率: ``` ffmpeg -i [音频文件路径] ``` 这里,将`[音频文件路径]`替换为你要查看的音频文件的完整路径。 3. 执行上述命令后,FFmpeg将显示音频文件的详细信息。在其中的输出中,你可以看到类似于下面这样的行: ``` Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp ``` 这里的`44100 Hz`表示音频文件采样率。你可以通过查找类似于`Audio`或`音频`的关键词来快速找到这一行。 使用上述方法,你可以轻松地查看音频文件的真实采样率。 ### 回答3: 要查看音频文件的真实采样率,可以使用FFmpeg进行操作。以下是使用FFmpeg查看音频文件采样率的步骤: 首先,打开命令提示符或终端窗口,并导航到FFmpeg的安装路径。 然后,使用以下命令行将音频文件的信息导出到文本文件中: ``` ffmpeg -i 输入音频文件路径 > 输出文本文件路径 执行 ``` 请将"输入音频文件路径"替换为要查看采样率音频文件的实际路径,并将"输出文本文件路径"替换为保存输出信息的文本文件的路径。 运行该命令后,FFmpeg将会分析音频文件并将结果输出到指定的文本文件中。 接下来,打开输出文本文件,寻找包含有关音频流的信息的部分。 在该部分内,应该能够找到采样率的信息。通常,采样率的信息将标明为"Sample rate"或"Srate"。它的值通常以Hz(赫兹)为单位给出。 查找到采样率信息后,您就能了解该音频文件的真实采样率了。 请注意,以上步骤假定您已经正确安装并配置了FFmpeg,并且了解如何在命令提示符或终端窗口中运行命令。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值