3

我正在尝试从照片框架中的视频文件(或来自 PHAsset url 的照片)的 AVURLAsset url 创建一个 NSInputStream。我的代码如下

mAsset = [NSInputStream inputStreamWithFileAtPath:[murl path]];
[mAsset open];

网址是 file:///var/mobile/Media/DCIM/100APPLE/IMG_0519.JPG

现在,当我阅读时

NSUInteger readLength = [mAsset read:(uint8_t *)data maxLength:maxSize];

返回的 readLength 为 -1。我认为这与 iOS 照片资产的权限有关

如果这种方式不正确,有没有办法可以从照片框架资产的视频或图像文件中流式传输数据。任何帮助将不胜感激。

4

1 回答 1

7

虽然这个问题有点老了,但我将解释我是如何解决它的,因为我遇到了同样的问题,并且从未在互联网上找到任何适用于照片框架的有效解决方案。

由于 Apple API 的设计方式,确实不可能直接从 ALAsset 和 PHAsset 源文件上传。因此,让我开始讨论如何使用旧的(现已弃用的)API - AssetsLibrary 解决这个问题。

ALAssetRepresentation有一种很棒的方法getBytes:fromOffset:length:error:可以直接转换为NSInputStream's read:maxLength:。这为您提供了如何从一个实例中放置流的许多选项ALAsset——您可以创建一对绑定的输入和输出流,或者您可以选择使用更复杂的子类NSInputStream化路径。

因此,在使用 Photos Framework 时,这为您提供了第一个解决方案:您可以尝试从 a获取ALAssetURL,PHAsset然后回退到从旧的ALAssetRepresentation. 是的,没有记录此 URL 转换,是的,AssetsLibrary 现在已被弃用,但是嘿 - 这是一个选项。并且有一篇关于 Medium 的文章表明它确实是一个可行的解决方案。

现在让我们继续讨论照片框架。

在 iOS 9 中,Apple 引入了一个PHAssetResourceManager适合我们目的的新类。这是一种冗长的方法requestDataForAssetResource:options:dataReceivedHandler:completionHandler: a) 逐步为您提供大量资产数据;b) 它提供对这些底层数据资源的直接访问,并且如果照片存在于手机上(即不是来自 iCloud),则不需要文件系统的任何额外空间。旁注:“b)”中的语句实际上并没有记录,但在现实生活中被证明是正确的——你可以尝试填满设备的存储空间并调用这个方法,它会很好地工作。但是,有一些注意事项PHAssetResourceManager- 它异步传递数据并且数据块是任意大小的。很容易理解为什么这个新的 API 看起来像它的样子 - 使用照片框架,您可以使用相同的方法来处理本地和 iCloud 资产。但总而言之,这个新方法并没有像方法NSInputStream那样很好地转换为 's 接口。但请放心,我们可以利用此方法的一个特性使其对消费者友好,使其看起来就像旧方法一样。此方法按顺序将其数据传递到串行队列中。这意味着我们可以使用有界阻塞队列来创建一个看起来像. 有了这样的方法之后,获取资产的字节就变得超级容易了。getBytes:fromOffset:length:error:ALAssetRepresentationgetBytes:fromOffset:length:error:requestDataForAssetResource:options:dataReceivedHandler:completionHandler:func nextChunk() throws -> Data?

实际上,这正是我在库PHAssetResourceInputStream中所做的。它承担了从 Photos Framework 获取资产字节背后的所有繁重工作,并为您提供了一个简单的 API,所以我希望它对遇到同样问题的人有所帮助。

TL;博士

PHAssetResourceManager会让你开心。

于 2017-02-13T17:08:43.697 回答