Skip to content

Commit

Permalink
Merge pull request #20 from enebin/release/0.4.0
Browse files Browse the repository at this point in the history
release/0.4.0
  • Loading branch information
enebin authored Jul 8, 2023
2 parents ff14219 + 00b1be9 commit fd108f0
Show file tree
Hide file tree
Showing 41 changed files with 595 additions and 850 deletions.
12 changes: 6 additions & 6 deletions Demo/Aespa-iOS/GalleryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import SwiftUI
struct GalleryView: View {
@ObservedObject var viewModel: VideoContentViewModel

@Binding private var mediaType: MediaType
@Binding private var mediaType: AssetType

init(
mediaType: Binding<MediaType>,
mediaType: Binding<AssetType>,
contentViewModel viewModel: VideoContentViewModel
) {
self._mediaType = mediaType
Expand All @@ -24,8 +24,8 @@ struct GalleryView: View {
var body: some View {
VStack(alignment: .center) {
Picker("File", selection: $mediaType) {
Text("Video").tag(MediaType.video)
Text("Photo").tag(MediaType.photo)
Text("Video").tag(AssetType.video)
Text("Photo").tag(AssetType.photo)
}
.pickerStyle(.segmented)
.frame(width: 200)
Expand All @@ -39,7 +39,7 @@ struct GalleryView: View {
spacing: 5
) {
ForEach(viewModel.photoFiles) { file in
let image = Image(uiImage: file.thumbnail ?? UIImage())
let image = file.image

image
.resizable()
Expand All @@ -55,7 +55,7 @@ struct GalleryView: View {
spacing: 5
) {
ForEach(viewModel.videoFiles) { file in
let image = Image(uiImage: file.thumbnail ?? UIImage())
let image = file.thumbnailImage

image
.resizable()
Expand Down
8 changes: 4 additions & 4 deletions Demo/Aespa-iOS/VideoContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct VideoContentView: View {
@State var showSetting = false
@State var showGallery = false

@State var captureMode: MediaType = .video
@State var captureMode: AssetType = .video

@ObservedObject private var viewModel = VideoContentViewModel()

Expand All @@ -32,8 +32,8 @@ struct VideoContentView: View {
ZStack(alignment: .center) {
// Mode change
Picker("Capture Modes", selection: $captureMode) {
Text("Video").tag(MediaType.video)
Text("Photo").tag(MediaType.photo)
Text("Video").tag(AssetType.video)
Text("Photo").tag(AssetType.photo)
}
.pickerStyle(.segmented)
.background(Color.black.opacity(0.7))
Expand Down Expand Up @@ -150,7 +150,7 @@ extension VideoContentView {
}
}

enum MediaType {
enum AssetType {
case video
case photo
}
Expand Down
21 changes: 10 additions & 11 deletions Demo/Aespa-iOS/VideoContentViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ class VideoContentViewModel: ObservableObject {
@Published var videoAlbumCover: Image?
@Published var photoAlbumCover: Image?

@Published var videoFiles: [VideoFile] = []
@Published var photoFiles: [PhotoFile] = []
@Published var videoFiles: [VideoAsset] = []
@Published var photoFiles: [PhotoAsset] = []

init() {
let option = AespaOption(albumName: "Aespa-Demo-App")
var option = AespaOption(albumName: "Aespa-Demo-App")
self.aespaSession = Aespa.session(with: option)

// Common setting
Expand Down Expand Up @@ -85,19 +85,18 @@ class VideoContentViewModel: ObservableObject {

func fetchVideoFiles() {
// File fetching task can cause low reponsiveness when called from main thread
DispatchQueue.global().async {
let fetchedFiles = self.aespaSession.fetchVideoFiles()

DispatchQueue.main.async {
self.videoFiles = fetchedFiles
}
Task(priority: .utility) {
let fetchedFiles = await aespaSession.fetchVideoFiles()
DispatchQueue.main.async { self.videoFiles = fetchedFiles }
}
}

func fetchPhotoFiles() {
// File fetching task can cause low reponsiveness when called from main thread
let fetchedFiles = self.aespaSession.fetchPhotoFiles()
self.photoFiles = fetchedFiles
Task(priority: .utility) {
let fetchedFiles = await aespaSession.fetchPhotoFiles()
DispatchQueue.main.async { self.photoFiles = fetchedFiles }
}
}
}

Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,8 @@ graph LR;
### `InteractivePreview`
One of our main feature, `InteractivePreview` provides a comprehensive and intuitive way for users to interact directly with the camera preview.

| Features | Description |
| Features | Description |
|------------------------|------------------------------------------------------------------------------------------------------------------|
| Tap to focus | Adjusts the focus of the camera based on the tapped area on the screen. |
| Double tap to change camera | Switches between the front and back camera upon double tapping. |
| Pinch zoom | Allows zooming in or out on the preview by using a pinch gesture. |

Expand Down Expand Up @@ -203,6 +202,8 @@ https://github.com/enebin/Aespa.git
import Aespa

let aespaOption = AespaOption(albumName: "YOUR_ALBUM_NAME")
// If you don't need album add this line
// aespaOption.asset.synchronizeWithLocalAlbum = false
let aespaSession = Aespa.session(with: aespaOption)
```

Expand Down Expand Up @@ -242,13 +243,13 @@ aespaSession.capturePhoto()
aespaSession.stopRecording { result in
switch result {
case .success(let file):
//
print(file.path) // file://some/path
case .failure(let error):
print(error)
}
}

// or
// or...
aespaSession.fetchVideoFiles(limit: 1)

// or you can use publisher
Expand Down
3 changes: 2 additions & 1 deletion Scripts/gen-mocks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ 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" -not -path "*/Context/*" -print0 | xargs -0)
SWIFT_FILES=$(find "$PACKAGE_SOURCE_PATH" -type f -name "*.swift" -not -path "*/Context/*" -not -path "*/Loader/*" -print0 | xargs -0)


echo "✅ Generated Mocks File = ${OUTPUT_FILE}"
echo "✅ Mocks Input Directory = ${PACKAGE_SOURCE_PATH}"
Expand Down
4 changes: 4 additions & 0 deletions Sources/Aespa/AespaError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,9 @@ public extension AespaError {
enum FileErrorReason: String {
case unableToFlatten =
"Cannot take a video because camera permissions are denied."
case notSupported =
"Unsuportted file type."
case alreadyExist =
"File already exists. Cannot overwrite the file."
}
}
25 changes: 11 additions & 14 deletions Sources/Aespa/AespaOption.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ public typealias FileNamingRule = () -> String
public struct AespaOption {
/// `Asset` configuration object which encapsulates options related to the media assets such as
/// the album name, file extension and naming convention for the files.
public let asset: Asset
public var asset: Asset

/// `Session` configuration object which holds the settings to be applied for the `Aespa` session,
/// such as auto video orientation.
public let session: Session
public var session: Session

/// `Log` configuration object which determines the logging behaviour during the session,
/// such as enabling or disabling logging.
public let log: Log
public var log: Log

/// Creates an `AespaOption` with specified album name and an option to enable logging.
///
Expand Down Expand Up @@ -56,38 +56,35 @@ public extension AespaOption {
/// such as the album name, file naming rule, and file extension.
struct Asset {
/// The name of the album where recorded assets will be saved.
let albumName: String
public var albumName: String

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

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

/// A `Boolean` flag that determines to use in-memory cache for `VideoFile`
///
/// It's set `true` by default.
let useVideoFileCache: Bool
public var synchronizeWithLocalAlbum: Bool

/// The file extension for the recorded videos.
let fileNameHandler: FileNamingRule
public var fileNameHandler: FileNamingRule

/// The rule for naming video files.
let fileExtension: String
public var fileExtension: String

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

self.useVideoFileCache = useVideoFileCache
self.synchronizeWithLocalAlbum = true
self.fileExtension = fileExtension.rawValue
self.fileNameHandler = fileNameHandler
}
Expand Down
18 changes: 6 additions & 12 deletions Sources/Aespa/AespaSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import AVFoundation
open class AespaSession {
let option: AespaOption
let coreSession: AespaCoreSession
private let fileManager: AespaCoreFileManager
private let albumManager: AespaCoreAlbumManager

private let recorder: AespaCoreRecorder
Expand All @@ -48,7 +47,6 @@ open class AespaSession {
session: session,
recorder: .init(core: session),
camera: .init(core: session),
fileManager: .init(enableCaching: option.asset.useVideoFileCache),
albumManager: .init(albumName: option.asset.albumName)
)
}
Expand All @@ -58,14 +56,12 @@ open class AespaSession {
session: AespaCoreSession,
recorder: AespaCoreRecorder,
camera: AespaCoreCamera,
fileManager: AespaCoreFileManager,
albumManager: AespaCoreAlbumManager
) {
self.option = option
self.coreSession = session
self.recorder = recorder
self.camera = camera
self.fileManager = fileManager
self.albumManager = albumManager

self.previewLayerSubject = .init(nil)
Expand All @@ -81,15 +77,13 @@ open class AespaSession {
coreSession: coreSession,
camera: camera,
albumManager: albumManager,
fileManager: fileManager,
option: option)

self.videoContext = AespaVideoContext(
commonContext: self,
coreSession: coreSession,
recorder: recorder,
albumManager: albumManager,
fileManager: fileManager,
option: option)
}

Expand Down Expand Up @@ -292,8 +286,8 @@ extension AespaSession: VideoContext {
videoContext.isMuted
}

public func startRecording(_ onComplete: @escaping CompletionHandler = { _ in }) {
videoContext.startRecording(onComplete)
public func startRecording(at path: URL? = nil, _ onComplete: @escaping CompletionHandler = { _ in }) {
videoContext.startRecording(at: path, onComplete)
}

public func stopRecording(_ completionHandler: @escaping (Result<VideoFile, Error>) -> Void = { _ in }) {
Expand Down Expand Up @@ -327,8 +321,8 @@ extension AespaSession: VideoContext {
videoContext.torch(mode: mode, level: level, onComplete)
}

public func fetchVideoFiles(limit: Int = 0) -> [VideoFile] {
videoContext.fetchVideoFiles(limit: limit)
public func fetchVideoFiles(limit: Int = 0) async -> [VideoAsset] {
return await videoContext.fetchVideoFiles(limit: limit)
}
}

Expand Down Expand Up @@ -365,8 +359,8 @@ extension AespaSession: PhotoContext {
photoContext.custom(setting)
}

public func fetchPhotoFiles(limit: Int = 0) -> [PhotoFile] {
photoContext.fetchPhotoFiles(limit: limit)
public func fetchPhotoFiles(limit: Int = 0) async -> [PhotoAsset] {
return await photoContext.fetchPhotoFiles(limit: limit)
}
}

Expand Down
Loading

0 comments on commit fd108f0

Please sign in to comment.