从Android上的摄像头录制视频到mp4

时间:2014-05-23 20:32:29

标签: android delphi camera firemonkey mpeg

FireMonkey(Delphi XE6)中似乎有TVideoCaptureDevice,但在官方文档中,捕获过程终止于行:

if(VideoCamera){
  //do something
}

如何在飞行中将视频录制到mp4?尝试在谷歌上看,但没有找到任何答案......

2 个答案:

答案 0 :(得分:6)

请参阅以下docwiki以获取答案(sort-of)。

Delphi Video Capturing in XE7

当然,这里的“捕获”一词意味着,获取视频输入并将其放在显示器上。 “录制”是指将帧连接在一起以制作电影文件。

以下代码由

的人员提供给我

flashavconverter并在此处发布并获得批准:

uses
  Androidapi.JNI.GraphicsContentViewText;

const
  RECORD_VIDEO = 9;

implementation

uses 
  System.IOUtils,
  Androidapi.JNI.Provider,
  Androidapi.JNI.App,
  Androidapi.JNI.Net,
  Androidapi.JNIBridge,
  Androidapi.Helpers,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.Os;

{$R *.fmx}

procedure TFormMain.btnRecordClick(Sender: TObject);
var
  VideoIntent: JIntent;
  videoUri: Jnet_Uri;
  AFile: JFile;
  FileName: TFileName;
begin
  FMessageSubscriptionID := 
    TMessageManager.DefaultManager.SubscribeToMessage(
      TMessageResultNotification, HandleActivityMessage);
  VideoIntent := 
    TJIntent.JavaClass.init(
      TJMediaStore.JavaClass.ACTION_VIDEO_CAPTURE
    );
  if (
    VideoIntent.resolveActivity(
      SharedActivityContext.getPackageManager()
    ) <> nil) then
  begin
    FileName := TPath.Combined(
      TPath.GetSharedDocumentsPath, 'recording.mp4')
    AFile:=TJFile.JavaClass.init(
      StringToJString(FileName));
    videoUri:=TJnet_Uri.JavaClass.fromFile(AFile);
    VideoIntent.putExtra(
      TJMediaStore.JavaClass.EXTRA_OUTPUT, 
      TJParcelable.Wrap((videoUri as ILocalObject).GetObjectID));
    SharedActivity.startActivityForResult(VideoIntent, RECORD_VIDEO);
  end;
end;

procedure TFormMain.HandleActivityMessage(const Sender: TObject;
  const M: TMessage);
begin
  if M is TMessageResultNotification then
    OnActivityResult(
      TMessageResultNotification(M).RequestCode,
      TMessageResultNotification(M).ResultCode,
      TMessageResultNotification(M).Value);
end;

function TFormMain.OnActivityResult(RequestCode, ResultCode: Integer;
  Data: JIntent): Boolean;
begin
  Result := False;

  TMessageManager.DefaultManager.Unsubscribe(
    TMessageResultNotification, FMessageSubscriptionID);
  FMessageSubscriptionID := 0;

  if RequestCode = RECORD_VIDEO then
  begin
    if ResultCode = TJActivity.JavaClass.RESULT_OK then
    begin
      TThread.Queue(nil, procedure
      begin
        lable1.Text:='recording completed';
        Invalidate;
      end);
    end;
  end;

端;

此代码是(近乎)完整的答案。启动特定于设备的视频记录器UI以供用户与之交互。除了保存录制文件的名称之外,没有编程控制。作为一个被Android API淹没的Delphi开发人员,我很感激这个解决方案。

答案 1 :(得分:1)

以下是使用原生API在Android上完成的工作方式:

var
    texture : JSurfaceTexture;
    surface: JSurface;
    recorder: JMediaRecorder;
begin
  texture := TJSurfaceTexture.JavaClass.init(1);
  surface := TJSurface.JavaClass.init(texture); 
  recorder := TJMediaRecorder.Create();

  recorder.setPreviewDisplay(surface);
  recorder.setAudioSource(AUDIO_MIC);
  recorder.setVideoSource(VIDEO_CAMERA);
  recorder.setOutputFormat(FORMAT_THREE_GPP);
  recorder.setAudioEncoder(AFORMAT_AMR_NB);
  recorder.setVideoEncoder(VFORMAT_MPEG_4_SP);
  recorder.setMaxDuration(1800000); // 30 minutes

  recorder.setVideoSize(320, 240);
  recorder.setVideoFrameRate(15);
  recorder.setOutputFile(StringToJString(TPath.GetSharedCameraPath + OUTPUT_FILE));

  recorder.prepare();
  recorder.start();
end;

文件将被记录,当您希望停止录制时,不要忘记发送recorder.stop()