3

これは、私が読んだすべての例とドキュメントに基づいて非常に簡単なもののようですが、奇妙な理由でこれを機能させることができません。

Alamofire Frame work を使用して、instagram からビデオをダウンロードしています。ダウンロードしたら、ビデオをカメラロールに保存したいと思います。ビデオをダウンロードしてディスクに保存するコードは次のとおりです。

let destination: (NSURL, NSHTTPURLResponse) -> (NSURL) = {
            (temporaryURL, response) in

            if let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {

                let finalPath = directoryURL.URLByAppendingPathComponent("\(Scripts.dateToString2(date: NSDate())).\(response.suggestedFilename!)")
                InstagramEngine.downloadMediaPath = finalPath

                Scripts.log("Final Path >> \(finalPath)")

                return finalPath
            }

            return temporaryURL
        }

        let request = Alamofire.download(.GET, self.videoURL, destination)

        request.response { _, response, data, error in

                NSNotificationCenter.defaultCenter().postNotificationName(kMediaDownloadComplete, object: nil)

        }

ダウンロードが完了すると、この関数を呼び出してカメラロールに保存する通知がトリガーされます。

UISaveVideoAtPathToSavedPhotosAlbum(InstagramEngine.downloadMediaPath.URLString, self, Selector("video:didFinishSavingWithError:contextInfo:"), nil)

ログステートメントに基づいてすべてが呼び出されており、エラーは発生していません。UISaveVideoAtPathToSavedPhotosAlbum に対して didFinishSavingWithError も正常に呼び出されており、エラーが見つからないことを確認しました。しかし、カメラロールを確認すると、そこにはまだビデオが保存されていません。何か案は?

4

2 に答える 2

4

残念ながら、Instagram で使用されるUISaveVideoAtPathToSavedPhotosAlbumフォーマットである と に関連するバグがあります。mp4

UIVideoAtPathIsCompatibleWithSavedPhotosAlbumビデオがメソッドと互換性があるかどうかを示すために呼び出されるヘルパー メソッドがありUISaveVideoAtPathToSavedPhotosAlbumます。falseこれは、Instagram からダウンロードしたビデオに対して返されます。


幸いなことに、ビデオをカメラロールに保存することは引き続き可能です。これは、を使用して可能ALAssetsLibraryです。私はあなたのサンプル コードを取得し、それを使用するように適応させようとしALAssetsLibraryました。

import AssetsLibrary

...
...

func downloadVideoToCameraRoll() {

    // Local variable pointing to the local file path for the downloaded video
    var localFileUrl: String?

    // A closure for generating the local file path for the downloaded video. This will be pointing to the Documents directory with a unique UDID file name.
    let destination: (NSURL, NSHTTPURLResponse) -> (NSURL) = {
        (temporaryURL, response) in

        if let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {
            let finalPath = directoryURL.URLByAppendingPathComponent("\(NSUUID()).\(response.suggestedFilename!)")
            localFileUrl = finalPath.absoluteString
            return finalPath
        }

        return temporaryURL
    }

    // The media post which should be downloaded
    let postURL = NSURL(string: "https://api.instagram.com/v1/media/" + "952201134785549382_250131908" + "?access_token=" + InstagramEngine.sharedEngine().accessToken)!

    // Then some magic happens that turns the postURL into the videoURL, which is the actual url of the video media:
    let videoURL = NSURL(string: "https://scontent.cdninstagram.com/hphotos-xfp1/t50.2886-16/11104555_1603400416544760_416259564_s.mp4")!

    // Download starts
    let request = Alamofire.download(.GET, videoURL, destination)

    // Completion handler for the download
    request.response { (request, response, data, error) -> Void in
        if let path = localFileUrl {
            let isVideoCompatible = UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(path)
            println("bool: \(isVideoCompatible)") // This logs out "bool: false"

            let library = ALAssetsLibrary()

            library.writeVideoAtPathToSavedPhotosAlbum(NSURL(string: path), completionBlock: { (url, error) -> Void in
                // Done! Go check your camera roll
            })
        }
    }
}
于 2015-07-08T10:12:31.937 に答える
1

Alamofire を使用して、動画をダウンロードして保存する方法は次のとおりです。コードは Swift 4 にあります。廃止されPhotosたため、フレームワークを使用する必要があることに注意してくださいAssetsLibrary

import UIKit
import Alamofire
import Photos

/// Download and save video to camera roll
final class VideoFetcher {
  private let fileManager: FileManager

  init(fileManager: FileManager = FileManager.default) {
    self.fileManager = fileManager
  }

  func downloadAndSave(videoUrl: URL, completion: @escaping (Bool) -> Void) {
    let destination: (URL, HTTPURLResponse) -> (URL, DownloadRequest.DownloadOptions) = {
      tempUrl, response in

      let option = DownloadRequest.DownloadOptions()
      let finalUrl = tempUrl.deletingPathExtension().appendingPathExtension(videoUrl.pathExtension)
      return (finalUrl, option)
    }

    Alamofire.download(videoUrl, to: destination)
      .response(completionHandler: { [weak self] response in
        guard response.error == nil,
          let destinationUrl = response.destinationURL else {
            completion(false)
            return
        }

        self?.save(videoFileUrl: destinationUrl, completion: completion)
      })
  }

  private func save(videoFileUrl: URL, completion: @escaping (Bool) -> Void) {
    PHPhotoLibrary.shared().performChanges({
      PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoFileUrl)
    }, completionHandler: { succeeded, error in
      guard error == nil, succeeded else {
        completion(false)
        return
      }

      completion(true)
    })
  }
}
于 2018-02-05T14:12:48.517 に答える