简体   繁体   English

从 Android 上的相机录制视频到 mp4

[英]Record video from camera on Android to mp4

There seems to be TVideoCaptureDevice in FireMonkey (Delphi XE6), but on official documentation, capturing process ends up on lines: FireMonkey (Delphi XE6) 中似乎有TVideoCaptureDevice ,但在官方文档中,捕获过程以行结束:

if(VideoCamera){
  //do something
}

What do I do to record video to mp4 on flight?在飞行中如何将视频录制到 mp4? Tried looking on google, but didn't find any answer...尝试在谷歌上查找,但没有找到任何答案...

See the following docwiki for an answer (sort-of).请参阅以下 docwiki 以获取答案(排序)。

Delphi Video Capturing in XE7 XE7 中的 Delphi 视频捕获

Of course the word "capturing" here means, getting the video input and putting it on the display.当然,这里的“捕获”一词的意思是,获取视频输入并将其放在显示器上。 "Recording" means joining the frames together to make a movie file. “录制”意味着将帧连接在一起以制作电影文件。

The following code was kindly provided to me by the people at以下代码是由人们提供给我的

flashavconverter and is posted here with their approval: 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;

end;结尾;

This code is a (near) complete answer to the question.此代码是该问题的(接近)完整答案。 The device-specific video recorder UI is launched for the user to interact with.启动设备特定的录像机 UI 以供用户交互。 There is no programmatic control other than the name of the file that the recording is saved to.除了保存记录的文件的名称之外,没有任何程序控制。 As a Delphi developer who is overwhelmed by the Android API, I am grateful for this solution.作为一个被 Android API 压得喘不过气来的 Delphi 开发者,我很感激这个解决方案。

Here is how it is done on Android using native API:以下是使用原生 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;

File will be recorded, just don't forget to send recorder.stop() when you wish to stop recording.文件将被录制,当您希望停止录制时不要忘记发送recorder.stop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM