Skip to content

Commit 46240f1

Browse files
authored
fix: Return file paths from recorders instead of URL (#3894)
* fix: return file paths from recorders * docs: clarify VisionCamera file paths
1 parent 6cbe3c7 commit 46240f1

11 files changed

Lines changed: 26 additions & 10 deletions

File tree

docs/content/docs/a-photo.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ const photo = ...
5353
const path = await photo.saveToTemporaryFileAsync()
5454
```
5555

56+
Photo file paths are plain filesystem paths, not `file://` URLs. If another library expects a URI, prepend `file://` at the call site.
57+
5658
#### Saving to the Camera Roll
5759

5860
After a [`Photo`](/api/react-native-vision-camera/hybrid-objects/Photo) has been saved to a file, you can save it to the user's Camera Roll using a library like [@react-native-camera-roll/camera-roll](https://github.com/react-native-cameraroll/react-native-cameraroll) or [expo-media-library](https://docs.expo.dev/versions/latest/sdk/media-library/).

docs/content/docs/photo-output.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,6 @@ const { filePath } = await photoOutput.capturePhotoToFile(
100100
)
101101
```
102102

103+
`filePath` is a plain filesystem path, not a `file://` URL. If another library expects a URI, prepend `file://` at the call site.
104+
103105
See [`CapturePhotoSettings`](/api/react-native-vision-camera/interfaces/CapturePhotoSettings) for a full list of configuration options, and [`CapturePhotoCallbacks`](/api/react-native-vision-camera/interfaces/CapturePhotoCallbacks) for a full list of callbacks for the capture method.

docs/content/docs/recorder.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ const interval = setInterval(() => {
5757
5858
The [`Recorder`](/api/react-native-vision-camera/hybrid-objects/Recorder) also exposes metadata about its state - like [`isRecording`](/api/react-native-vision-camera/hybrid-objects/Recorder#isrecording), [`isPaused`](/api/react-native-vision-camera/hybrid-objects/Recorder#ispaused) and [`filePath`](/api/react-native-vision-camera/hybrid-objects/Recorder#filepath).
5959
60+
`filePath` and the value passed to `onRecordingFinished` are plain filesystem paths instead of `file://` URLs; if another library expects a URI, prepend `file://` at the call site.
61+
6062
### Pausing/Resuming
6163

6264
To pause/resume Video Recordings, use [`Recorder.pauseRecording()`](/api/react-native-vision-camera/hybrid-objects/Recorder#pauserecording)/[`Recorder.resumeRecording()`](/api/react-native-vision-camera/hybrid-objects/Recorder#resumerecording), which also fires the `onRecordingPaused`/`onRecordingResumed` callbacks previously passed to the [`Recorder.startRecording(...)`](/api/react-native-vision-camera/hybrid-objects/Recorder#startrecording) function:

packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/recording/HybridVideoRecorder.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ class HybridVideoRecorder(
8181
}
8282
if (finishReason != null) {
8383
// Recording finished successfully - either no error, or file/duration limit reached:
84-
val outputUri = event.outputResults.outputUri
85-
onRecordingFinished(outputUri.toString(), finishReason)
84+
onRecordingFinished(file.absolutePath, finishReason)
8685
} else {
8786
// We have an error, either during capture or even while starting:
8887
val error = VideoRecorderError(event.error, event.cause)

packages/react-native-vision-camera/ios/Hybrid Objects/Image Types/HybridPhoto.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ final class HybridPhoto: HybridPhotoSpec, NativePhoto {
111111
guard let data = photo.fileDataRepresentation() else {
112112
throw RuntimeError.error(withMessage: "Failed to get file data representation of Photo!")
113113
}
114-
guard let url = URL(string: path) else {
115-
throw RuntimeError.error(withMessage: "The given path \"\(path)\" is not a valid URL!")
116-
}
114+
let url = URL(fileURLWithPath: path)
117115
try data.write(to: url)
118116
}
119117

@@ -128,7 +126,7 @@ final class HybridPhoto: HybridPhotoSpec, NativePhoto {
128126
// 1. Create temp path
129127
let fileType = try self.containerFormat.toUTType()
130128
let file = try URL.createTempURL(fileType: fileType)
131-
let path = file.absoluteString
129+
let path = file.path
132130
// 2. Save image
133131
try self.saveImage(to: path)
134132
// 3. Return path

packages/react-native-vision-camera/ios/Hybrid Objects/Recording/HybridFrameRecorder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ final class HybridFrameRecorder: HybridRecorderSpec {
8888
}
8989

9090
var filePath: String {
91-
return fileURL.absoluteString
91+
return fileURL.path
9292
}
9393

9494
func initializeVideoTrack(withSettings settings: [String: Any]) throws {

packages/react-native-vision-camera/ios/Hybrid Objects/Recording/HybridVideoRecorder.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ final class HybridVideoRecorder: HybridRecorderSpec {
5353
return Double(videoOutput.recordedFileSize)
5454
}
5555
var filePath: String {
56-
return fileURL.absoluteString
56+
return fileURL.path
5757
}
5858

5959
func startRecording(
@@ -96,7 +96,7 @@ final class HybridVideoRecorder: HybridRecorderSpec {
9696
return
9797
}
9898
// Recording finished!
99-
onRecordingFinished(url.absoluteString, reason)
99+
onRecordingFinished(url.path, reason)
100100
},
101101
onRecordingError: { error in
102102
if !isResolved {

packages/react-native-vision-camera/src/specs/instances/Photo.nitro.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,15 @@ export interface Photo
154154
* Must contain a full path name including filename
155155
* and extension. All parent directories must exist,
156156
* but the file itself must not exist.
157+
* This must be a filesystem path, not a `file://` URL.
157158
*/
158159
saveToFileAsync(path: string): Promise<void>
159160
/**
160161
* Asynchronously saves this {@linkcode Photo} to
161162
* a temporary file using this {@linkcode containerFormat},
162163
* and returns the path it was saved at.
164+
*
165+
* The returned value is a filesystem path, not a `file://` URL.
163166
*/
164167
saveToTemporaryFileAsync(): Promise<string>
165168
/**

packages/react-native-vision-camera/src/specs/outputs/CameraPhotoOutput.nitro.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ export interface CapturePhotoSettings {
230230
export interface PhotoFile {
231231
/**
232232
* The path of the file.
233+
* This is a filesystem path, not a `file://` URL.
233234
*/
234235
filePath: string
235236
}

packages/react-native-vision-camera/src/specs/outputs/CameraVideoOutput.nitro.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export interface RecorderSettings {
147147
* The absolute path (including file name and extension) where
148148
* the recording file should be written to, or `undefined` to
149149
* create a file in the device's temporary directory.
150+
* Pass a filesystem path, not a `file://` URL.
150151
*
151152
* All parent directories in this {@linkcode filePath} will
152153
* be automatically created if they do not yet exist.
@@ -232,6 +233,8 @@ export interface CameraVideoOutput extends CameraOutput {
232233
*
233234
* The {@linkcode Recorder} will record to the configured
234235
* file path, or to a temporary file if no path was provided.
236+
* The {@linkcode Recorder}'s file paths are filesystem paths,
237+
* not `file://` URLs.
235238
* It can only record once.
236239
*
237240
* If you want to create a second recording,

0 commit comments

Comments
 (0)