brew 安装关联三方库
1 安装FFmpeg
brew install ffmpeg
这一步主要是把主要的依赖都安装上
选择一个第三方仓库,安装options、并和ffmepg关联起来
有两个仓库,分别是homebrew-ffmpeg和varenc-homebrew-ffmpeg ;这里使用homebrew-ffmpeg;
- 执行
brew tap homebrew-ffmpeg/ffmpeg
- 执行
brew install homebrew-ffmpeg/ffmpeg/ffmpeg
- 执行如下命令,看此仓库支持哪些options。
brew options homebrew-ffmpeg/ffmpeg/ffmpeg
- 根据第(3)步得到的options,替换下面命令中的option,然后执行
brew reinstall homebrew-ffmpeg/ffmpeg/ffmpeg --with-fdk-aac --with-game-music-emu --with-libbluray --with-libbs2b --with-libgsm --with-libmodplug --with-libopenmpt --with-librist --with-librsvg --with-libsoxr --with-libvmaf --with-libxml2 --with-opencore-amr --with-openh264 --with-openjpeg --with-openssl --with-openssl@1.1 --with-rav1e --with-rtmpdump --with-speex --with-srt --with-two-lame --with-webp --with-xvid --with-zeromq --with-zimg
Mac 签名.dylb
这种签名方式会把 /usr/local/opt/
目录下所有的动态库都签名;
codesign -f -s "Apple Development: 你的邮箱" /usr/local/*/*/lib/*.dylib
证书名字可以通过下述命令查询:
security find-identity -v -p codesigning
重采样问题
-35问题
对于出现-35的问题,这个其实就是设备的资源没有准备好;网上说要延迟解决,其实不应该延迟,反而使用延迟会导致无法确定合适的延迟时间而导致录制的数据出现问题,最简单的做法如下:
if (ret == AVERROR(EAGAIN)) { // 资源临时不可用
av_packet_unref(audioPacket);
continue;
}
输入缓冲区
关于av_samples_alloc_array_and_samples创建输入缓冲区的时候src_nb_samples(单个通道采样个数计算)计算的问题;我mac上采集的AVPacket大小是2048,单声道,FLT(浮点 是 4个字节)的;所以计算下就是 2048/1/4 = 512;
输出缓冲区
输出缓冲区的dst_nb_samples计算,ffmpeg提供了av_rescale_rnd可以用来计算,计算如下:
dst_nb_samples =
(int)av_rescale_rnd(src_nb_samples, DstRate, SrcRate, AV_ROUND_UP);
重采样的src_nb_samples计算
src_nb_samples = audioPacket->size / av_get_bytes_per_sample(srcSampleFmt);
acc 编码问题
如果无法使用libfdk_aac
库,那么需要检查下ffempeg库编译的时候是否关联的库;可以使用上面的方式关联,也可以自己编译;
FF_PROFILE_AAC_HE_V2 的profile最低要求双声道,所以使用的时候判断下:
if (av_get_channel_layout_nb_channels(channel_layout)) == 2) {
codecCtx->bit_rate = 32000;
codecCtx->profile = FF_PROFILE_AAC_HE_V2;
}else if(av_get_channel_layout_nb_channels(channel_layout) == 1) {
codecCtx->bit_rate = 97000;
codecCtx->profile = FF_PROFILE_AAC_LOW;
}
fmt要求的是16的倍数,可以使用ffmpeg官方提供的示例进行检查:
// 检查编码器codec是否支持采样格式sample_fmt
static int check_sample_fmt(const AVCodec *codec,
enum AVSampleFormat sample_fmt) {
const enum AVSampleFormat *p = codec->sample_fmts;
while (*p != AV_SAMPLE_FMT_NONE) {
if (*p == sample_fmt) return 1;
p++;
}
return 0;
}
调用方式:检查采样格式
if (!check_sample_fmt(codec, dstSampleFmt)) {
av_log(NULL, AV_LOG_DEBUG, "Encoder does not support sample format %s\n",av_get_sample_fmt_name(dstSampleFmt));
return nullptr;
}