ffmpeg从音频设备上读取和录制数据

292 阅读2分钟

读取数据

API: av_read_frame

读取音视频或视频数据, 如果读取的是视频包放入视频文件, 如果读取的是音频包, 放入音频文件, 一次实现音视频数据的分离.

两个参数和返回值:

  • AVFormatContext : 上下文, 通过ffmpeg处理多媒体文件或者设备的时候 首先要有一个上下文, 通过 avformat_open_input 这个API获得. 通过获得的这个上下文指针, 来知道是从设备中读取数据还是从多媒体文件中读取数据.

  • AVPacket : 音/视频数据包, 根据环境去判断属于音频还是属于视频.

  • 返回值为0 表示成功, 通过判断是否等于0来持续的读取数据.

AVPacket重要属性:

  • data : 音频/视频的具体数据.
  • size : data指向的缓冲区的大小是多少, 应该取出多少字节.

与AVPacket相关的API:

  • av_init_packet : 对AVPacket进行初始化, 但是这个初始化是有一定限制的: 是除了data 和 size 之外的其他域(属性)的初始化.

  • av_packet_unref : 减引用计数, 释放AVPacket, 与av_init_packet 成对使用.

  • av_packet_alloc : 内部做了两件事, 首先分配堆内存空间, 然后调用av_init_packet进行内部成员的初始化.

  • av_packet_free : av_packet_alloc 的反操作, 内部首先调用av_packet_unref释放pakcet内部的资源后 再将av_packet_alloc申请的空间释放掉, 与av_packet_alloc 成对使用.

录制数据

创建文件

staticFILE* create_outfile(void) {    char *filename = "/Users/.../audio.aac"; // 文件路径    FILE *outfile = fopen(filename, "wb+"); // w : 写数据   b: 二进制数据  + : 如果文件不存在就创建    return outfile;}

将音频数据写入到文件中

系统出于效率考虑,并不会直接将数据写入文件内,而是首先将数据放入一个缓冲区, 等攒够一大段的数据后, 系统才会将数据写入到文件IO中, 再操作磁盘进行写入. 因此当机器出现故障等异常情况的时候, 写入操作将会终止,造成一部分数据的丢失, 所以这里可以根据自己的逻辑手动将数据直接写入文件中: fflush().

fwrite(pkt->data, pkt->size, 1, output); 
// pkt : 读取到或者经过其他处理的音频数据包
// output : 输出文件的路径(上一步创建的文件)

关闭文件

fclose(outfile);

一个完成的商业级的录制, 还需要做灾备的功能: 由服务器进行录制, 并且在收到数据之后分发给多台服务器进行录制, 避免某一台或多台服务器出现故障导致录制失败或者数据丢失的情况.