Videos in PhotoData are not playable

349 Views Asked by At

I'm building an photo/video picker where I fetch all the videos from the phone using the following code

func fetchVideos() -> AnyPublisher<[Video], Never> {
    Future { promise in
        let options = PHFetchOptions()
        options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
            
        var videos = [Video]()
            
        PHAsset.fetchAssets(with: .video, options: options).enumerateObjects { asset, _, _ in
            videos.append(Video(asset: asset))
        }
            
        promise(.success(videos))
    }
    .eraseToAnyPublisher()
}

Once the user taps on a video I fetch the AVAsset from the PHAsset using the code below

func fetchAVAsset(_ completion: @escaping (AVAsset?) -> Void) {
    let options = PHVideoRequestOptions()
    options.isNetworkAccessAllowed = true

    PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { avAsset, _, _ in
        DispatchQueue.main.async {
            completion(avAsset)
        }
    }
}

I notices that the videos are stored in two different places

  • file:///var/mobile/Media/DCIM/100APPLE/IMG_0813.MP4
  • file:///var/mobile/Media/PhotoData/Metadata/DCIM/100APPLE/IMG_0787.medium.MP4

The videos stored in the former path are working just fine. The videos stored at the latter path are not playable. I'm trying to play them in the AVPlayerViewController but it displays a crossed-out play button and no video. Why?

1

There are 1 best solutions below

0
Ray On

I had the same problem. If I request with youIt seems to be fetching only meta information. When I tried changing deliveryMode and version, I was able to edit and play correctly.

let options: PHVideoRequestOptions = PHVideoRequestOptions()
options.version = .original
options.deliveryMode = .highQualityFormat
options.isNetworkAccessAllowed = true

    
PHImageManager.default().requestAVAsset(forVideo:self.videoAssets[0], options: options, resultHandler: { (asset, audioMix, info) in
        DispatchQueue.main.async {
            if let urlAsset = asset as? AVURLAsset {
                
             // asset, urlAsset
                
            }
        }
})