Skip to content

Instantly share code, notes, and snippets.

@Taehyeon-Kim
Created March 15, 2024 12:39
Show Gist options
  • Save Taehyeon-Kim/ced4492187d12a4b38440606d0c0c9aa to your computer and use it in GitHub Desktop.
Save Taehyeon-Kim/ced4492187d12a4b38440606d0c0c9aa to your computer and use it in GitHub Desktop.
SwiftUI: Fetch Video from the Photo Album
import AVKit
import PhotosUI
import SwiftUI
struct VideoTransferable: Transferable {
let url: URL
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(contentType: .movie) { exporting in
return SentTransferredFile(exporting.url)
} importing: { received in
let origin = received.file
let filename = origin.lastPathComponent
let copied = URL.documentsDirectory.appendingPathComponent(filename)
let filePath = copied.path()
if FileManager.default.fileExists(atPath: filePath) {
try FileManager.default.removeItem(atPath: filePath)
}
try FileManager.default.copyItem(at: origin, to: copied)
return VideoTransferable(url: copied)
}
}
}
struct VideoPlayerView: View {
@State private var player = AVPlayer()
@State private var photosPickerItem: PhotosPickerItem?
@State private var errorMessage: String?
@State private var showAlert: Bool = false
var body: some View {
/// 1. UI
VStack {
VideoPlayer(player: player)
PhotosPicker(
"Select a video",
selection: $photosPickerItem,
matching: .videos
)
}
/// 3. Observing
.onChange(of: photosPickerItem) { oldValue, newValue in
if let newValue {
Task {
do {
if let url = try await loadVideo(newValue) {
let playerItem = AVPlayerItem(url: url)
player.replaceCurrentItem(with: playerItem)
}
} catch {
errorMessage = error.localizedDescription
showAlert.toggle()
}
}
}
}
/// 4. Alert
.alert(errorMessage ?? "", isPresented: $showAlert, actions: {})
}
/// 2. Load Video
private func loadVideo(_ item: PhotosPickerItem) async throws -> URL? {
guard let video = try await item.loadTransferable(type: VideoTransferable.self) else {
return nil
}
return video.url
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment