代码中录制的音频,播放报Invalid data

来源:6-12 通过界面来控制开启或关闭录制

weixin_慕斯卡8568554

2023-08-26


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无法正常播放;另一个问题就是,为什么源码给出的和视频这里不一致?

写回答

1回答

李超

2023-08-27

ffplay 播放.pcm 音频时必须指定音频参数:采样率,通道数和采样大小,因为他是原始数据,你不告诉ffplay 它就不知道怎么播这个文件。如果你不知道这些参数时,可以先用ffmpeg 命令录制一段.wav 格式的音频问题,然后用ffplay xxx.wav 播放,就可以看到这些参数了,然后用这些参数播放.pcm就可以了。

0
2
李超
回复
weixin_慕斯卡8568554
把你获得参数的完整截图发上来看看,或者到课程QQ群里把截图发上来,这样更便于沟通
2023-08-28
共2条回复

音视频小白系统入门课 音视频基础+ffmpeg原理

掌握音视频采集、编解码、RTMP传输协议等核心基础

2214 学习 · 758 问题

查看课程