Android:同时录制和流式传输

Posted

技术标签:

【中文标题】Android:同时录制和流式传输【英文标题】:Android: Recording and Streaming at the same time 【发布时间】:2015-05-14 18:15:16 【问题描述】:

这并不是一个真正的问题,而是我为解决我所面临的最具挑战性的功能之一所做的所有尝试。

我使用libstreaming 库将实时视频流式传输到Wowza Server,我需要同时将其录制到 SD 卡中。我在下面展示了我所有的尝试,以便从社区收集新的想法。

将字节从 libstreaming 流复制到 mp4 文件

发展

我们在 libstreaming 库中创建了一个拦截器,将所有发送的字节复制到一个 mp4 文件中。 Libstreaming 通过 LocalSocket 将字节发送到 Wowza 服务器。它使用 MediaRecorder 访问设备的摄像头和麦克风,并将输出文件设置为 LocalSocket 的输入流。我们所做的是围绕从 InputStream 扩展而来的输入流创建一个包装器,并在其中创建一个文件输出流。因此,每次 libstreaming 对 LocaSocket 的输入流执行读取操作时,我们都会将所有数据复制到输出流,尝试创建一个有效的 MP4 文件。

障碍

当我们尝试读取文件时,它已损坏。我们意识到 MP4 文件中缺少元信息。特别是 moov 原子。我们试图延迟流式传输的关闭,以便有时间发送此标头(这仍然是一个猜测),但它没有奏效。为了测试这些数据的一致性,我们使用付费软件来尝试恢复视频,包括标题。它变得可播放,但主要是绿屏。所以这成为了一个不可信的解决方案。我们还尝试使用“untrunc”,一个免费的开源命令行程序,它甚至无法启动恢复,因为没有 moov atom。

使用编译成android的ffmpeg访问摄像头

发展

FFMPEG 有一个带有 java 接口的 gradle 插件,可以在 Android 应用程序中使用它。我们认为我们可以通过命令行访问摄像机(它可能在“/dev/video0”中)并将其发送到媒体服务器。

障碍

我们在尝试访问相机时收到“权限被拒绝”错误。解决方法是 root 设备以访问它,但这会使手机失去保修并可能使它们变砖。

使用ffmpeg编译成android结合MediaRecorder

发展

我们试图通过 MediaRecorder 将 FFMPEG 流制成一个 mp4 文件并记录在手机中

障碍

FFMPEG 无法流式传输尚未完成录制的 MP4 文件。

使用 ffmpeg 通过 libstreaming 编译到 android

发展

Libstreaming 使用 LocalServerSocket 作为应用程序和服务器之间的连接,因此我们认为可以使用连接 LocalServerSocket 本地地址的 ffmpeg 将流直接复制到 SD 卡内的本地文件中。在流式传输开始后,我们还运行 ffmpeg 命令开始将数据记录到文件中。使用 ffmpeg,我们相信它会以正确的方式创建 MP4 文件,这意味着包含 moov atom 标头。

障碍

创建的“地址”不能通过命令行读取,因为它是手机内部的本地地址。所以无法复制。

使用 OpenCV

发展

OpenCV 是一个开源的跨平台库,为计算机视觉实验和应用程序提供构建块。它提供用于捕获、处理和呈现图像数据的高级接口。它有自己的 API 来连接设备摄像头,因此我们开始研究它,看看它是否具有同时进行流式传输和录制的必要功能。

障碍

我们发现该库并非真正定义为执行此操作,而是更多地用于图像数学操作。我们甚至得到了使用 libstreaming 的建议(我们已经这样做了)。

使用 Kickflip SDK

发展

Kickflip 是一种媒体流服务,提供自己的 SDK 用于在 android 和 ios 中进行开发。它还使用 HLS 代替 RTMP,这是一种较新的协议。

障碍

他们的 SDK 要求我们创建一个带有摄像头视图的 Activity,该视图占据了设备的整个屏幕,从而破坏了我们应用的可用性。

使用 Adob​​e Air

发展

我们开始就 Play 商店中已经提供的应用程序的其他开发人员进行咨询,这些应用程序已经流式传输到服务器。

障碍

与这些开发人员取得联系后,他们确信使用这项技术无法同时进行录制和流式传输。更重要的是,我们必须使用 Adob​​e Air 从头开始​​重做整个应用程序。

更新

Webrtc

发展

我们在this great project 之后开始使用 WebRTC。我们将信令服务器包含在我们的 NODEJS 服务器中,并开始通过套接字进行标准握手。我们仍在通过 webrtc 在本地录制和流媒体之间切换。

障碍

Webrtc 并不适用于所有网络配置。除此之外,相机获取都是原生代码,这使得尝试复制字节或拦截字节变得更加困难。

【问题讨论】:

cine.io 似乎类似于 kickflip。不过还没有测试过。 感谢您发布有关此问题的所有发现。我正在尝试在我的 Android 应用程序中做同样的事情。根据您的经验,大多数方法都有自己的问题。我想知道您是否找到了同时流式传输和录制视频的解决方案?如果是这样,你能提供一些解释或例子吗? 我现在已经迁移到webRTC进行直播了,但是还没有同时录制。我将使用这些额外信息更新列表! 感谢分享@BrunoSiqueira!您是否曾经完成过流式传输并保存到文件的解决方案? 【参考方案1】:

如果你愿意放弃 libstreaming,有一个库可以轻松地同时流式传输和记录到本地文件。

https://github.com/pedroSG94/rtmp-rtsp-stream-client-java

克隆项目并运行示例应用。例如,点击“默认 RTSP”。输入您的端点。点击“开始直播”,然后点击“开始录制”。然后点击“停止流”和“停止录制”。我已经用 Wowza Server 测试了它,它运行良好。该项目也可以用作库而不是独立应用程序。

【讨论】:

【参考方案2】:

一旦 OpenCV 3.0 可用(RC1 可以下载 here),我们可以在此列表中添加另一个选项:

使用 OpenCV 内置的 Motion-JPEG encoder

【讨论】:

以上是关于Android:同时录制和流式传输的主要内容,如果未能解决你的问题,请参考以下文章

Android:使用 AudioTrack 和 Socket 手动有效地流式传输音频

如何使用 mediaRecorder 流式传输 android 的内部音频+屏幕?

Android Mediamuxer moov atom

直播 RTMP/RTSP 播放器,无需在 Android 上使用 webview(WOWZA 服务器)

Android - 将视频从摄像头流式传输到另一个Android设备

如何同时播放/流式传输视频并保存?