首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >播放通过CloudKit下载的视频作为CKAsset - iOS

播放通过CloudKit下载的视频作为CKAsset - iOS
EN

Stack Overflow用户
提问于 2015-10-01 02:03:56
回答 3查看 2.5K关注 0票数 0

我正在制作一个应用程序,它记录视频,用CloudKit将视频上传到CKAsset,然后下载该文件并在AVPlayer中播放。这都是用Swift 2.0编写的

我已经下载了数据,我想我已经能够引用它了,但我不确定。当我将URL转换为NSData对象并将其打印到控制台时,数据/垃圾就会打印出来。但是,视频文件作为二进制文件下载。我能够访问CloudKit仪表板并下载文件并将'.mov‘附加到其中,并且它在Quicktime中打开没有问题。

因此,我认为我的主要问题是,我无法解决如何让视频文件实际播放,因为该文件没有扩展名。我尝试过在结尾添加“.mov”,但URLByAppendingPathExtension()没有效果。让我知道任何想法!

上传视频

代码语言:javascript
复制
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    let tempURL = info[UIImagePickerControllerMediaURL] as! NSURL

    dismissViewControllerAnimated(true) { () -> Void in
        self.uploadVideoToiCloud(tempURL)
        print("\n     Before Upload: \(tempURL)\n")
    }
}

func uploadVideoToiCloud(url: NSURL) {
    let videoRecord = CKRecord(recordType: "video", recordID: id)

    videoRecord["title"] = "This is the title"

    let videoAsset = CKAsset(fileURL: url)
    videoRecord["video"] = videoAsset

    CKContainer.defaultContainer().privateCloudDatabase.saveRecord(videoRecord) { (record, error) -> Void in
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            if error == nil {
                print("upload successful")

            } else {
                print(error!)
            }
        })
    }
}

下载录影带

代码语言:javascript
复制
func downloadVideo(id: CKRecordID) {

    privateDatabase.fetchRecordWithID(id) { (results, error) -> Void in

        dispatch_async(dispatch_get_main_queue()) { () -> Void in
            if error != nil {

                    print(" Error Fetching Record  " + error!.localizedDescription)
            } else {
                if results != nil {
                    print("pulled record")

                    let record = results!
                    let videoFile = record.objectForKey("video") as! CKAsset

                    self.videoURL = videoFile.fileURL

                    print("     After Download: \(self.videoURL!)")

                    self.videoAsset = AVAsset(URL: self.videoURL!)
                    self.playVideo()

                } else {
                    print("results Empty")
                }
            }
        }
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-10-01 02:41:35

解决方案的结果是,在将数据写入文件名之前,我忘记指定文件名。我使用的是URLByAppendingPathExtension,它破坏了URL,最后使用了URLByAppendingPathComponent并在那里添加了一个文件名。这是对我有效的解决办法!谢谢各位的评论。

代码语言:javascript
复制
func downloadVideo(id: CKRecordID) {

    privateDatabase.fetchRecordWithID(id) { (results, error) -> Void in

        dispatch_async(dispatch_get_main_queue()) { () -> Void in
            if error != nil {

                    print(" Error Fetching Record  " + error!.localizedDescription)
            } else {
                if results != nil {
                    print("pulled record")

                    let record = results as CKRecord!
                    let videoFile = record.objectForKey("video") as! CKAsset

                    self.videoURL = videoFile.fileURL as NSURL!
                    let videoData = NSData(contentsOfURL: self.videoURL!)

                    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
                    let destinationPath = NSURL(fileURLWithPath: documentsPath).URLByAppendingPathComponent("filename.mov", isDirectory: false) //This is where I messed up.

                    NSFileManager.defaultManager().createFileAtPath(destinationPath.path!, contents:videoData, attributes:nil)

                    self.videoURL = destinationPath

                    self.videoAsset = AVURLAsset(URL: self.videoURL!)
                    self.playVideo()

                } else {
                    print("results Empty")
                }
            }
        }
    }
}
票数 2
EN

Stack Overflow用户

发布于 2016-05-24 14:12:15

根本的问题是,AVPlayer需要一个文件扩展名,例如.mov,但是CKAssetfileURL属性指向一个缺少扩展名的文件。最干净的解决方案是创建一个硬链接,避免在周围移动兆字节的数据,并且不需要磁盘空间:

代码语言:javascript
复制
- (NSURL *)videoURL {
    return [self createHardLinkToVideoFile];
}


- (NSURL *)createHardLinkToVideoFile {
    NSError *err;
    if (![self.hardURL checkResourceIsReachableAndReturnError:nil]) {
        if (![[NSFileManager defaultManager] linkItemAtURL:self.asset.fileURL toURL:self.hardURL error:&err]) {
            // if creating hard link failed it is still possible to create a copy of self.asset.fileURL and return the URL of the copy
        }
    }
    return self.hardURL;
}

- (void)removeHardLinkToVideoFile {
    NSError *err;
    if ([self.hardURL checkResourceIsReachableAndReturnError:nil]) {
        if (![[NSFileManager defaultManager] removeItemAtURL:self.hardURL error:&err]) {
        }
    }
}

- (NSURL *)hardURL {
    return [self.asset.fileURL URLByAppendingPathExtension:@"mov"];
}

然后在视图控制器中,将AVPlayer指向videoURL而不是asset.fileURL

票数 5
EN

Stack Overflow用户

发布于 2022-01-21 07:23:58

以下是从CloudKit下载多个视频的解决方案。使用它,您可以将视频存储在多个目标上,并轻松获取文件路径。

代码语言:javascript
复制
import AVKit
import CloudKit

var assetForVideo = [CKAsset]()
var videoURLForGetVideo = NSURL()
database.perform(queryForVideo, inZoneWith: nil) { [weak self] record, Error in
    guard  let records = record, Error == nil else {
        return
    }
    DispatchQueue.main.async { [self] in
        self?.assetForVideo = records.compactMap({ $0.value(forKey: "video") as? CKAsset })

        for (i,dt) in self!.assetForVideo.enumerated(){
            self!.videoURLForGetVideo = (dt.fileURL as NSURL?)!
            let videoData = NSData(contentsOf: self!.videoURLForGetVideo as URL)
            let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
            let destinationPath = NSURL(fileURLWithPath: documentsPath).appendingPathComponent(self!.assetForVideo.count == i ? "filename\(self!.assetForVideo.count).mov" : "filename\(i+1).mov", isDirectory: false)! as NSURL
            FileManager.default.createFile(atPath: destinationPath.path!, contents: videoData as Data?, attributes: nil)
            self?.videoURLForGetVideo = destinationPath
            self!.videoAssett = AVURLAsset(url: self!.videoURLForGetVideo as URL)
            let abc = self!.videoAssett.url
            let videoURL = URL(string: "\(abc)")
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32878358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档