我开发的应用程序能够录制来自网络摄像头的视频和来自麦克风的音频。我一直在使用QT,但遗憾的是相机模块无法在Windows上工作,导致我使用ffmpeg来录制视频/音频。
我的相机模块现在运行良好,除了同步的轻微问题。音频和视频有时会因为一小段差异而不同步(不到1秒我会说,虽然录制时间越长可能会更糟)。
当我对帧进行编码时,我按以下方式添加PTS(我从muxing.c示例中获取):
nb_samples
(从0开始)。我以25 fps保存文件并要求相机给我25 fps(可以)。我也将视频帧转换为YUV420P
格式。对于音频帧转换,我需要使用AVAudioFifo
因为微生物发送的样本比mp4流支持的样本更大,所以我必须将它们拆分成块。我使用了transcode.c示例。
我不知道如何同步音频和视频。我是否需要使用时钟或其他东西来正确同步两个流?
完整的代码太大了,无法在此处发布,但如果有必要,我可以将其添加到github中。例如。
以下是编写框架的代码:
int FFCapture::writeFrame(const AVRational *time_base, AVStream *stream, AVPacket *pkt) {
/* rescale output packet timestamp values from codec to stream timebase */
av_packet_rescale_ts(pkt, *time_base, stream->time_base);
pkt->stream_index = stream->index;
/* Write the compressed frame to the media file. */
return av_interleaved_write_frame(oFormatContext, pkt);
}
获取已用时间的代码:
qint64 FFCapture::getElapsedTime(qint64 *previousTime) {
qint64 newTime = timer.elapsed();
if(newTime > *previousTime) {
*previousTime = newTime;
return newTime;
}
return -1;
}
分别添加PTS(视频和音频流)的代码:
qint64 time = getElapsedTime(&previousVideoTime);
if(time >= 0) outFrame->pts = time;
//if(time >= 0) outFrame->pts = av_rescale_q(time, outStream.videoStream->codec->time_base, outStream.videoStream->time_base);
qint64 time = getElapsedTime(&previousAudioTime);
if(time >= 0) {
AVRational aux;
aux.num = 1;
aux.den = 1000;
outFrame->pts = time;
//outFrame->pts = av_rescale_q(time, aux, outStream.audioStream->time_base);
}