菜鸟教程小白 发表于 2022-12-11 17:09:42

ios - Swift 将视频 NSData 写入图库


                                            <p><p>我正在 swift 上编写一个 iOS 应用程序,它从 URL 下载视频并将其写入磁盘。我正在获取数据,但迄今为止未能成功写入磁盘。下面是代码:</p>

<pre><code>let yourURL = NSURL(string: &#34;http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4&#34;)
    //Create a URL request
    let urlRequest = NSURLRequest(URL: yourURL!)
    //get the data
    var theData = NSData();
    do{
      theData = try NSURLConnection.sendSynchronousRequest(urlRequest, returningResponse: nil)
    }
    catch let err as NSError
    {

    }

    try! PHPhotoLibrary.sharedPhotoLibrary().performChangesAndWait({ ()-&gt; Void in
      if #available(iOS 9.0, *) {
            PHAssetCreationRequest.creationRequestForAsset().addResourceWithType(PHAssetResourceType.Video, data: theData, options: nil)

            print(&#34;SUCESS&#34;);
      } else {

      };

    });
</code></pre>

<p>我收到以下错误,感谢任何见解:</p>

<pre><code>fatal error: &#39;try!&#39; expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=-1 &#34;(null)&#34;: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-703.0.18.1/src/swift/stdlib/public/core/ErrorType.swift, line 54
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>一个问题是您试图将视频(可能非常大)加载到 <code>NSData</code> 的内存中。如果您可以流式传输到持久存储中的文件,或者从这些文件流式传输,那就更好了。您可以通过使用 <code>NSURLSession</code> 下载任务而不是使用已弃用的 <code>NSURLConnection</code> 方法 <code>sendSynchronousRequest</code> 来完成此操作。</p>

<p>通过使用 <code>NSURLSession</code> 下载任务,您可以避免一次尝试在内存中保存一个大视频,而是将视频直接流式传输到持久存储。 (注意,不要使用 <code>NSURLSession</code> 数据任务,因为这将与 <code>NSURLConnection</code> 的已弃用方法 <code>sendSynchronousRequest</code> 具有相同的内存占用问题。)</p>

<p><code>NSURLSession</code> 下载任务将下载直接流式传输到持久存储后,您可以将文件移动到临时文件,然后使用 <code>addResourceWithType</code>,再次提供文件 URL 而不是 <code>NSData</code>。</p>

<p>当我这样做时(并添加了一些其他有用的错误检查),它似乎工作正常:</p>

<pre><code>// make sure it&#39;s authorized

PHPhotoLibrary.requestAuthorization { authorizationStatus in
    guard authorizationStatus == .Authorized else {
      print(&#34;cannot proceed without permission&#34;)
      return
    }

    self.downloadVideo()
}
</code></pre>

<p>地点:</p>

<pre><code>func downloadVideo() {
    let fileManager = NSFileManager.defaultManager()

    // create request

    let url = NSURL(string: &#34;http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4&#34;)!
    let task = NSURLSession.sharedSession().downloadTaskWithURL(url) { location, response, error in
      // make sure there weren&#39;t any fundamental networking errors

      guard location != nil &amp;&amp; error == nil else {
            print(error)
            return
      }

      // make sure there weren&#39;t and web server errors

      guard let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200 else {
            print(response)
            return
      }

      // move the file to temporary folder

      let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory())
            .URLByAppendingPathComponent(url.lastPathComponent!)

      do {
            try fileManager.moveItemAtURL(location!, toURL: fileURL)
      } catch {
            print(error)
            return
      }

      // now save it in our photo library

      PHPhotoLibrary.sharedPhotoLibrary().performChanges({
            PHAssetCreationRequest.creationRequestForAsset().addResourceWithType(.Video, fileURL: fileURL, options: nil)
      }, completionHandler: { success, error in
            defer {
                do {
                  try fileManager.removeItemAtURL(fileURL)
                } catch let removeError {
                  print(removeError)
                }
            }

            guard success &amp;&amp; error == nil else {
                print(error)
                return
            }

            print(&#34;SUCCESS&#34;)
      })
    }
    task.resume()
}
</code></pre>

<p>注意,由于 <code>NSURLSession</code> 对确保不执行不安全请求更为严格,您可能需要更新 <code>info.plist</code>(右键单击它并选择“打开方式”-“源代码”)并将其添加到文件中:</p>

<pre class="lang-xml prettyprint-override"><code>&lt;dict&gt;
    &lt;key&gt;NSExceptionDomains&lt;/key&gt;
    &lt;dict&gt;
      &lt;key&gt;sample-videos.com&lt;/key&gt;
      &lt;dict&gt;
            &lt;!--Include to allow subdomains--&gt;
            &lt;key&gt;NSIncludesSubdomains&lt;/key&gt;
            &lt;true/&gt;
            &lt;!--Include to allow HTTP requests--&gt;
            &lt;key&gt;NSTemporaryExceptionAllowsInsecureHTTPLoads&lt;/key&gt;
            &lt;true/&gt;
            &lt;!--Include to specify minimum TLS version--&gt;
            &lt;key&gt;NSTemporaryExceptionMinimumTLSVersion&lt;/key&gt;
            &lt;string&gt;TLSv1.1&lt;/string&gt;
      &lt;/dict&gt;
    &lt;/dict&gt;
&lt;/dict&gt;
</code></pre>

<p>但是,当我完成所有这些操作时,视频已成功下载并添加到我的照片库中。请注意,我在这里删除了所有同步请求(<code>NSURLSession</code> 是异步的,<code>performChanges</code> 也是如此),因为您几乎从不想执行同步请求(当然也永远不会在主队列上) )。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - Swift 将视频 NSData 写入图库,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/38732839/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/38732839/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Swift 将视频 NSData 写入图库