SwiftUi如何从项目标识符加载所选视频

5ssjco0h  于 2022-10-31  发布在  Swift
关注(0)|答案(1)|浏览(145)

我是Swift的新手,一直在使用SwiftUI 4.0中的新PhotosPicker。我可以显示选定的图像,但不能显示视频。当我选择一个视频时,我可以获得如下所示的一些信息

  • 照片选取器项目(_项目标识符:可选(“40 F724 uF-24 M7 -4523- 9 B2B-AD 43 FB 2C 7 D 71/L0/001”),应显示项目标识符:false,支持的内容类型:[〈_UTCoreType 0x 106 c4 cd 60〉com.apple. quicktime-电影(不是动态的,已声明)],_项目提供者:〈PU照片文件提供程序项目提供程序:0x 600003 ea 05 a0〉{类型=(“com.苹果. quicktime-电影”)})*

我想知道是否有某种方式,我可以使用该项目标识符来加载所选的视频。我一直在寻找不同的例子,但没有一个显示视频的PhotosPicker。我有一个非常小的项目,我正在测试这一点,任何建议将是伟大的

import SwiftUI
     import Combine
     import PhotosUI
     import AVKit

    struct PlayVideoView: View {
    @State private var selectedItem: [PhotosPickerItem] = []
    @State private var data: Data?
    @State var player = AVPlayer(url: URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4")!)

    var body: some View {
        PhotosPicker(selection: $selectedItem,
                     maxSelectionCount: 1,
                     matching: .any(of: [.images,.videos])) {
            Image(systemName: "photo")
                .resizable()
                .foregroundColor(.blue)
                .frame(width: 24, height: 24)
                .padding(.top, 5.0)
        }.onChange(of: selectedItem) { newMedia in
            Task {
                guard let item = selectedItem.first else {
                    return
                }
                item.loadTransferable(type: Data.self) { result in

                    switch result {
                    case .success(let data):
                        if let data = data {
                            print(item) // get video url here and display in videoplayer
                            self.data = data

                        } else {
                            print("data is nil")
                        }
                    case .failure(let failure):
                        fatalError("\(failure)")
                    }
                }
            }
        }
        VideoPlayer(player: player) // selected video url should go here
             .frame(width: 400, height: 300, alignment: .center)
    }
}

struct PlayVideoView_Previews: PreviewProvider {
    static var previews: some View {
        PlayVideoView()
     }
    }
arknldoa

arknldoa1#

您可以尝试这种方法,使用https://github.com/zunda-pixel/SamplePhotosPicker中的代码。这里复制的Movie代码使用TransferRepresentation来表示临时文件中的url。

import Foundation
import SwiftUI
import PhotosUI
import AVKit
import CoreTransferable

// from: https://github.com/zunda-pixel/SamplePhotosPicker
struct Movie: Transferable {
  let url: URL

  static var transferRepresentation: some TransferRepresentation {
    FileRepresentation(contentType: .movie) { movie in
      SentTransferredFile(movie.url)
    } importing: { receivedData in
      let fileName = receivedData.file.lastPathComponent
      let copy: URL = FileManager.default.temporaryDirectory.appendingPathComponent(fileName)

      if FileManager.default.fileExists(atPath: copy.path) {
        try FileManager.default.removeItem(at: copy)
      }

      try FileManager.default.copyItem(at: receivedData.file, to: copy)
      return .init(url: copy)
    }
  }
}

struct ContentView: View {
    var body: some View {
        PlayVideoView()
    }
}

struct PlayVideoView: View {
    @State private var selectedItem: [PhotosPickerItem] = []
    @State var player = AVPlayer(url: URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4")!)

    var body: some View {
        PhotosPicker(selection: $selectedItem,
                     maxSelectionCount: 1,
                     matching: .any(of: [.images,.videos])) {
            Image(systemName: "photo")
                .resizable()
                .foregroundColor(.blue)
                .frame(width: 24, height: 24)
                .padding(.top, 5.0)
        }.onChange(of: selectedItem) { newMedia in
            Task {
                guard let item = selectedItem.first else {  return }
                item.loadTransferable(type: Movie.self) { result in   // <-- here
                    switch result {
                    case .success(let movie):
                        if let movie = movie {
                            player = AVPlayer(url: movie.url) // <-- here
                        } else {
                            print("movie is nil")
                        }
                    case .failure(let failure):
                        fatalError("\(failure)")
                    }
                }
            }
        }
        VideoPlayer(player: player)
            .frame(width: 400, height: 300, alignment: .center)
    }
}

相关问题