Skip to content

Commit

Permalink
release v0.2.0 (#13)
Browse files Browse the repository at this point in the history
* Remove setting from capture method

* Add context data structure

* Implement video context

* Remove video related code from public session

* Implement photo context

* Refactor file structure 
- with comments

* Implement photo fetching

* Fix photo context to use new setting each time

* Update cache test cases

* Add cache storage tests

* Split video and photo fetching logic

* Add generator tests

* Move fetch method location

* Remove unnecessary data

* Separate video and photo context

* Fix workflow and test cases

* Fix error

* Update readme

* Add orientation getter

* Fix thumbnail setting
  • Loading branch information
enebin authored Jun 25, 2023
1 parent 587d953 commit 211845a
Show file tree
Hide file tree
Showing 38 changed files with 1,793 additions and 981 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Unit testing and collect result infomations

on:
pull_request:
types: [synchronize]
types: [opened, synchronize]

concurrency:
group: unit-test-${{ github.head_ref }}
Expand Down Expand Up @@ -35,6 +35,7 @@ jobs:
- name: Test
run: |
set -o pipefail
ROOT_PATH="./"
# Now do test
Expand All @@ -56,4 +57,4 @@ jobs:
if [ $? -ne 0 ]; then
echo "❌ Error: Tests failed."
exit 1
fi
fi
8 changes: 4 additions & 4 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ analyzer_rules:
- explicit_self

included:
- Sources/*
- Sources
excluded:
- Tests/*
- Tests

# If true, SwiftLint will not fail if no lintable files are found.
allow_zero_lintable_files: false

force_cast: warning # implicitly
force_cast: error # implicitly
force_try:
severity: warning # explicitly
# implicitly
Expand All @@ -38,6 +38,6 @@ identifier_name:
allowed_symbols: ["_"]

missing_docs:
included: Sources/*
severity: warning

reporter: "xcode"
142 changes: 78 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ try await Aespa.configure()
- [Requirements](#Requirements)
- [Getting Started](#Getting-Started)
- [Implementation Examples](#Implementation-Examples)
- [Start & Stop Recording](#Start-&-Stop-Recording)
- [Subscribing Publisher](#Subscribing-Publisher)
- [Configuration](#Configuration)
- [Recording & Capture](#Recording-&-Capture)
- [SwiftUI Integration](#SwiftUI-Integration)
- [Example Usage](#Example-Usage)
- [Contributing](#Contributing)
Expand Down Expand Up @@ -118,38 +118,63 @@ graph LR;
</details>

## Functionality
Aespa offers the following functionalities for managing a video recording session:

| Function | Description |
|------------------------------|---------------------------------------------------|
| `startRecording` | Initiates the recording of a video session. |
| `stopRecording` | Terminates the current video recording session and attempts to save the video file. |
| `mute` | Mutes the audio input for the video recording session. |
| `unmute` | Restores the audio input for the video recording session. |
| `setOrientation` | Adjusts the orientation for the video recording session. |
| `setPosition` | Changes the camera position for the video recording session. |
| `setQuality` | Alters the video quality preset for the recording session. |
| `setStabilization` | Modifies the stabilization mode for the video recording session. |
| `zoom` | Adjusts the zoom factor for the video recording session. |
| `setAutofocusing` | Modifies the autofocusing mode for the video recording session. |
| `fetchVideoFiles` | Fetch a list of recorded video files. |
| `doctor` | Check if essential conditions for recording are satisfied. |

> **Note**
>
> You can access our **official documentation** for the most comprehensive and up-to-date explanations in [here](https://enebin.github.io/Aespa/documentation/aespa/)
| Common | Description |
|----------------------------------|------------------------------------------------------------------------------------------------------------------|
|`zoom` | Modifies the zoom factor. |
|`setPosition` | Changes the camera position. |
| `setOrientation` | Modifies the orientation. |
| `setAutofocusing` | Alters the autofocusing mode. |
| `setQuality` | Adjusts the video quality preset for the recording session. |
| `doctor` | Checks if essential conditions to start recording are satisfied. |
| `previewLayerPublisher` | Responsible for emitting updates to the preview layer. |

| Video | Description |
|----------------------------------|------------------------------------------------------------------------------------------------------------------|
|`startRecording` | Initiates the recording of a video session. |
|`stopRecording` | Terminates the current video recording session and attempts to save the video file. |
| `mute` | Mutes the audio input. |
| `unmute` | Restores the audio input. |
| `setStabilization` | Alters the stabilization mode. |
| `setTorch` | Adjusts the torch mode and level. |
| `customize` | Customizes the session with a specific tuning configuration. |
|`fetchVideoFiles` | Fetches a list of recorded video files. |
| `videoFilePublisher` | Emits a `Result` object containing a latest video file data. |

| Photo | Description |
|----------------------------------|------------------------------------------------------------------------------------------------------------------|
|`capturePhoto` | Capture a photo and returns a result image file. |
|`setFlashMode` | Sets the flash mode for the photo capture session. |
| `redEyeReduction` | Enables or disables red-eye reduction for the photo capture session. |
| `customize` | Customizes the photo capture session with a specific `AVCapturePhotoSettings`. |
|`fetchPhotoFiles` | Fetches a list of captured photos files. |
| `photoFilePublisher` | Emits a `Result` object containing a latest image file data. |

## Installation
### Swift Package Manager (SPM)
Follow these steps to install **Aespa** using SPM:

1. From within Xcode 13 or later, choose `File` > `Swift Packages` > `Add Package Dependency`.
2. At the next screen, enter the URL for the **Aespa** repository in the search bar then click `Next`.
``` Text
https://github.com/enebin/Aespa.git
```
``` Text
https://github.com/enebin/Aespa.git
```
3. For the `Version rule`, select `Up to Next Minor` and specify the current Aespa version then click `Next`.
4. On the final screen, select the `Aespa` library and then click `Finish`.

**Aespa** should now be integrated into your project 🚀

## Usage

> **Note**
>
> We offer an extensively detailed and ready-to-use code base for a SwiftUI app that showcases most of the package's features.
> You can access it [here](https://github.com/enebin/Aespa-iOS).
### Requirements
- Swift 5.5+
- iOS 14.0+
Expand All @@ -166,49 +191,39 @@ Task(priority: .background) {
}
```
> **Warning**
>
> Please ensure to call `configure` within a background execution context. Neglecting to do so may lead to significantly reduced responsiveness in your application. ([reference](https://developer.apple.com/documentation/avfoundation/avcapturesession/1388185-startrunning))

and so on. You can find the latest documetation in [here](https://enebin.github.io/Aespa/documentation/aespa/)
.Implementation examples are decribed in [here](##Implementation-Exapmles)


## Implementation Exapmles
### Start & stop recording
### Configuration
``` Swift
do {
try aespaSession
.setStabilization(mode: .auto)
.setPosition(to: .front)
.setQuality(to: .hd1920x1080)
.mute()
.startRecording()
} catch {
print("Failed to start recording")
}

// Later...
try? aespaSession.stopRecording()

// Common setting
aespaSession
.setAutofocusing(mode: .continuousAutoFocus)
.setOrientation(to: .portrait)
.setQuality(to: .high)
.customize(WideColorCameraTuner())

// Photo-only setting
aespaSession
.setFlashMode(to: .on)
.redEyeReduction(enabled: true)

// Video-only setting
aespaSession
.mute()
.setStabilization(mode: .auto)
```

### Subscribing publihser
``` Swift
// Subscribe file publisher
aespaSession.videoFilePublisher
.receive(on: DispatchQueue.global(qos: .utility))
.sink { [weak self] status in
guard let self else { return }
switch status {
case .success(let file):
// Handle file
// ex) return file.thumbnailImage
case .failure(let error):
// Handle error
// ex)print(error)
}
}
.store(in: &subsriptions)
### Recording & Capture
``` Swift
// Start recording
aespaSession.startRecording()
// Later... stop recording
aespaSession.stopRecording()

// Capture photo
aespaSession.capturePhoto()
```

## SwiftUI Integration
Expand Down Expand Up @@ -249,13 +264,12 @@ class VideoContentViewModel: ObservableObject {
Task(priority: .background) {
do {
try await Aespa.configure()
try aespaSession
.mute()
aespaSession
.setAutofocusing(mode: .continuousAutoFocus)
.setStabilization(mode: .auto)
.setOrientation(to: .portrait)
.setQuality(to: .high)
.customize(WideColorCameraTuner())

// Other settings ...

} catch let error {
print(error)
Expand All @@ -264,10 +278,10 @@ class VideoContentViewModel: ObservableObject {
}
}
```
> **Note**: You can find the demo app in here([Aespa-iOS](https://github.com/enebin/Aespa-iOS))

> **Note**: In UIKit, you can access the preview through the `previewLayer` property of `AespaSession`.
> **Note**
>
> In `UIKit`, you can access the preview through the `previewLayer` property of `AespaSession`.
> For more details, refer to the [AVCaptureVideoPreviewLayer](https://developer.apple.com/documentation/avfoundation/avcapturevideopreviewlayer) in the official Apple documentation.
## Contributing
Expand Down
4 changes: 2 additions & 2 deletions Scripts/gen-mocks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ PROJECT_NAME="Aespa"
TESTER_NAME="TestHostApp"
PACKAGE_SOURCE_PATH="${ROOT_PATH}/Sources/Aespa"
OUTPUT_FILE="${ROOT_PATH}/Tests/Tests/Mock/GeneratedMocks.swift"
SWIFT_FILES=$(find "$PACKAGE_SOURCE_PATH" -type f -name "*.swift" -print0 | xargs -0)
SWIFT_FILES=$(find "$PACKAGE_SOURCE_PATH" -type f -name "*.swift" -not -path "*/Context/*" -print0 | xargs -0)

echo "✅ Generated Mocks File = ${OUTPUT_FILE}"
echo "✅ Mocks Input Directory = ${PACKAGE_SOURCE_PATH}"
Expand All @@ -28,4 +28,4 @@ if [ $? -ne 0 ]; then
exit 1
fi

echo "✅ Generating mock was successful"
echo "✅ Generating mock was successful"
13 changes: 12 additions & 1 deletion Sources/Aespa/AespaOption.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,14 @@ public extension AespaOption {
/// `Asset` provides options for configuring the video assets,
/// such as the album name, file naming rule, and file extension.
struct Asset {
/// The name of the album where recorded videos will be saved.
/// The name of the album where recorded assets will be saved.
let albumName: String

/// The name of the album where recorded videos will be saved.
let videoDirectoryName: String

/// The name of the album where recorded photos will be saved.
let photoDirectoryName: String

/// A `Boolean` flag that determines to use in-memory cache for `VideoFile`
///
Expand All @@ -71,11 +77,16 @@ public extension AespaOption {

init(
albumName: String,
videoDirectoryName: String = "video",
photoDirectoryName: String = "photo",
useVideoFileCache: Bool = true,
fileExtension: FileExtension = .mp4,
fileNameHandler: @escaping FileNamingRule = FileNamingRulePreset.Timestamp().rule
) {
self.albumName = albumName
self.videoDirectoryName = videoDirectoryName
self.photoDirectoryName = photoDirectoryName

self.useVideoFileCache = useVideoFileCache
self.fileExtension = fileExtension.rawValue
self.fileNameHandler = fileNameHandler
Expand Down
Loading

0 comments on commit 211845a

Please sign in to comment.