这几天,用RVMedia的从摄像头抓取视频,但RVMedia 4.0.2 只支持录制成 MJPEG 格式,而 MJPEG 的格式是以JPEG 格式存贮的图片序列,只是在前面加上了一个 MIME 信息,其格式参考 http://blog.chinaunix.net/uid-22670933-id-1771591.html。里面没有视频的时间信息,也就没有帧速率的信息,所以,有些东西就需要自己做一些工作来处理,保证转码成 H.264 的 MP4 视频没有“被加速”。
首先,我们要在录制视频时,做一个简单的计数,记录视频录制的时间和录制的总帧数(可以在OnGetImage事件里计数,每帧都会触发它一次),然后根据它计算出一个平均的帧速率(总帧数/总时间)。
然后,然后调用 FFMPEG 的命令行参数进行转码,或者是直接调用相应的动态链接库转码,本人较懒,所以用命令行参数来调用,使用了 TDOSCommand 这个组件。这个组件要在 Delphi 10 等版本中使用的话,需要简单做一点点修改,[0..MaxInt] of Char 改为 [0..0] of Char 就可以了,剩下的都不需要变动。
下面是一段具体的转换实现代码,供大家参考:
var
ADosCmd: TDosCommand;
AUsedTime: Cardinal;
AFrameRate: Integer;
begin
AUsedTime := GetTickCount - FCaptureStartTime;
AFrameRate := FCapturedFrames * 1000 div AUsedTime;
DeleteFile(TempFileName + '.mp4');
ADosCmd := TDosCommand.Create(nil);
ADosCmd.CommandLine := 'ffmpeg -framerate ' + IntToStr(AFrameRate) + ' -i ' +
ExtractFileName(TempFileName + '.mjpeg') + ' -vcodec h264 ' +
ExtractFileName(TempFileName + '.mp4');
ADosCmd.ShowWindow := swHide;
ADosCmd.Execute;
while ADosCmd.Active do
begin
Sleep(50);
Application.ProcessMessages;
end;
FreeAndNil(ADosCmd);
DeleteFile(TempFileName+'.mjpeg');
end;
