ios Swift - 从远程 URL 下载视频并将其保存在相册中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35479903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:33:00  来源:igfitidea点击:

Swift - Download a video from distant URL and save it in an photo album

iosiphoneswiftipad

提问by Melanie Journe

I'm currently displaying a video in my app and I want the user to be able to save it to its device gallery/album photo/camera roll. Here it's what I'm doing but the video is not saved in the album :/

我目前正在我的应用程序中显示视频,我希望用户能够将其保存到其设备画廊/相册照片/相机胶卷中。这是我正在做的,但视频没有保存在相册中:/

    func downloadVideo(videoImageUrl:String)
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        //All stuff here

        print("downloadVideo");
        let url=NSURL(string: videoImageUrl);
        let urlData=NSData(contentsOfURL: url!);

        if((urlData) != nil)
        {
            let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0];

            let fileName = videoImageUrl; //.stringByDeletingPathExtension

            let filePath="\(documentsPath)/\(fileName)";

            //saving is done on main thread

            dispatch_async(dispatch_get_main_queue(), { () -> Void in

                urlData?.writeToFile(filePath, atomically: true);
                print("videoSaved");
            })

        }
    })

}

I'va also look into this :

我还研究了这个:

let url:NSURL = NSURL(string: fileURL)!;

    PHPhotoLibrary.sharedPhotoLibrary().performChanges({
        let assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(url);
        let assetPlaceHolder = assetChangeRequest!.placeholderForCreatedAsset;
        let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: self.assetCollection)
        albumChangeRequest!.addAssets([assetPlaceHolder!])
        }, completionHandler: saveVideoCallBack)

But I have the error "Unable to create data from file (null)". My "assetChangeRequest" is nil. I don't understand as my url is valid and when I go to it with a browser, it download a quick time file.

但是我有错误“无法从文件(空)创建数据”。我的“资产变更请求”为零。我不明白,因为我的 url 是有效的,当我使用浏览器访问它时,它会下载一个快速时间文件。

If anyone can help me, it would be appreciated ! I'm using Swift and targeting iOS 8.0 min.

如果有人可以帮助我,将不胜感激!我正在使用 Swift 并针对 iOS 8.0 分钟。

回答by Nimble

Update

更新

Wanted to update the answer for Swift 3 using URLSession and figured out that the answer already exists in related topic here. Use it.

想使用URLSession来更新斯威夫特3的答案,想通了,答案已经相关主题中存在这里。用它。

Original Answer

原答案

The code below saves a video file to Camera Roll. I reused your code with a minor change - I removed let fileName = videoImageUrl;because it leads to incorrect file path.

下面的代码将视频文件保存到相机胶卷。我重用了你的代码,做了一个小改动 - 我删除了,let fileName = videoImageUrl;因为它会导致不正确的文件路径。

I tested this code and it saved the asset into camera roll. You asked what to place into creationRequestForAssetFromVideoAtFileURL- put a link to downloaded video file as in the example below.

我测试了这段代码并将资产保存到相机胶卷中。您询问要放入什么内容creationRequestForAssetFromVideoAtFileURL- 如下例所示放入下载的视频文件的链接。

let videoImageUrl = "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"

DispatchQueue.global(qos: .background).async {
    if let url = URL(string: urlString),
        let urlData = NSData(contentsOf: url) {
        let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0];
        let filePath="\(documentsPath)/tempFile.mp4"
        DispatchQueue.main.async {
            urlData.write(toFile: filePath, atomically: true)
            PHPhotoLibrary.shared().performChanges({
                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL(fileURLWithPath: filePath))
            }) { completed, error in
                if completed {
                    print("Video is saved!")
                }
            }
        }
    }
}

回答by Yuval Tal

Swift 3 version of the code from @Nimble:

来自@Nimble 的 Swift 3 版本代码:

DispatchQueue.global(qos: .background).async {
    if let url = URL(string: urlString),
        let urlData = NSData(contentsOf: url)
    {
        let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0];
        let filePath="\(documentsPath)/tempFile.mp4"
        DispatchQueue.main.async {
            urlData.write(toFile: filePath, atomically: true)
            PHPhotoLibrary.shared().performChanges({
                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL(fileURLWithPath: filePath))
            }) { completed, error in
                if completed {
                    print("Video is saved!")
                }
            }
        }
    }
}

回答by Jefin Abdul Jaleel

PHPhotoLibrary.shared().performChanges({
     PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: video.url!)}) {
     saved, error in
     if saved {
          print("Save status SUCCESS")
     }
}