这几天,用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;