Hello,
I'm currently stuck trying to load a Video - previously picked by an PHPicker. In the photos you can see the current Views. The Videoplayer View stays unresponsive but in the first frames when the picker disappears you can see the thumbnail and a play button. What am i doing wrong? Should i load the file differently?
This is my Picker:
struct VideoPicker: UIViewControllerRepresentable{
@Binding var videoURL:String?
func makeUIViewController(context: Context) -> PHPickerViewController {
var config = PHPickerConfiguration()
config.filter = .videos
let picker = PHPickerViewController(configuration: config)
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator:NSObject, PHPickerViewControllerDelegate{
let parent:VideoPicker
init(_ parent: VideoPicker){
self.parent = parent
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true) {
// do something on dismiss
}
guard let provider = results.first?.itemProvider else {return}
provider.loadFileRepresentation(forTypeIdentifier: "public.movie") { url, error in
guard let url = url else {return}
self.parent.videoURL = url.absoluteString
print(url)
print(FileManager.default.fileExists(atPath: url.path))
}
}
}
}
I'm totally able to get the URL (local URL - e.g.:
file:///private/var/mobile/Containers/Data/Application/22126131-CBF4-4CAF-B943-22540F1096E1/tmp/.com.apple.Foundation.NSItemProvider.
)
But for the life of me - the VideoPlayer won't play it:
struct VideoView:View{
@Binding var videoURL:String?
@Binding var showVideoPicker:Bool
var body: some View{
if let videoURL = videoURL {
VideoPlayer(player: AVPlayer(url: URL(fileURLWithPath:videoURL)))
.frame(width: 100, height: 100, alignment: .center)
.clipShape(RoundedRectangle(cornerRadius: 16))
.onLongPressGesture{
generator.feedback.notificationOccurred(.success)
showVideoPicker.toggle()
}
}
else{
Text("...")
}
}
}
Maybe somebody can point me in the right direction because in every Tutorial everybody uses stuff that's bundled to play a video. I want to use Videos from the Photos APP (apple). The videoURL is a @State
in my ContentView. It gets updated through the VideoPicker
. Sorry for the formatting this is my first Post.
Okay i just fixed it by myself.
If anybody comes across this and has the same problem:
You first have to copy the video to your APP storage. Well at least that's what it made it work for me.
In your Picker do something like this after receiving the URL
from the picker. I always thought the videoplayer could just play the Video from the given URL. It can't. In my picker delegate method:
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true) {
// do something on dismiss
}
guard let provider = results.first?.itemProvider else {return}
provider.loadFileRepresentation(forTypeIdentifier: "public.movie") { url, error in
guard error == nil else{
print(error)
return
}
// receiving the video-local-URL / filepath
guard let url = url else {return}
// create a new filename
let fileName = "\(Int(Date().timeIntervalSince1970)).\(url.pathExtension)"
// create new URL
let newUrl = URL(fileURLWithPath: NSTemporaryDirectory() + fileName)
// copy item to APP Storage
try? FileManager.default.copyItem(at: url, to: newUrl)
self.parent.videoURL = newUrl.absoluteString
}
}
be sure to remove any gestures on VideoView (my longpressgesture messed with the standard interactions given by the AVPlayer)