There seems to be TVideoCaptureDevice
in FireMonkey (Delphi XE6), but on official documentation, capturing process ends up on lines:
if(VideoCamera){
//do something
}
What do I do to record video to mp4 on flight? Tried looking on google, but didn't find any answer...
See the following docwiki for an answer (sort-of).
Delphi Video Capturing in XE7
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:
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. 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.
Here is how it is done on Android using native API:
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.