【问题标题】:Swift / iOS 10 : How to download a VIDEO and store within the appSwift / iOS 10:如何下载视频并在应用程序中存储
【发布时间】:2016-11-06 13:27:40
【问题描述】:

我是 SWIFT/Programming & 的新手 我找不到我的问题的答案,这就是为什么我要在这里尝试一下:

  1. 如何从 URL 下载视频 (mp4) 并将其存储在应用程序中**

  2. 如何在容器中显示视频**

我已经找到了这个话题:

Swift - Downloading video with downloadTaskWithURL

但就我而言,我不希望视频被保存在相机胶卷中。就在应用内。

感谢任何帮助/提示!

【问题讨论】:

  • 这个问题可能有点宽泛,无论如何你应该下载它并存储在“文档”目录中——例如——。 this question might helps.
  • 是的,只需将其下载到您的文件夹即可。只有应用可以访问它。
  • 感谢您的帮助!!我试试看

标签: swift video download


【解决方案1】:

您可以使用 URLSession 的 dataTask 或 downloadTask 从 url 下载任何文件(如果它是可下载的)

以下是使用dataTask进行下载的方法:

    let videoUrl = "Some video url"

        let docsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

    let destinationUrl = docsUrl.appendingPathComponent("MyFileSaveName.mp4")
    if(FileManager().fileExists(atPath: destinationUrl.path)){
            print("\n\nfile already exists\n\n")
        }
        else{
            //DispatchQueue.global(qos: .background).async {
                var request = URLRequest(url: URL(string: videoUrl)!)
                request.httpMethod = "GET"
                _ = session.dataTask(with: request, completionHandler: { (data, response, error) in
    if(error != nil){
        print("\n\nsome error occured\n\n")
        return
    }
    if let response = response as? HTTPURLResponse{
        if response.statusCode == 200{
            DispatchQueue.main.async {
                if let data = data{
                    if let _ = try? data.write(to: destinationUrl, options: Data.WritingOptions.atomic){
                        print("\n\nurl data written\n\n")
                    }
                    else{
                        print("\n\nerror again\n\n")
                    }
                }//end if let data
            }//end dispatch main
        }//end if let response.status
    }
}).resume()
            //}//end dispatch global
        }//end outer else

现在播放保存的文件:

class MyViewController: UIViewController {
 override func viewDidLoad() {
let baseUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

    let assetUrl = baseUrl.appendingPathComponent("MyFileSaveName.mp4")

    let url = assetUrl
    print(url)
    let avAssest = AVAsset(url: url)
    let playerItem = AVPlayerItem(asset: avAssest)


    let player = AVPlayer(playerItem: playerItem)

    let playerViewController = AVPlayerViewController()
    playerViewController.player = player

    self.present(playerViewController, animated: true, completion: {
        player.play()
    })
 }
}

但是,大多数网站不提供可直接下载的视频链接。您可以通过在UIWebView 中播放视频来获取该链接,并注册以下观察者以获取该链接:

NotificationCenter.default.addObserver(self, selector: #selector(videoPlayedInWebView), name: NSNotification.Name(rawValue: "AVPlayerItemBecameCurrentNotification"), object: nil)

 @objc func videoPlayedInWebView(aNotification: NSNotification) {
    if let playerItem: AVPlayerItem = aNotification.object as? AVPlayerItem{
        let asset: AVURLAsset = playerItem.asset as! AVURLAsset
        var downloadebaleVideoUrl = asset.url
        print(downloadebaleVideoUrl)
 }
}

这里的“downloadebaleVideoUrl”是视频在网络视图中播放后生成的链接。 如果您有任何问题随时问。 注意:这仅适用于具有 mp4 文件的网站。使用此方法不会下载“HLS”流。为此,您可以参考以下答案: https://stackoverflow.com/a/54493233/10758374

编辑:这仅适用于UIWebView,不适用于WKWebView

【讨论】:

  • 保存带有文件扩展名的路径组件,例如 .mp4 是我保存后播放它所必需的。
  • 上面哪种类型的_=会话?
  • URLSessionDataTask
  • 我尝试使用“FileManager.default,createFile(::)”写入我的文件,但没有成功。知道为什么吗? 'Data.write(to:options:)' 工作。
  • 我不确定,但我认为“çreateFile”用于文件,而下载的数据是视频,因此您需要 data.write 将确切的数据保存在内存中。
【解决方案2】:

您需要创建一个本地 url,这将是您应用文件系统中的一个路径,并将视频的数据写入其中。

    func writeToFile(urlString: String) {

    guard let videoUrl = URL(string: urlString) else {
        return
    }

    do {

        let videoData = try Data(contentsOf: videoUrl)

        let fm = FileManager.default

        guard let docUrl = fm.urls(for: .documentDirectory, in: .userDomainMask).first else {
            print("Unable to reach the documents folder")
            return false
        }

        let localUrl = docUrl.appendingPathComponent("test.mp4")

        try videoData.write(to: localUrl)

    } catch  {
        print("could not save data")
    }
 }

请记住始终在后台线程中调用此函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 2012-12-10
    • 2016-11-15
    • 2012-06-24
    • 2014-07-31
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多