wip: write to internal storage, pass videoId to RecordingSession, tested

This commit is contained in:
Loewy 2024-03-11 22:42:26 -07:00
parent 19bf300bbe
commit 6bf69be6c6
5 changed files with 421 additions and 416 deletions

View File

@ -13,7 +13,7 @@ import com.mrousavy.camera.types.RecordVideoOptions
import com.mrousavy.camera.utils.makeErrorMap import com.mrousavy.camera.utils.makeErrorMap
import java.util.* import java.util.*
suspend fun CameraView.startRecording(options: RecordVideoOptions, onRecordCallback: Callback) { suspend fun CameraView.startRecording(options: RecordVideoOptions, videoId: Int, onRecordCallback: Callback) {
// check audio permission // check audio permission
if (audio == true) { if (audio == true) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
@ -33,7 +33,7 @@ suspend fun CameraView.startRecording(options: RecordVideoOptions, onRecordCallb
val errorMap = makeErrorMap(error.code, error.message) val errorMap = makeErrorMap(error.code, error.message)
onRecordCallback(null, errorMap) onRecordCallback(null, errorMap)
} }
cameraSession.startRecording(audio == true, options, callback, onError) cameraSession.startRecording(audio == true, options, videoId, callback, onError)
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")

View File

@ -95,12 +95,12 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
// TODO: startRecording() cannot be awaited, because I can't have a Promise and a onRecordedCallback in the same function. Hopefully TurboModules allows that // TODO: startRecording() cannot be awaited, because I can't have a Promise and a onRecordedCallback in the same function. Hopefully TurboModules allows that
@ReactMethod @ReactMethod
fun startRecording(viewTag: Int, jsOptions: ReadableMap, onRecordCallback: Callback) { fun startRecording(viewTag: Int, jsOptions: ReadableMap, videoId: Int, onRecordCallback: Callback) {
coroutineScope.launch { coroutineScope.launch {
val view = findCameraView(viewTag) val view = findCameraView(viewTag)
try { try {
val options = RecordVideoOptions(jsOptions) val options = RecordVideoOptions(jsOptions)
view.startRecording(options, onRecordCallback) view.startRecording(options, videoId, onRecordCallback)
} catch (error: CameraError) { } catch (error: CameraError) {
val map = makeErrorMap("${error.domain}/${error.id}", error.message, error) val map = makeErrorMap("${error.domain}/${error.id}", error.message, error)
onRecordCallback(null, map) onRecordCallback(null, map)

View File

@ -621,6 +621,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
suspend fun startRecording( suspend fun startRecording(
enableAudio: Boolean, enableAudio: Boolean,
options: RecordVideoOptions, options: RecordVideoOptions,
videoId: Int,
callback: (video: RecordingSession.Video) -> Unit, callback: (video: RecordingSession.Video) -> Unit,
onError: (error: CameraError) -> Unit onError: (error: CameraError) -> Unit
) { ) {
@ -640,6 +641,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
videoOutput.enableHdr, videoOutput.enableHdr,
orientation, orientation,
options, options,
videoId,
callback, callback,
onError, onError,
this.callback, this.callback,

View File

@ -23,6 +23,7 @@ class RecordingSession(
private val hdr: Boolean = false, private val hdr: Boolean = false,
private val cameraOrientation: Orientation, private val cameraOrientation: Orientation,
private val options: RecordVideoOptions, private val options: RecordVideoOptions,
private val videoId: Int,
private val callback: (video: Video) -> Unit, private val callback: (video: Video) -> Unit,
private val onError: (error: CameraError) -> Unit, private val onError: (error: CameraError) -> Unit,
private val allCallbacks: CameraSession.Callback, private val allCallbacks: CameraSession.Callback,
@ -38,10 +39,12 @@ class RecordingSession(
data class Video(val path: String, val durationMs: Long, val size: Size) data class Video(val path: String, val durationMs: Long, val size: Size)
private val outputPath = run { private val outputPath = run {
val videoDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) val videoDir = context.filesDir
val fileExtension = options.fileType.toExtension()
val sdf = SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS", Locale.US) val sdf = SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS", Locale.US)
val videoFileName = "VID_${sdf.format(Date())}" val videoFileName = "VID_${videoId}_${sdf.format(Date())}.$fileExtension"
File(videoDir!!, videoFileName) val outputFile = File(videoDir, videoFileName)
outputFile
} }
private val bitRate = getBitRate() private val bitRate = getBitRate()

View File

@ -173,7 +173,7 @@ export class Camera extends React.PureComponent<CameraProps, CameraState> {
* }, 5000) * }, 5000)
* ``` * ```
*/ */
public startRecording(options: RecordVideoOptions): void { public startRecording(options: RecordVideoOptions, videoId: number): void {
const { onRecordingError, onRecordingFinished, videoBitRate, ...passThruOptions } = options const { onRecordingError, onRecordingFinished, videoBitRate, ...passThruOptions } = options
if (typeof onRecordingError !== 'function' || typeof onRecordingFinished !== 'function') if (typeof onRecordingError !== 'function' || typeof onRecordingFinished !== 'function')
throw new CameraRuntimeError('parameter/invalid-parameter', 'The onRecordingError or onRecordingFinished functions were not set!') throw new CameraRuntimeError('parameter/invalid-parameter', 'The onRecordingError or onRecordingFinished functions were not set!')
@ -207,7 +207,7 @@ export class Camera extends React.PureComponent<CameraProps, CameraState> {
} }
try { try {
// TODO: Use TurboModules to make this awaitable. // TODO: Use TurboModules to make this awaitable.
CameraModule.startRecording(this.handle, nativeOptions, onRecordCallback) CameraModule.startRecording(this.handle, nativeOptions, videoId, onRecordCallback)
} catch (e) { } catch (e) {
throw tryParseNativeCameraError(e) throw tryParseNativeCameraError(e)
} }