英文:
Upload Video to Firebase Using Swift UI
问题
这是我从设备中选择视频并将其上传到Firebase的代码:
import SwiftUI
import PhotosUI
import FirebaseStorage
class ShareVideo: NSObject, ObservableObject {
@Published var videoURL: URL?
func selectVideo() {
PHPhotoLibrary.requestAuthorization { status in
switch status {
case .authorized:
print("访问权限已授权。")
case .denied, .restricted:
print("访问权限被拒绝。")
case .notDetermined:
print("权限未确定。")
@unknown default:
fatalError("出现新的授权状态。")
}
}
var configuration = PHPickerConfiguration()
configuration.filter = .videos
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
UIApplication.shared.windows.first?.rootViewController?.present(picker, animated: true)
}
func uploadVideo() {
guard let videoURL = videoURL else {
return
}
let storage = Storage.storage()
let storageRef = storage.reference()
let videoRef = storageRef.child("videos/\(UUID().uuidString).mp4")
let metadata = StorageMetadata()
metadata.contentType = "video/mp4"
videoRef.putFile(from: videoURL, metadata: metadata) { metadata, error in
if let error = error {
print("上传视频错误: \(error.localizedDescription)")
} else {
print("视频上传成功。")
}
}
}
}
extension ShareVideo: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
guard let result = results.first else {
return
}
result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { url, error in
if let error = error {
print("加载视频错误: \(error.localizedDescription)")
} else if let url = url {
DispatchQueue.main.async {
self.videoURL = url
}
}
}
}
}
struct ShareVideoView: View {
@StateObject private var shareVideo = ShareVideo()
var body: some View {
VStack{
Button(action: {
shareVideo.selectVideo()
}){
Text("选择视频")
}
Button("上传视频") {
shareVideo.uploadVideo()
}
}
}
}
struct ShareVideoView_Previews: PreviewProvider {
static var previews: some View {
ShareVideoView()
}
}
我收到以下错误消息:
上传视频错误: 文件URL: file:///Users/hitesh/Library/Developer/CoreSimulator/Devices/B28A566B-E082-4802-87CA-E2044ECCE57C/data/Containers/Data/Application/25CE276A-BD92-4D0C-9FBE-C594E9C05E90/tmp/.com.apple.Foundation.NSItemProvider.8pCkyb/SampleVideo_1280x720_1mb.mp4 无法访问。请确保文件URL不是目录、符号链接或无效URL。
英文:
Here is my code to pick the video from device and upload it to firebase
import SwiftUI
import PhotosUI
import FirebaseStorage
class ShareVideo: NSObject, ObservableObject {
@Published var videoURL: URL?
func selectVideo() {
PHPhotoLibrary.requestAuthorization { status in
switch status {
case .authorized:
print("Access granted.")
case .denied, .restricted:
print("Access denied.")
case .notDetermined:
print("Authorization not determined.")
@unknown default:
fatalError("New authorization status is available.")
}
}
var configuration = PHPickerConfiguration()
configuration.filter = .videos
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
UIApplication.shared.windows.first?.rootViewController?.present(picker, animated: true)
}
func uploadVideo() {
guard let videoURL = videoURL else {
return
}
let storage = Storage.storage()
let storageRef = storage.reference()
let videoRef = storageRef.child("videos/\(UUID().uuidString).mp4")
let metadata = StorageMetadata()
metadata.contentType = "video/mp4"
videoRef.putFile(from: videoURL, metadata: metadata) { metadata, error in
if let error = error {
print("->>>>\(videoURL)")
print("Error uploading video: \(error.localizedDescription)")
} else {
print("Video uploaded successfully.")
}
}
}
}
extension ShareVideo: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
guard let result = results.first else {
return
}
result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { url, error in
if let error = error {
print("Error loading video: \(error.localizedDescription)")
} else if let url = url {
DispatchQueue.main.async {
self.videoURL = url
}
}
}
}
}
struct ShareVideoView: View {
@StateObject private var shareVideo = ShareVideo()
var body: some View {
VStack{
Button(action: {
shareVideo.selectVideo()
}){
Text("Select Video")
}
Button("Upload Video") {
shareVideo.uploadVideo()
}
}
}
}
struct ShareVideoView_Previews: PreviewProvider {
static var previews: some View {
ShareVideoView()
}
}
I am getting the following error
Error uploading video: File at URL: file:///Users/hitesh/Library/Developer/CoreSimulator/Devices/B28A566B-E082-4802-87CA-E2044ECCE57C/data/Containers/Data/Application/25CE276A-BD92-4D0C-9FBE-C594E9C05E90/tmp/.com.apple.Foundation.NSItemProvider.8pCkyb/SampleVideo_1280x720_1mb.mp4 is not reachable. Ensure file URL is not a directory, symbolic link, or invalid url.
答案1
得分: 0
这是您提供的代码的翻译:
我不知何故设法实现了它
import PhotosUI
import SwiftUI
import UIKit
import AVKit
import ImageCaptureCore
import AVFoundation
import FirebaseStorage
struct VideoPicker: View {
@State private var videoURL: URL?
@State private var isShowingVideoPicker = false
private func pickVideo() {
isShowingVideoPicker = true
}
private func handleVideoPickerResult(_ videoURL: URL) {
self.videoURL = videoURL
}
// 为Firebase设置注册应用程序委托
var body: some View {
VStack {
Button(action: pickVideo) {
Text("从相册选择视频")
}.padding()
.sheet(isPresented: $isShowingVideoPicker) {
ImagePickerDelegate(sourceType: .photoLibrary, mediaTypes: ["public.movie"], didPickVideo: handleVideoPickerResult)
}
if let videoURL = videoURL {
VideoPlayerView(videoURL: videoURL)
.frame(height: 200)
} else {
Text("点击按钮选择视频")
.padding()
}
Button("上传视频") {
if let videoURL = videoURL {
upload(file: videoURL) { url in
print(url)
}
}
}
.padding()
}
}
}
extension VideoPicker {
func upload(file: URL, completion: @escaping ((_ url: URL?) -> ())) {
let name = "\(UIDevice.current.identifierForVendor?.uuidString ?? "")\(UUID().uuidString).mp4"
do {
let data = try Data(contentsOf: file)
let storageRef = Storage.storage().reference().child("Videos").child(name)
if let uploadData = data as Data? {
let metaData = StorageMetadata()
metaData.contentType = "video/mp4"
storageRef.putData(uploadData, metadata: metaData) { (metadata, error) in
if let error = error {
completion(nil)
} else {
storageRef.downloadURL { (url, error) in
guard let downloadURL = url else {
completion(nil)
return
}
completion(downloadURL)
}
print("上传成功")
}
}
}
} catch let error {
print(error)
}
}
}
struct ImagePickerDelegate: UIViewControllerRepresentable {
let sourceType: UIImagePickerController.SourceType
let mediaTypes: [String]
let didPickVideo: (URL) -> Void
func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.sourceType = sourceType
picker.mediaTypes = mediaTypes
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(didPickVideo: didPickVideo)
}
final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let didPickVideo: (URL) -> Void
init(didPickVideo: @escaping (URL) -> Void) {
self.didPickVideo = didPickVideo
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
if let videoURL = info[.mediaURL] as? URL {
didPickVideo(videoURL)
}
picker.dismiss(animated: true)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true)
}
}
}
struct VideoPlayerView: View {
var videoURL: URL
var body: some View {
VideoPlayer(player: AVPlayer(url: videoURL))
.onAppear {
// 视图出现时自动播放视频
let player = AVPlayer.shared()
player.play()
}
.onDisappear {
// 视图消失时暂停视频
let player = AVPlayer.shared()
player.pause()
}
}
}
extension AVPlayer {
static func shared() -> AVPlayer {
struct Singleton {
static let instance = AVPlayer()
}
return Singleton.instance
}
}
struct VideoPickerView_Previews: PreviewProvider {
static var previews: some View {
Homeview()
}
}
请注意,我已经将文本中的 HTML 实体代码(如"
)替换为双引号。
英文:
I have somehow managed to achieve it
import PhotosUI
import SwiftUI
import UIKit
import AVKit
import ImageCaptureCore
import AVFoundation
import FirebaseStorage
struct VideoPicker: View {
@State private var videoURL: URL?
@State private var isShowingVideoPicker = false
private func pickVideo() {
isShowingVideoPicker = true
}
private func handleVideoPickerResult(_ videoURL: URL) {
self.videoURL = videoURL
}
// register app delegate for Firebase setup
var body: some View {
VStack {
Button(action: pickVideo) {
Text("Select Video from Gallery")
}.padding()
.sheet(isPresented: $isShowingVideoPicker) {
ImagePickerDelegate(sourceType: .photoLibrary, mediaTypes: ["public.movie"], didPickVideo: handleVideoPickerResult)
}
if let videoURL = videoURL {
VideoPlayerView(videoURL: videoURL)
.frame(height: 200)
} else {
Text("Tap the button to select a video")
.padding()
}
Button("Upload Video") {
if let videoURL = videoURL {
upload(file: videoURL) { url in
print(url)
}
}
}
.padding()
}
}
}
extension VideoPicker {
func upload(file: URL, completion: @escaping ((_ url : URL?) -> ())) {
let name = "\(UIDevice.current.identifierForVendor?.uuidString)!\(UUID().uuidString).mp4"
do {
let data = try Data(contentsOf: file)
let storageRef =
Storage.storage().reference().child("Videos").child(name)
if let uploadData = data as Data? {
let metaData = StorageMetadata()
metaData.contentType = "video/mp4"
storageRef.putData(uploadData, metadata: metaData
, completion: { (metadata, error) in
if let error = error {
completion(nil)
}
else{
storageRef.downloadURL { (url, error) in
guard let downloadURL = url else {
completion(nil)
return
}
completion(downloadURL)
}
print("success")
}
})
}
}catch let error {
print(error)
}
}
}
struct ImagePickerDelegate: UIViewControllerRepresentable {
let sourceType: UIImagePickerController.SourceType
let mediaTypes: [String]
let didPickVideo: (URL) -> Void
func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.sourceType = sourceType
picker.mediaTypes = mediaTypes
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(didPickVideo: didPickVideo)
}
final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let didPickVideo: (URL) -> Void
init(didPickVideo: @escaping (URL) -> Void) {
self.didPickVideo = didPickVideo
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
if let videoURL = info[.mediaURL] as? URL {
didPickVideo(videoURL)
}
picker.dismiss(animated: true)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true)
}
}
}
struct VideoPlayerView: View {
var videoURL: URL
var body: some View {
VideoPlayer(player: AVPlayer(url: videoURL))
.onAppear {
// Auto-play the video when the view appears
let player = AVPlayer.shared()
player.play()
}
.onDisappear {
// Pause the video when the view disappears
let player = AVPlayer.shared()
player.pause()
}
}
}
extension AVPlayer {
static func shared() -> AVPlayer {
struct Singleton {
static let instance = AVPlayer()
}
return Singleton.instance
}
}
struct VideoPickerView_Previews: PreviewProvider {
static var previews: some View {
Homeview()
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论