通过 WiFi 将一个安卓手机的实时视频流传输到另一个手机

119

我在互联网上搜索了好几天,想知道如何通过WiFi连接从一个安卓手机实现向另一个安卓手机的视频流传输功能,但是我好像找不到有用的东西。我在安卓开发人员网站、stackoverflow、谷歌和安卓博客上查看了示例代码,但都没有结果。我只能找到一些可以用于流媒体传输的手机到桌面或桌面到手机的解决方案,但是在我的应用中无法使用任何东西。

我需要使用Arduino ADK来控制机器人,因此我使用了两部手机,一部手机将被安装在机器人上,另一部手机将从机器人接收视频流。我提到这一点是因为我试图在广播时间和视图时间之间实现最小延迟。

我正在编写两个应用程序,一个主应用程序来控制机器人(从手持电话中),它将控制从机应用程序并接收该流,第二个从应用程序将在机器人上运行,控制电机/执行器/流式传输到主应用程序。不幸的是,我不能使用第三方应用程序。我需要将视频流代码集成到我的两个应用程序中。

有哪些选项可用于实现此目标?而且是否很难实现?因为我从来没有处理过视频流,尽管我在Java和安卓开发方面做得很好。我应该如何编码/解码流,如何初始化连接,是否需要使用UDP而不是TCP/IP?我真的不知道从哪里开始,因为没有任何示例代码可以参考。我相信这是可以实现的。只是找不到有用的东西以使我朝着正确的方向前进。

我偶然发现了Spydroid,但它使用了桌面上的VLC,所以对我没什么用。


编辑:看看Cagney Moreau的博客。他详细介绍了如何实现这一点。


1
你能分享一下你的项目吗?我正在做类似的事情,但是是在安卓和桌面(WebClient)之间进行视频流传输。我考虑使用HTML5 + WebSockets,但是遇到了很多问题... - Buksy
1
我正在开发一个解决方案,它与你尝试做的80%相同。你需要配置一个VOIP服务器,然后创建客户端来传输你的语音和视频。我也在寻找这个。如果有人知道,请告诉我。 - AZ_
1
email is given on my profile - AZ_
1
请查看我的项目。所有内容均使用Java编写并详细解释。http://cagneymoreau.com/stream-video-android/ - cagney
1
谢谢,我也在做一个机器人。很有趣的东西。 - cagney
显示剩余8条评论
4个回答

55

如果您的应用程序不需要录音和播放功能,则使用现成的流媒体应用程序和播放器是一个合理的选择。

但是,如果您的应用程序需要这些功能,您将需要研究MediaRecorder API(用于服务器/摄像头应用程序)和MediaPlayer(用于客户端/播放器应用程序)。

以下是服务器的快速示例代码:

// this is your network socket
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// this is the unofficially supported MPEG2TS format, suitable for streaming (Android 3.0+)
mMediaRecorder.setOutputFormat(8);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mediaRecorder.setOutputFile(pfd.getFileDescriptor());
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
mMediaRecorder.prepare();
mMediaRecorder.start();

对于玩家来说有点棘手,你可以尝试这样做:

// this is your network socket, connected to the server
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(pfd.getFileDescriptor());
mMediaPlayer.prepare();
mMediaPlayer.start();

不幸的是,MediaPlayer通常不喜欢这样做,因此您有几个选项:要么(a)将套接字中的数据保存到文件中(在获取到一些数据后),然后从文件播放MediaPlayer,要么(b)创建一个运行在本地的小型HTTP代理,可以接受MediaPlayer的GET请求,回复HTTP头,然后将数据从远程服务器复制到它。对于(a),您可以使用文件路径或文件URL创建MediaPlayer,对于(b),请向其提供指向您的代理的http URL。

另请参见:

使用套接字fd从手机流式传输视频到手机

MediaPlayer在mp3播放开始时出现卡顿


2
你好Alex,你有没有通过RTP从安卓手机发送本地存储的音频文件的经验? - B770
1
你好,能否请您发送完整的项目给我? - Umar Asghar
1
请问您能否发布完整的项目? - User6006
1
@AhmedHamdy确实:在API级别23(Android 6.0)中,您可以使用setDataSource(MediaDataSource)而不是FileDescriptor。 实现MediaDataSource将允许您进行自己的网络读取和缓冲,而无需写入临时文件。 - Alex I
如果您要将文件保存到磁盘上,它是一个MPEG2传输流文件(https://en.wikipedia.org/wiki/MPEG_transport_stream)。如果您给它一个.ts扩展名,它可以在ffmpeg或avplay中播放。@AhmedHamdy - Alex I
显示剩余5条评论

9

我曾经处理过类似的事情,但实时发送和播放视频是一件非常复杂的事情。建议您仅使用PNG格式。在我的实现中,我使用主机摄像头捕获PNG图片,然后将其通过网络发送到客户端,客户端收到图像后立即显示它并请求下一个图像从主机获取。由于您连接WIFI通信速度足以每秒传输8-10张图片(仅为近似值,我曾在蓝牙上工作),因此这将看起来像是连续的视频,但需要付出更少的努力。对于通信,您可以使用UDP套接字(更快,不那么复杂)或DLNA(不确定如何使用)。


是的,这将是我的最后选择。感谢您的反馈! - androidu
3
JPEG流肯定比PNG流更高效吧? - stealthcopter
我只是建议使用一个图像,你可以使用任何格式你希望的。 - Arveen
@krossreg> 你能否请粘贴一下你所建议的示例代码? - Jasper

8

您可以使用IP Webcam,或者使用DLNA。例如,三星设备配备了一个名为AllShare的应用程序,可以在网络上共享和访问启用DLNA的设备。不过我认为IP Webcam是最好的选择。您应该能够使用MX Video player或类似的播放器打开它创建的流。


2
我正在编写两个应用程序,一个主应用程序用于控制机器人(从手持电话)并查看机器人所看到的内容,第二个从属应用程序将运行在机器人绑定的手机上,控制电机/执行器/流媒体。不幸的是,我不能使用第三方应用程序。我需要将视频流代码集成到我的两个应用程序中。 - androidu
也许你可以对DLNA规范进行一些研究,并尝试使用它来制作自己的应用程序,或者给IP Webcam的开发人员发送电子邮件并请求帮助。 - ldam
是的,我想我别无选择了。 - androidu

5
你可以检查一下安卓VLC,它可以流媒体播放视频。如果你想了解更多信息,可以查看他们的GIT以分析他们在做什么。祝好运!

4
我正在研究Android VLC。您可以告诉我如何使用它来流式传输视频吗? - user1914692

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接