[FFMPEG] 使用 FFMPEG 将 MJPEG 格式转换为 H.264 格式的 MP4

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

 

分享到: