void rec_audio() {
int ret = -1;
char errors[1024] = {0, };
int count = 0;
//ctx
AVFormatContext *fmt_ctx = NULL;
AVDictionary *options = NULL;
//pakcet
AVPacket pkt;
// [[video device]:[audio device]]
char *devicename = ":1";
// set log level
av_log_set_level(AV_LOG_DEBUG);
// start record
rec_status = 1;
// register audio device
// av_register_all();
avdevice_register_all();
// get format
AVInputFormat *iformat = av_find_input_format("avfoundation");
// open device
if((ret = avformat_open_input(&fmt_ctx, devicename, iformat, &options)) < 0 ){
av_strerror(ret, errors, 1024);
fprintf(stderr, "Failed to open audio device, [%d]%s\n", ret, errors);
return;
}
sleep(1);
// create file
char *out = "/Users/mac/Documents/imooc_av/1.pcm";
FILE *outfile = fopen(out, "wb+");
ret = -1;
// read data from device
while (ret != 0 && count++ < 5000) {
ret = av_read_frame(fmt_ctx, &pkt);
printf("ret is %d\n", ret);
printf("device is not ready!\n");
sleep(1);
}
while((ret = av_read_frame(fmt_ctx, &pkt)) == 0 &&
rec_status){
// write file
fwrite(pkt.data, 1, pkt.size, outfile);
fflush(outfile);
printf("pkt.size is %d\n", pkt.size);
av_log(NULL, AV_LOG_INFO,
"packet size is %d(%p), count=%d \n",
pkt.size, pkt.data, count);
av_packet_unref(&pkt); //release pkt
sleep(1);
}
// close file
fclose(outfile);
//close device and release ctx
avformat_close_input(&fmt_ctx);
av_log(NULL, AV_LOG_DEBUG, "finish!\n");
return;
}
这个是我的代码,与您课程中对不一致主要来源于打开设备后要一阵子才能开始录制音频,并且每次录制中需要sleep 1s才能继续下去。
这段代码将录制的音频保存为1.pcm这个文件。
之前提的问题是播放问题,也就是
使用ffplay -ar 44100 -ac 2 -f s16le test.pcm
播放有误,虽然我这边无法确定-f后的参数是什么,我使用 ffplay test.pcm
看到是16位的,但是使用-f s16就出现倍速和杂音。
但是我把该参数去掉以后,可以正常播放ffmpeg -f avfoundation -i :1 test.pcm
录制的音频。
贴出的代码中,打印如下,无法从打印中看到有什么问题
2023-08-26 23:17:33.081426+0800 myapp[21674:2472955] Metal API Validation Enabled
2023-08-26 23:17:35.004356+0800 myapp[21674:2473409] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x600000261d40> F8BB1C28-BAE8-11D6-9C31-00039315CD46
2023-08-26 23:17:35.048942+0800 myapp[21674:2473409] HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine
2023-08-26 23:17:35.049546+0800 myapp[21674:2473409] HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine
2023-08-26 23:17:35.049981+0800 myapp[21674:2473409] HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine
2023-08-26 23:17:35.062643+0800 myapp[21674:2473409] HALC_ShellObject::GetPropertyData: call to the proxy failed, Error: 2003332927 (who?)
2023-08-26 23:17:35.062687+0800 myapp[21674:2473409] HALPlugIn::ObjectGetPropertyData: got an error from the plug-in routine, Error: 2003332927 (who?)
2023-08-26 23:17:35.081562+0800 myapp[21674:2473409] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x600000268da0> 30010C1C-93BF-11D8-8B5B-000A95AF9C6A
2023-08-26 23:17:35.096743+0800 myapp[21674:2473409] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x600000268da0> 30010C1C-93BF-11D8-8B5B-000A95AF9C6A
[avfoundation @ 0x102433840] audio device 'Built-in Microphone' opened
ret is 0
device is not ready!
pkt.size is 4096
packet size is 4096(0x1028e8a00), count=1
pkt.size is 4096
packet size is 4096(0x103112600), count=1
pkt.size is 4096
packet size is 4096(0x1038aa200), count=1
pkt.size is 4096
packet size is 4096(0x1028f8e00), count=1
pkt.size is 4096
packet size is 4096(0x1028e8a00), count=1
pkt.size is 4096
packet size is 4096(0x1038a9a00), count=1
finish!
但是使用ffplay对音频进行播放时,
% ffplay 1.pcm
ffplay version 6.0 Copyright © 2003-2023 the FFmpeg developers
built with Apple clang version 12.0.0 (clang-1200.0.32.29)
configuration: --prefix=/usr/local/ffmpeg --enable-debug=3 --disable-static --enable-shared
libavutil 58. 2.100 / 58. 2.100
libavcodec 60. 3.100 / 60. 3.100
libavformat 60. 3.100 / 60. 3.100
libavdevice 60. 1.100 / 60. 1.100
libavfilter 9. 3.100 / 9. 3.100
libswscale 7. 1.100 / 7. 1.100
libswresample 4. 10.100 / 4. 10.100
1.pcm: Invalid data found when processing input
报Invalid data found
这里,我看视频中fwrite函数是
fwrite(pkt.data, pkt.size, 1, outfile);
而提供的源码中,则是
fwrite(pkt.data, 1, pkt.size, outfile);
我两种都尝试了,报的是同一个问题,也就是Invalid data。
所以,我主要的问题,来源于为什么得到1.pcm无法正常播放;另一个问题就是,为什么源码给出的和视频这里不一致?