Here is the example of SlowMo video capture using Camera2 API and CamEX2 class. This is the code for recording slow-motion video which you can find at the bottom of CamEX2 Class of attached example,
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
Usage:
Note: This is not a complete camera example but just a tutorial of the above functions. So the preview panel may look stretched but the recorded video file will not.
			
			
			
				B4X:
			
		
		
		#Region HighSpeed/SlowMo
Public Sub getHighSpeedVideoSizesAndFPS As List
    Dim scMap As JavaObject = GetFromCameraCharacteristic("SCALER_STREAM_CONFIGURATION_MAP")
    Dim sizelist() As Object = scMap.RunMethod("getHighSpeedVideoSizes",Null)
    Dim FPSRanges() As Object
    Dim vList As List
    vList.Initialize
    For Each size As JavaObject In sizelist
        FPSRanges = scMap.RunMethodJO("getHighSpeedVideoFpsRangesFor",Array(size))
        Dim fpsVal As Int
        Dim fpsR As Object
        For Each fps As JavaObject In FPSRanges
            fpsVal = fps.RunMethod("getUpper",Null)
            fpsR = fps
        Next
        vList.Add(CreateMap("sizeObject":size, "FPSRange":fpsR, "FPS":fpsVal, "quality":size.RunMethod("getHeight",Null)&"p"))
    Next
    Return vList
End Sub
'Prepares the surface for high speed video capture.
'Need to add this line to the manifest editor:
'AddPermission(android.permission.RECORD_AUDIO)
Public Sub PrepareSurfaceForHighSpeedVideo (MyTaskIndex As Int, Dir As String, FileName As String, FPS As Int, Size As Object) As ResumableSub
    If getHighSpeedVideoSizesAndFPS.Size > 0 Then
        HighSpeedVideo = False
        If MyTaskIndex <> TaskIndex Then Return False
        CloseSession
        Wait For (CreateSurface) Complete (Result As Boolean)
        If MyTaskIndex <> TaskIndex Then Return False
        File.Delete(Dir, FileName)
        MediaRecorder = Camera.CreateMediaRecorder(PreviewSize, Dir, FileName)
        MediaRecorder.RunMethod("setOrientationHint", Array(GetHintOrientation))
        MediaRecorder.RunMethod("setVideoFrameRate", Array(30))
        Dim dFps As Double = FPS
        MediaRecorder.RunMethod("setCaptureRate", Array(dFps))
        Dim ii As Int = (FPS/30)*1000000
        MediaRecorder.RunMethod("setVideoEncodingBitRate", Array(ii))
     
        Dim jo As JavaObject = Me
        jo.RunMethod("StartHighSpeedSession",Array(Camera,tv, Size))
        Wait For Camera_SessionConfigured (Success As Boolean)
        If MyTaskIndex <> TaskIndex Then Return False
        HighSpeedVideo = True
        Return Success
    Else
        Return False
    End If
End Sub
#End Region
#if Java
import android.view.TextureView;
import android.view.Surface;
import android.util.Size;
import android.util.Log;
import android.util.Range;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession;
import android.media.MediaCodec;
import android.os.Handler;
public void StartHighSpeedSession(final anywheresoftware.b4a.objects.Camera2 _cam,final TextureView Surface, final Size PreviewSize) throws CameraAccessException, IllegalStateException, IOException {
     
    final ArrayList<Surface> targets = new ArrayList<Surface>();
    if (Surface != null) {
        _cam.previewSurface = new Surface(Surface.getSurfaceTexture());
        Surface.getSurfaceTexture().setDefaultBufferSize(PreviewSize.getWidth(), PreviewSize.getHeight());
        targets.add(_cam.previewSurface);
    }
  
    _cam.persistentSurface = MediaCodec.createPersistentInputSurface();
    _cam.mediaRecorder.setInputSurface(_cam.persistentSurface);
    _cam.mediaRecorder.prepare();
    targets.add(_cam.persistentSurface);
  
    _cam.cameraDevice.createConstrainedHighSpeedCaptureSession((java.util.List)targets, (CameraCaptureSession.StateCallback)new CameraCaptureSession.StateCallback() {
        public void onConfigureFailed(final CameraCaptureSession session) {
            ba.raiseEventFromUI(null, "camera_sessionconfigured", new Object[] { false });
        }
     
        public void onConfigured(final CameraCaptureSession session) {
            _cam.captureSession = session;
            ba.raiseEventFromUI(null, "camera_sessionconfigured", new Object[] { true });
        }
     
        public void onClosed(final CameraCaptureSession session) {
            if (_cam.captureSession != null && _cam.captureSession.equals(session)) {
                _cam.captureSession = null;
            }
        }
    }, (Handler)null);
}
public Object SetRepeatingBurst(final anywheresoftware.b4a.objects.Camera2 _cam,final Object Builder, final Range<Integer> fpsRange) throws CameraAccessException {
    final CaptureRequest.Builder builder = ((CaptureRequest.Builder)Builder);
    final CaptureRequest req = builder.build();
  
    CameraConstrainedHighSpeedCaptureSession mPreviewSessionHighSpeed = (CameraConstrainedHighSpeedCaptureSession) _cam.captureSession;
  
    List<CaptureRequest> mPreviewBuilderBurst = mPreviewSessionHighSpeed.createHighSpeedRequestList(req);
    mPreviewSessionHighSpeed.setRepeatingBurst(mPreviewBuilderBurst, null, (Handler)null);
    return req;
}
#End IfUsage:
- Check if the device supports High FPS video recording using getHighSpeedVideoSizesAndFPS.- This will return a list of High FPS profile.
- Each Profile will contain a capture size, fps range, max fps of that profile and a quality string (eg. 720p) for information
- If the list size is ZERO then the device does not support High FPS recording
 
- Initialize Camera Preview (check example attached line 84, 85)
- At last call, PrepareSurfaceForHighSpeedVideo to prepare the hardware to High FPS mode. (check example attached line 87)
- Now you can call StartVideoRecording and StopVideoRecording to record a slow-motion video.
Note: This is not a complete camera example but just a tutorial of the above functions. So the preview panel may look stretched but the recorded video file will not.
Attachments
			
				Last edited: 
			
		
	
							 
				 
 
		 
 
		 
 
		 
 
		 
 
		 
 
		 
 
		