用PortAudio写入fifo并在OSX上用ffmpeg读取

时间:2017-11-21 17:22:10

标签: c++ macos ffmpeg fifo portaudio

我想做什么:

  1. 在PortAudio中打开麦克风作为音频源(正常工作)
  2. 将流写入fifo(作品)
  3. 用ffmpeg读取fifo(duse't work)
  4. 在PortAudio中,我正在使用阻塞I / O,如下所示: http://portaudio.com/docs/v19-doxydocs/blocking_read_write.html

    在循环中,我像这样写入fifo:

    int data = write('/tmp/aaa', sampleBlock, bufferSize);
    

    当我把它读到PortAudio写缓冲区时,它可以工作。

    bytes_read = read('/tmp/aaa', readSampleBlock, bufferSize);
    err = Pa_WriteStream(stream, readSampleBlock, bufferSize)
    

    当我在控制台上用ffmpeg读取它时:

    ffmpeg -y -i /tmp/aaa -f s16le -acodec copy -f nut -ar 48000 -ac 2 -v debug -report -acodec copy out.wav
    

    它只是阻止循环,就是这样。

    有人可以帮我弄清楚我需要做什么吗?

    我的代码:

    #define SAMPLE_SIZE (1)
    #define FRAMES_PER_BUFFER (480)
    #define AUDIOFIFO "/tmp/aaa"
    
    char *sampleBlock = NULL;
    int status, captured_bytes, fifo, bytes_read;
    
    
    err = Pa_OpenStream(&stream,
                        &inputParameters,
                        NULL,
                        48000,
                        FRAMES_PER_BUFFER,
                        paClipOff,
                        NULL, /* no callback, use blocking API */
                        NULL ); /* no callback, so no callback userData */
    if( err != paNoError ) goto error;
    
    numBytes = FRAMES_PER_BUFFER * numChannels * SAMPLE_SIZE ;
    sampleBlock = (char *) malloc( numBytes );
    memset( sampleBlock, SAMPLE_SILENCE, numBytes );
    
    if (status = mkfifo(AUDIOFIFO, 0666) < 0) 
    { 
      printf("Error making AUDIOFIFO: %s \n", strerror(errno)); 
    }
    err = Pa_StartStream( stream );
    if( err != paNoError )
    {
      goto error;
    } 
    
    fifo = open(AUDIOFIFO, O_RDWR, O_NONBLOCK);
    if (fifo < 0) printf("Error opening AUDIOFIFO: %s \n", strerror(errno));
    
    for( i=0; i<(60*48000)/FRAMES_PER_BUFFER; ++i )
    {   
      if ((err = Pa_ReadStream(stream, sampleBlock, FRAMES_PER_BUFFER)) != paNoError)
      {
        goto xrun;
      }  
      captured_bytes = write(fifo, sampleBlock, FRAMES_PER_BUFFER);
      if (captured_bytes < 0) 
      { 
        printf("Error writing to AUDIOFIFO: %s \n", strerror(errno));
      }
    
      framesProcessed += bufferSize;
    }
    

1 个答案:

答案 0 :(得分:0)

AFAIK是 ffmpeg 命令行的一般格式:

ffmpeg <GLOBAL OPTIONS> <INPUT OPTIONS> -i INPUT <OUTPUT OPTIONS> OUTPUT

即。在打开之前,您必须将输入流描述为 ffmpeg

所以我认为-f s16le(至少)必须在 ffmpeg 命令行的-i /tmp/aaa之前:

ffmpeg -y -f s16le -i /tmp/aaa ....