-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add custom
path
for takePhoto
/takeSnapshot
/`startRecordin…
…g` (#3103) * feat: Add custom `path` for `takePhoto`/`takeSnapshot`/`startRecording` * feat: Implement custom `path` for iOS * chore: Parse strongly typed * Update Flash.swift * feat: Add `path` for `takePhoto` on Android * feat: Throw error if flash is not available on iOS * feat: Support `path` for `takeSnapshot` on Android * feat: Support `path` for `startRecording` on Android * fix: Move logic into `OutputFile` to allow deletion if it is a temp file * fix: Make file URL parsing more solid * fix: Fix video file type * Update MediaPage.tsx * fix: Don't look for directories
- Loading branch information
Showing
30 changed files
with
384 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 15 additions & 17 deletions
32
package/android/src/main/java/com/mrousavy/camera/core/CameraSession+Photo.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,45 @@ | ||
package com.mrousavy.camera.core | ||
|
||
import android.media.AudioManager | ||
import android.util.Log | ||
import com.mrousavy.camera.core.extensions.takePicture | ||
import com.mrousavy.camera.core.types.Flash | ||
import com.mrousavy.camera.core.types.Orientation | ||
import com.mrousavy.camera.core.types.TakePhotoOptions | ||
import com.mrousavy.camera.core.utils.FileUtils | ||
|
||
suspend fun CameraSession.takePhoto(flash: Flash, enableShutterSound: Boolean): Photo { | ||
suspend fun CameraSession.takePhoto(options: TakePhotoOptions): Photo { | ||
val camera = camera ?: throw CameraNotReadyError() | ||
val configuration = configuration ?: throw CameraNotReadyError() | ||
val photoConfig = configuration.photo as? CameraConfiguration.Output.Enabled<CameraConfiguration.Photo> ?: throw PhotoNotEnabledError() | ||
val photoOutput = photoOutput ?: throw PhotoNotEnabledError() | ||
|
||
if (flash != Flash.OFF && !camera.cameraInfo.hasFlashUnit()) { | ||
// Flash | ||
if (options.flash != Flash.OFF && !camera.cameraInfo.hasFlashUnit()) { | ||
throw FlashUnavailableError() | ||
} | ||
|
||
photoOutput.flashMode = flash.toFlashMode() | ||
val enableShutterSoundActual = getEnableShutterSoundActual(enableShutterSound) | ||
|
||
photoOutput.flashMode = options.flash.toFlashMode() | ||
// Shutter sound | ||
val enableShutterSound = options.enableShutterSound && !audioManager.isSilent | ||
// isMirrored (EXIF) | ||
val isMirrored = photoConfig.config.isMirrored | ||
|
||
// Shoot photo! | ||
val photoFile = photoOutput.takePicture( | ||
context, | ||
options.file.file, | ||
isMirrored, | ||
enableShutterSoundActual, | ||
enableShutterSound, | ||
metadataProvider, | ||
callback, | ||
CameraQueues.cameraExecutor | ||
) | ||
|
||
// Parse resulting photo (EXIF data) | ||
val size = FileUtils.getImageSize(photoFile.uri.path) | ||
val rotation = photoOutput.targetRotation | ||
val orientation = Orientation.fromSurfaceRotation(rotation) | ||
|
||
return Photo(photoFile.uri.path, size.width, size.height, orientation, isMirrored) | ||
} | ||
|
||
private fun CameraSession.getEnableShutterSoundActual(enable: Boolean): Boolean { | ||
if (enable && audioManager.ringerMode != AudioManager.RINGER_MODE_NORMAL) { | ||
Log.i(CameraSession.TAG, "Ringer mode is silent (${audioManager.ringerMode}), disabling shutter sound...") | ||
return false | ||
} | ||
|
||
return enable | ||
} | ||
private val AudioManager.isSilent: Boolean | ||
get() = ringerMode != AudioManager.RINGER_MODE_NORMAL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 19 additions & 17 deletions
36
package/android/src/main/java/com/mrousavy/camera/core/types/RecordVideoOptions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,27 @@ | ||
package com.mrousavy.camera.core.types | ||
|
||
import android.content.Context | ||
import com.facebook.react.bridge.ReadableMap | ||
import com.mrousavy.camera.core.utils.FileUtils | ||
import com.mrousavy.camera.core.utils.OutputFile | ||
|
||
class RecordVideoOptions(map: ReadableMap) { | ||
var fileType: VideoFileType = VideoFileType.MOV | ||
var videoCodec = VideoCodec.H264 | ||
var videoBitRateOverride: Double? = null | ||
var videoBitRateMultiplier: Double? = null | ||
class RecordVideoOptions( | ||
val file: OutputFile, | ||
val videoCodec: VideoCodec, | ||
val videoBitRateOverride: Double?, | ||
val videoBitRateMultiplier: Double? | ||
) { | ||
|
||
init { | ||
if (map.hasKey("fileType")) { | ||
fileType = VideoFileType.fromUnionValue(map.getString("fileType")) | ||
} | ||
if (map.hasKey("videoCodec")) { | ||
videoCodec = VideoCodec.fromUnionValue(map.getString("videoCodec")) | ||
} | ||
if (map.hasKey("videoBitRateOverride")) { | ||
videoBitRateOverride = map.getDouble("videoBitRateOverride") | ||
} | ||
if (map.hasKey("videoBitRateMultiplier")) { | ||
videoBitRateMultiplier = map.getDouble("videoBitRateMultiplier") | ||
companion object { | ||
fun fromJSValue(context: Context, map: ReadableMap): RecordVideoOptions { | ||
val directory = if (map.hasKey("path")) FileUtils.getDirectory(map.getString("path")) else context.cacheDir | ||
val fileType = if (map.hasKey("fileType")) VideoFileType.fromUnionValue(map.getString("fileType")) else VideoFileType.MOV | ||
val videoCodec = if (map.hasKey("videoCodec")) VideoCodec.fromUnionValue(map.getString("videoCodec")) else VideoCodec.H264 | ||
val videoBitRateOverride = if (map.hasKey("videoBitRateOverride")) map.getDouble("videoBitRateOverride") else null | ||
val videoBitRateMultiplier = if (map.hasKey("videoBitRateMultiplier")) map.getDouble("videoBitRateMultiplier") else null | ||
val outputFile = OutputFile(context, directory, fileType.toExtension()) | ||
return RecordVideoOptions(outputFile, videoCodec, videoBitRateOverride, videoBitRateMultiplier) | ||
} | ||
} | ||
} |
12 changes: 0 additions & 12 deletions
12
package/android/src/main/java/com/mrousavy/camera/core/types/SnapshotOptions.kt
This file was deleted.
Oops, something went wrong.
20 changes: 20 additions & 0 deletions
20
package/android/src/main/java/com/mrousavy/camera/core/types/TakePhotoOptions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.mrousavy.camera.core.types | ||
|
||
import android.content.Context | ||
import com.facebook.react.bridge.ReadableMap | ||
import com.mrousavy.camera.core.utils.FileUtils | ||
import com.mrousavy.camera.core.utils.OutputFile | ||
|
||
data class TakePhotoOptions(val file: OutputFile, val flash: Flash, val enableShutterSound: Boolean) { | ||
|
||
companion object { | ||
fun fromJS(context: Context, map: ReadableMap): TakePhotoOptions { | ||
val flash = if (map.hasKey("flash")) Flash.fromUnionValue(map.getString("flash")) else Flash.OFF | ||
val enableShutterSound = if (map.hasKey("enableShutterSound")) map.getBoolean("enableShutterSound") else false | ||
val directory = if (map.hasKey("path")) FileUtils.getDirectory(map.getString("path")) else context.cacheDir | ||
|
||
val outputFile = OutputFile(context, directory, ".jpg") | ||
return TakePhotoOptions(outputFile, flash, enableShutterSound) | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
package/android/src/main/java/com/mrousavy/camera/core/types/TakeSnapshotOptions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.mrousavy.camera.core.types | ||
|
||
import android.content.Context | ||
import com.facebook.react.bridge.ReadableMap | ||
import com.mrousavy.camera.core.utils.FileUtils | ||
import com.mrousavy.camera.core.utils.OutputFile | ||
|
||
data class TakeSnapshotOptions(val file: OutputFile, val quality: Int) { | ||
|
||
companion object { | ||
fun fromJSValue(context: Context, map: ReadableMap): TakeSnapshotOptions { | ||
val quality = if (map.hasKey("quality")) map.getInt("quality") else 100 | ||
val directory = if (map.hasKey("path")) FileUtils.getDirectory(map.getString("path")) else context.cacheDir | ||
|
||
val outputFile = OutputFile(context, directory, ".jpg") | ||
return TakeSnapshotOptions(outputFile, quality) | ||
} | ||
} | ||
} |
14 changes: 10 additions & 4 deletions
14
package/android/src/main/java/com/mrousavy/camera/core/utils/FileUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
package/android/src/main/java/com/mrousavy/camera/core/utils/OutputFile.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.mrousavy.camera.core.utils | ||
|
||
import android.content.Context | ||
import java.io.File | ||
|
||
data class OutputFile(val context: Context, val directory: File, val extension: String) { | ||
val file = File.createTempFile("mrousavy", extension, directory) | ||
|
||
init { | ||
if (directory.absolutePath.contains(context.cacheDir.absolutePath)) { | ||
// If this is a temp file (inside temp directory), the file will be deleted once the app closes | ||
file.deleteOnExit() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.