Android:同时录制和流式传输

标签 android opencv ffmpeg stream webrtc

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

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

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

发展

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

障碍

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

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

发展

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

障碍

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

使用 ffmpeg 编译成 android 结合 MediaRecorder

发展

我们尝试通过 MediaRecorder 将 FFMPEG 流制作为在手机内录制的 mp4 文件

障碍

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

使用 ffmpeg 用 libstreaming 编译成 android

发展

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

障碍

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

使用 OpenCV

发展

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

障碍

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

使用 Kickflip SDK

发展

Kickflip 是一种媒体流服务,提供自己的 SDK 用于在 android 和 IOS 中进行开发。它还使用 HLS 而不是 RTMP,后者是一种较新的协议(protocol)。

障碍

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

使用 Adob​​e Air

发展

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

障碍

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

更新

网页版

发展

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

障碍

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

最佳答案

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

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

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

关于Android:同时录制和流式传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29012335/

相关文章:

java - 存储/检索椭圆曲线加密 (ECC) 公钥和私钥

java - LibGDX 计时器在 android 上恢复游戏后不启动

android - 从 URL 在 ImageView 中加载图像

c++ - 将 cv::Mat 转换为 ipcMatrix<ipcRGB>

python - 通过 Python 子进程传递包含 % 的 ffmpeg 命令

android - 在android中的视频中添加文本水印

android - Intent 服务永远不会启动

python-3.x - 使用opencv去除弧并完成矩形

c++ - OpenCV:如何读取 .pfm 文件?

c++ - 使用 ffmpeg 和分离的 AVCodecContext 解码 h264 rtsp