ffmeg

音频文件转码

简介

本文描述如何从其它格式的音频转成符合语音识别输入要求格式的音频文件。

由于底层识别使用的是pcm,因此推荐直接上传pcm文件。如果上传其它格式,会在服务器端转码成pcm,调用接口的耗时会增加。

语音识别仅支持以下格式 :pcm(不压缩)、wav(不压缩,pcm编码)、amr(有损压缩格式);8k/16k 采样率 16bit 位深的单声道。即:

  1. pcm wav amr 格式三选一。 正常情况请使用pcm。其中wav格式需要使用pcm编码。
  2. 采用率二选一 8000 或者 16000。正常情况请使用16000
  3. 单声道

示例音频文件下载

转换命令示例

wav 文件转 16k 16bits 位深的单声道pcm文件

ffmpeg -y  -i 16k.wav  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 16k.pcm 

44100 采样率 单声道 16bts pcm 文件转 16000采样率 16bits 位深的单声道pcm文件

ffmpeg -y -f s16le -ac 1 -ar 44100 -i test44.pcm  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 16k.pcm 

mp3 文件转 16K 16bits 位深的单声道 pcm文件

ffmpeg -y  -i aidemo.mp3  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 16k.pcm 

// -acodec pcm_s16le pcm_s16le 16bits 编码器 
// -f s16le 保存为16bits pcm格式
// -ac 1 单声道
//  -ar 16000  16000采样率

正常输出如下:

Input #0, mp3, from 'aaa.mp3':
  Metadata:
    encoded_by      : Lavf52.24.1
  Duration: 00:02:33.05, start: 0.000000, bitrate: 128 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 128 kb/s
// 输入音频, MP3格式, 44100采样率,stereo-双声道, 16bits 编码   
    
Output #0, s16le, to '16k.pcm':
  Metadata:
    encoded_by      : Lavf52.24.1
    encoder         : Lavf57.71.100
    Stream #0:0: Audio: pcm_s16le, 16000 Hz, mono, s16, 256 kb/s
    
// 输入音频, MP3格式, 16000采样率,mono-单声道, 16bits    
// 256 kb/s = 32KB/s = 32B/ms

ffmpeg 使用说明

简介

ffmpeg 的一个功能是转换不同的音频格式,其它简介请至http://ffmpeg.org/

linux 版本:http://www.ffmpeg.org/download.html#build-linux linux 静态编译版本:https://www.johnvansickle.com/ffmpeg/ windows 版本 :http://ffmpeg.zeranoe.com/builds/

ffmpeg官方文档地址:http://ffmpeg.org/ffmpeg.html

编译参数与支持格式

ffmpeg默认支持pcm与wav(pcm编码)格式,额外的编译参数如下:

  • --enable-libopencore-amrnb 支持amr-nb(8000 采样率) 读写
  • --enable-libopencore-amrwb 支持amr-wb(16000 采样率) 读取
  • --enable-libvo-amrwbenc 支持amr-wb(16000 采样率) 写入
  • --enable-libmp3lame 支持mp3 写入 ffmpeg -codecs 可以查看所有的格式:
	D..... = Decoding supported  # 读取
	.E.... = Encoding supported  # 写入
	..A... = Audio codec      # 音频编码
	....L. = Lossy compression # 有损
	.....S = Lossless compression # 无损
	DEA..S pcm_s16le            PCM signed 16-bit little-endian
	DEA.LS wavpack              WavPack
	DEA.L. mp3  MP3 (MPEG audio layer 3) 
	DEA.L. amr_nb       AMR-NB (Adaptive Multi-Rate NarrowBand)         
	DEA.L. amr_wb       AMR-WB (Adaptive Multi-Rate WideBand)     

输入音频参数

wav amr 与mp3格式都自带头部, 含有采样率 编码 多声道等信息。而pcm为原始音频信息,没有类似头部。 wav(pcm编码)格式,仅仅在同样参数的pcm文件加了个几百k的文件头。

输入 wav amr 及mp3格式:

-i  test.wav # 或test.mp3 或者 test.amr

输入 pcm格式: pcm需要额外告知编码格式,采样率,单声道信息

-f s16le -ac 1 -ar 16000 -i 8k.pcm
// 单声道 16000 采样率  16bits编码 pcm文件

输出音频参数

在原始采样率 大于或者接近16000的时候,推荐使用16000的采样率。 8000的采样率会降低识别效果。 输出wav和amr格式时,如果不指定输出编码器的haunt,ffmpeg会选取默认编码器。

输出pcm音频

-f s16le -ac 1 -ar 16000 16k.pcm  
// 单声道 16000 采样率 16bits编码 pcm文件

输出wav 音频:

-ac 1 -ar 16000 16k.wav 
// 单声道 16000 采样率 16bits编码 pcm编码的wav文件

输出amr-nb 音频 :全称是:Adaptive Multi-Rate,自适应多速率,是一种音频编码文件格式,专用于有效地压缩语音频率。在带宽不是瓶颈的情况下,不建议选择这种格式,解压需要百度服务器额外的耗时 amr-nb格式只能选 8000采样率。bit rates越高音质越好,但是文件越大。 bit rates 4.75k, 5.15k, 5.9k, 6.7k, 7.4k, 7.95k, 10.2k or 12.2k

8000的采样率及有损压缩会降低识别效果。如果原始采样率大于16000,请使用 amr-wb格式。

-ac 1 -ar 8000 -ab 12.2k 8k-122.amr

// 8000 采样率 12.2 bitRates 

输出 amr-wb 格式,采样率 16000。 bit rates越高音质越好,但是文件越大。 6600 8850 12650 14250 15850 18250 19850 23050 23850

-acodec amr_wb -ac 1 -ar 16000 -ab 23850 16k-23850.amr

常用参数

  • -y 覆盖同名文件
  • -v 日志输出基本 如 -v ERROR -v quiet 等

参数拼接

ffmpeg {常用参数} {输入音频参数} {输出音频参数}

示例: 输入是 32000HZ的单声道 16bits pcm文件。查询之前的输入参数为 “ -f s16le -ac 1 -ar 32000 -i test32.pcm” 输出是 16000HZ的单声道 16bits pcm文件。查询之前的输出参数为 “-f s16le -ac 1 -ar 16000 16k.pcm” 常用参数选择 -y

合并如下:

ffmpeg  -y  -f s16le -ac 1 -ar 32000  -i test32.pcm -f s16le -ac 1 -ar 16000 16k.pcm

查看音频格式ffprobe使用

查看语音合成生成的MP3格式信息:

ffprobe -v quiet -print_format json -show_streams  aidemo.mp3

返回如下

 {
    "streams": [
        {
            "index": 0,
            "codec_name": "mp3", // mp3 格式
            "codec_long_name": "MP3 (MPEG audio layer 3)",
            "codec_type": "audio",
            "codec_time_base": "1/16000", 
            "codec_tag_string": "[0][0][0][0]",
            "codec_tag": "0x0000",
            "sample_fmt": "s16p", 
            "sample_rate": "16000", // 16000采样率
            "channels": 1, // 单声道
            "channel_layout": "mono",
            "bits_per_sample": 0,
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0",
            "time_base": "1/14112000",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 259096320,
            "duration": "18.360000",
            "bit_rate": "16000",
            "disposition": {
                "default": 0,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0
            }
        }
    ]
}

pcm文件音频时长计算

同图像bmp文件一样,pcm文件保存的是未压缩的音频信息。 16bits 编码是指,每次采样的音频信息用2个字节保存。可以对比下bmp文件用分别用2个字节保存RGB颜色的信息。 16000采样率 是指 1秒钟采样 16000次。常见的音频是44100HZ,即一秒采样44100次。 单声道: 只有一个声道。

根据这些信息,我们可以计算: 1秒的16000采样率音频文件大小是 216000 = 32000字节 ,约为32K 1秒的8000采样率音频文件大小是 28000 = 16000字节 ,约为 16K

如果已知录音时长,可以根据文件的大小计算采样率是否正常。



http://ai.baidu.com/docs#/ASR-API/top     语音识别rest api文档

ffmpeg硬件解码demo主要是通过调用ffmpeg库中的接口来实现硬件加速解码功能。下面是一个简单的示例代码: ```c++ #include <stdio.h> #include <stdbool.h> #include <SDL2/SDL.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/imgutils.h> int main(int argc, char* argv[]) { // 初始化FFmpeg库 av_register_all(); avformat_network_init(); // 打开视频文件 AVFormatContext* formatCtx = avformat_alloc_context(); if (avformat_open_input(&formatCtx, argv[1], NULL, NULL) != 0) { printf("无法打开输入文件\n"); return -1; } if (avformat_find_stream_info(formatCtx, NULL) < 0) { printf("无法获取流信息\n"); return -1; } // 查找视频流 int videoStreamIndex = -1; for (int i = 0; i < formatCtx->nb_streams; i++) { if (formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoStreamIndex = i; break; } } if (videoStreamIndex == -1) { printf("无法找到视频流\n"); return -1; } // 获取解码器 AVCodec* codec = avcodec_find_decoder(formatCtx->streams[videoStreamIndex]->codecpar->codec_id); if (codec == NULL) { printf("找不到解码器\n"); return -1; } // 打开解码器 AVCodecContext* codecCtx = avcodec_alloc_context3(codec); if (avcodec_parameters_to_context(codecCtx, formatCtx->streams[videoStreamIndex]->codecpar) != 0) { printf("无法打开解码器\n"); return -1; } if (avcodec_open2(codecCtx, codec, NULL) < 0) { printf("无法打开解码器\n"); return -1; } // 创建SDL窗口 SDL_Window* window = SDL_CreateWindow("FFmpeg硬件解码Demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, codecCtx->width, codecCtx->height, SDL_WINDOW_OPENGL); if (window == NULL) { printf("无法创建窗口\n"); return -1; } // 创建SDL渲染器 SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0); AVFrame* frame = av_frame_alloc(); AVPacket packet; // 读取视频帧并渲染 bool quit = false; while (!quit) { if (av_read_frame(formatCtx, &packet) < 0) { break; } if (packet.stream_index == videoStreamIndex) { avcodec_send_packet(codecCtx, &packet); while (avcodec_receive_frame(codecCtx, frame) == 0) { SDL_RenderClear(renderer); // 将帧数据复制到纹理 SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, codecCtx->width, codecCtx->height); SDL_UpdateYUVTexture(texture, NULL, frame->data[0], frame->linesize[0], frame->data[1], frame->linesize[1], frame->data[2], frame->linesize[2]); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); SDL_DestroyTexture(texture); SDL_Event event; SDL_PollEvent(&event); if (event.type == SDL_QUIT) { quit = true; break; } } } av_packet_unref(&packet); } // 释放资源 av_frame_free(&frame); avcodec_close(codecCtx); avformat_close_input(&formatCtx); return 0; } ``` 这个示例代码使用了SDL库来进行窗口和渲染器的创建,通过SDL播放解码后的视频帧。其中,ffmpeg库提供了相关的接口方法来实现视频文件的打开、流信息的获取、解码器的查找和打开、帧的解码等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值