【问题标题】:Get FileInputStream from Android content URI (or how to seek on an InputStream)从 Android 内容 URI 获取 FileInputStream(或如何在 InputStream 上查找)
【发布时间】:2015-01-30 21:03:46
【问题描述】:

我有一个播放自定义 h264 传输流的视频播放器应用。我的任务是能够通过诸如用户打开“画廊”、选择“电影”以及选择电影后选择要启动的应用程序等方法来启动我们的播放器……这一切都很完美。我的问题是如何使用 ContentResolver 在 InputStream 上来回搜索。

我也在这里阅读了很多帖子,例如 Android: Getting a file URI from a content URI? 以及关于使用 InputStream 而不是其他方法的咆哮 http://commonsware.com/blog/2013/08/07/for-android-apis-think-streams-not-files.html,但是对于大型视频文件,跳过和标记/重置将不适用于查找在我们的播放器中,所以一个普通的 InputStream 有点没用...... FileInputStream 工作得很好,作为一个黑客,我将 resolver.getInputStream 转换为 FileInputStream 并且它打球,但这是一个黑客......所以......如何如何从内容 uri 中获取 File 对象或 FileInputStream?或者我怎样才能有效地寻找输入流?

【问题讨论】:

  • 不确定为什么会被否决?使用 android 4.4,来自 uri 方法的路径显然不再可靠地工作,而使用 android 5.0,您更有可能获得内容类型,所以这是一个很好的相关问题...如果您要投反对票,请告诉我为什么?

标签: android uri h.264 fileinputstream android-contentresolver


【解决方案1】:

因此,虽然内容 URI 可能不受文件支持,但可以确定它是否...您可以使用 ParcelFileDescriptor 中的getStatSize,如果支持资产是,它将返回一个值一个文件,如果不是,则为 -1。如果是文件,那么显然你可以得到一个 FileInputStream 和底层通道

【讨论】:

    【解决方案2】:

    我的问题是如何使用 ContentResolver 在 InputStream 上来回搜索

    这并不总是可能的。这取决于ContentProvider 如何提供InputStream 内容。如果它使用由文件支持的ParcelFileDescriptor,则流将是可搜索的。如果它使用由createPipe() 创建的管道支持的ParcelFileDescriptor,则该流将不可搜索。我还没有在ParcelFileDescriptor 上测试过一些较新的管道选项,但我希望它们也是不可搜索的。

    但是对于大型视频文件,跳过和标记/重置将无法在我们的播放器中搜索

    我希望这些方法适用于某些 content:// Uri 值,但不是全部。如果您说您需要skip()mark()reset() 以外的其他东西,那么我不太确定您的意思。

    FileInputStream 工作得很好,作为一个 hack,我将 resolver.getInputStream 转换为 FileInputStream 并且它发挥了作用

    它肯定不会可靠地“打球”。此外,这似乎是无用的,因为我没有看到任何与您的场景相关的 on FileInputStream 方法,这些方法不是继承 from InputStream。值得注意的是,mark()reset()skip()InputStream 上。

    如何从内容 uri 中获取 File 对象或 FileInputStream?

    你没有。例如,视频文件可能位于可移动存储上,而在 Android 4.4+ 上,您无法直接访问可移动存储上的文件。

    如何有效地寻找输入流?

    如果markSupported() 返回真,请使用mark()reset()。如果没有,请告诉用户您无法播放该流,或禁用需要搜索的选项,或对您从流中读取的数据进行自己的缓存(例如,用于倒带操作)。

    【讨论】:

    • 1.如果我使用 BufferedInputStream 文档说我保证支持标记/重置......但是如果文件很大(因为视频文件往往是),你不能在流式传输后“返回”(或跳过)向前很多(或者至少它对我没有用)。 2. FileInputStream 允许我获取底层通道并设置位置,因此当用户擦洗视频时,它可以完美地在文件中的任何位置来回移动。 3. 4.4的内部媒体播放器怎么找?这显然是可行的,我只是找不到方法(因此是 q) 4. hack 是一个测试,也是一个 hack
    • @PapaWhiskey:“在你已经流式传输(或跳过)很多(或者至少它对我没有用)之后,你不能“返回”——这应该取决于底层数据源。 “内部媒体播放器在 4.4 中如何寻找?” - 如果“内部”是指“预安装”,则预安装的应用程序甚至可以访问可移动存储上的文件,前提是制造商以这种方式设置它们。而且,预安装的应用程序可以知道MediaStore 的内部工作原理,并且可以做出比分发到任意设备的 SDK 应用程序更多的假设。
    • @PapaWhiskey:要实现您想要的,您可能确实需要文件访问权限。您只是没有一种可靠的方式来获取文件,尤其是那些在 Android 4.4+ 上的可移动媒体上的文件。
    • 谢谢...我希望得到不同的答案,但是阅读了很多帖子(您通常都在上面),我觉得我不会得到我想要的,但是问...看起来你的“缓存”建议可能是我必须采取的路线
    猜你喜欢
    • 2023-03-09
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    相关资源
    最近更新 更多