Compare commits
No commits in common. "0e05fc314fb759ec0944bf09c07aba9ad753fc2b" and "009838db7523d6a7ee48c8c194b3d4daac50350d" have entirely different histories.
0e05fc314f
...
009838db75
@ -11,7 +11,6 @@ import com.mrousavy.camera.core.CodeScannerFrame
|
|||||||
import com.mrousavy.camera.core.UnknownCameraError
|
import com.mrousavy.camera.core.UnknownCameraError
|
||||||
import com.mrousavy.camera.core.code
|
import com.mrousavy.camera.core.code
|
||||||
import com.mrousavy.camera.types.CodeType
|
import com.mrousavy.camera.types.CodeType
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
fun CameraView.invokeOnInitialized() {
|
fun CameraView.invokeOnInitialized() {
|
||||||
Log.i(CameraView.TAG, "invokeOnInitialized()")
|
Log.i(CameraView.TAG, "invokeOnInitialized()")
|
||||||
@ -34,15 +33,6 @@ fun CameraView.invokeOnStopped() {
|
|||||||
reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(id, "cameraStopped", null)
|
reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(id, "cameraStopped", null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CameraView.invokeOnChunkReady(filepath: File, index: Int) {
|
|
||||||
Log.e(CameraView.TAG, "invokeOnError(...):")
|
|
||||||
val event = Arguments.createMap()
|
|
||||||
event.putInt("index", index)
|
|
||||||
event.putString("filepath", filepath.toString())
|
|
||||||
val reactContext = context as ReactContext
|
|
||||||
reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(id, "onVideoChunkReady", event)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun CameraView.invokeOnError(error: Throwable) {
|
fun CameraView.invokeOnError(error: Throwable) {
|
||||||
Log.e(CameraView.TAG, "invokeOnError(...):")
|
Log.e(CameraView.TAG, "invokeOnError(...):")
|
||||||
error.printStackTrace()
|
error.printStackTrace()
|
||||||
|
@ -25,7 +25,6 @@ import com.mrousavy.camera.types.Torch
|
|||||||
import com.mrousavy.camera.types.VideoStabilizationMode
|
import com.mrousavy.camera.types.VideoStabilizationMode
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// TODOs for the CameraView which are currently too hard to implement either because of CameraX' limitations, or my brain capacity.
|
// TODOs for the CameraView which are currently too hard to implement either because of CameraX' limitations, or my brain capacity.
|
||||||
@ -266,10 +265,6 @@ class CameraView(context: Context) :
|
|||||||
invokeOnStopped()
|
invokeOnStopped()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onVideoChunkReady(filepath: File, index: Int) {
|
|
||||||
invokeOnChunkReady(filepath, index)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCodeScanned(codes: List<Barcode>, scannerFrame: CodeScannerFrame) {
|
override fun onCodeScanned(codes: List<Barcode>, scannerFrame: CodeScannerFrame) {
|
||||||
invokeOnCodeScanned(codes, scannerFrame)
|
invokeOnCodeScanned(codes, scannerFrame)
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ class CameraViewManager : ViewGroupManager<CameraView>() {
|
|||||||
.put("cameraStopped", MapBuilder.of("registrationName", "onStopped"))
|
.put("cameraStopped", MapBuilder.of("registrationName", "onStopped"))
|
||||||
.put("cameraError", MapBuilder.of("registrationName", "onError"))
|
.put("cameraError", MapBuilder.of("registrationName", "onError"))
|
||||||
.put("cameraCodeScanned", MapBuilder.of("registrationName", "onCodeScanned"))
|
.put("cameraCodeScanned", MapBuilder.of("registrationName", "onCodeScanned"))
|
||||||
.put("onVideoChunkReady", MapBuilder.of("registrationName", "onVideoChunkReady"))
|
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
override fun getName(): String = TAG
|
override fun getName(): String = TAG
|
||||||
|
@ -54,7 +54,6 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class CameraSession(private val context: Context, private val cameraManager: CameraManager, private val callback: Callback) :
|
class CameraSession(private val context: Context, private val cameraManager: CameraManager, private val callback: Callback) :
|
||||||
CameraManager.AvailabilityCallback(),
|
CameraManager.AvailabilityCallback(),
|
||||||
@ -641,8 +640,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
|
|||||||
orientation,
|
orientation,
|
||||||
options,
|
options,
|
||||||
callback,
|
callback,
|
||||||
onError,
|
onError
|
||||||
this.callback,
|
|
||||||
)
|
)
|
||||||
recording.start()
|
recording.start()
|
||||||
this.recording = recording
|
this.recording = recording
|
||||||
@ -726,7 +724,6 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
|
|||||||
fun onInitialized()
|
fun onInitialized()
|
||||||
fun onStarted()
|
fun onStarted()
|
||||||
fun onStopped()
|
fun onStopped()
|
||||||
fun onVideoChunkReady(filepath: File, index: Int)
|
|
||||||
fun onCodeScanned(codes: List<Barcode>, scannerFrame: CodeScannerFrame)
|
fun onCodeScanned(codes: List<Barcode>, scannerFrame: CodeScannerFrame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,12 @@ import com.mrousavy.camera.types.RecordVideoOptions
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
class ChunkedRecordingManager(private val encoder: MediaCodec, private val outputDirectory: File, private val orientationHint: Int, private val iFrameInterval: Int, private val callbacks: CameraSession.Callback) :
|
class ChunkedRecordingManager(private val encoder: MediaCodec, private val outputDirectory: File, private val orientationHint: Int, private val iFrameInterval: Int) :
|
||||||
MediaCodec.Callback() {
|
MediaCodec.Callback() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "ChunkedRecorder"
|
private const val TAG = "ChunkedRecorder"
|
||||||
|
|
||||||
fun fromParams(
|
fun fromParams(
|
||||||
callbacks: CameraSession.Callback,
|
|
||||||
size: Size,
|
size: Size,
|
||||||
enableAudio: Boolean,
|
enableAudio: Boolean,
|
||||||
fps: Int? = null,
|
fps: Int? = null,
|
||||||
@ -58,7 +57,7 @@ class ChunkedRecordingManager(private val encoder: MediaCodec, private val outpu
|
|||||||
// Create a MediaCodec encoder, and configure it with our format. Get a Surface
|
// Create a MediaCodec encoder, and configure it with our format. Get a Surface
|
||||||
// we can use for input and wrap it with a class that handles the EGL work.
|
// we can use for input and wrap it with a class that handles the EGL work.
|
||||||
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
|
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
|
||||||
return ChunkedRecordingManager(codec, outputDirectory, 0, iFrameInterval, callbacks)
|
return ChunkedRecordingManager(codec, outputDirectory, 0, iFrameInterval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +79,7 @@ class ChunkedRecordingManager(private val encoder: MediaCodec, private val outpu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Muxer specific
|
// Muxer specific
|
||||||
private class MuxerContext(val muxer: MediaMuxer, val filepath: File, val chunkIndex: Int, startTimeUs: Long, encodedFormat: MediaFormat) {
|
private class MuxerContext(val muxer: MediaMuxer, startTimeUs: Long, encodedFormat: MediaFormat) {
|
||||||
val videoTrack: Int = muxer.addTrack(encodedFormat)
|
val videoTrack: Int = muxer.addTrack(encodedFormat)
|
||||||
val startTimeUs: Long = startTimeUs
|
val startTimeUs: Long = startTimeUs
|
||||||
|
|
||||||
@ -98,10 +97,7 @@ class ChunkedRecordingManager(private val encoder: MediaCodec, private val outpu
|
|||||||
private var muxerContext: MuxerContext? = null
|
private var muxerContext: MuxerContext? = null
|
||||||
|
|
||||||
private fun createNextMuxer(bufferInfo: BufferInfo) {
|
private fun createNextMuxer(bufferInfo: BufferInfo) {
|
||||||
muxerContext?.let {
|
muxerContext?.finish()
|
||||||
it.finish()
|
|
||||||
this.callbacks.onVideoChunkReady(it.filepath, it.chunkIndex)
|
|
||||||
}
|
|
||||||
chunkIndex++
|
chunkIndex++
|
||||||
|
|
||||||
val newFileName = "$chunkIndex.mp4"
|
val newFileName = "$chunkIndex.mp4"
|
||||||
@ -113,7 +109,7 @@ class ChunkedRecordingManager(private val encoder: MediaCodec, private val outpu
|
|||||||
)
|
)
|
||||||
muxer.setOrientationHint(orientationHint)
|
muxer.setOrientationHint(orientationHint)
|
||||||
muxerContext = MuxerContext(
|
muxerContext = MuxerContext(
|
||||||
muxer, newOutputFile, chunkIndex, bufferInfo.presentationTimeUs, this.encodedFormat!!
|
muxer, bufferInfo.presentationTimeUs, this.encodedFormat!!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,7 @@ class RecordingSession(
|
|||||||
private val cameraOrientation: Orientation,
|
private val cameraOrientation: Orientation,
|
||||||
private val options: RecordVideoOptions,
|
private val options: RecordVideoOptions,
|
||||||
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,
|
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "RecordingSession"
|
private const val TAG = "RecordingSession"
|
||||||
@ -46,7 +45,6 @@ class RecordingSession(
|
|||||||
|
|
||||||
private val bitRate = getBitRate()
|
private val bitRate = getBitRate()
|
||||||
private val recorder = ChunkedRecordingManager.fromParams(
|
private val recorder = ChunkedRecordingManager.fromParams(
|
||||||
allCallbacks,
|
|
||||||
size,
|
size,
|
||||||
enableAudio,
|
enableAudio,
|
||||||
fps,
|
fps,
|
||||||
|
@ -26,10 +26,6 @@ interface OnErrorEvent {
|
|||||||
message: string
|
message: string
|
||||||
cause?: ErrorWithCause
|
cause?: ErrorWithCause
|
||||||
}
|
}
|
||||||
interface OnVideoChunkReadyEvent {
|
|
||||||
filepath: string
|
|
||||||
index: int
|
|
||||||
}
|
|
||||||
type NativeCameraViewProps = Omit<CameraProps, 'device' | 'onInitialized' | 'onError' | 'frameProcessor' | 'codeScanner'> & {
|
type NativeCameraViewProps = Omit<CameraProps, 'device' | 'onInitialized' | 'onError' | 'frameProcessor' | 'codeScanner'> & {
|
||||||
cameraId: string
|
cameraId: string
|
||||||
enableFrameProcessor: boolean
|
enableFrameProcessor: boolean
|
||||||
@ -39,7 +35,6 @@ type NativeCameraViewProps = Omit<CameraProps, 'device' | 'onInitialized' | 'onE
|
|||||||
onCodeScanned?: (event: NativeSyntheticEvent<OnCodeScannedEvent>) => void
|
onCodeScanned?: (event: NativeSyntheticEvent<OnCodeScannedEvent>) => void
|
||||||
onStarted?: (event: NativeSyntheticEvent<void>) => void
|
onStarted?: (event: NativeSyntheticEvent<void>) => void
|
||||||
onStopped?: (event: NativeSyntheticEvent<void>) => void
|
onStopped?: (event: NativeSyntheticEvent<void>) => void
|
||||||
onVideoChunkReady?: (event: NativeSyntheticEvent<OnVideoChunkReadyEvent>) => void
|
|
||||||
onViewReady: () => void
|
onViewReady: () => void
|
||||||
}
|
}
|
||||||
type NativeRecordVideoOptions = Omit<RecordVideoOptions, 'onRecordingError' | 'onRecordingFinished' | 'videoBitRate'> & {
|
type NativeRecordVideoOptions = Omit<RecordVideoOptions, 'onRecordingError' | 'onRecordingFinished' | 'videoBitRate'> & {
|
||||||
|
Loading…
Reference in New Issue
Block a user