【问题标题】:How to decode the H.264 video stream received from parcelfiledescriptor如何解码从 parcelfiledescriptor 接收的 H.264 视频流
【发布时间】:2013-09-19 05:45:24
【问题描述】:

我正在两部安卓手机之间创建一个实时视频流的安卓应用程序。我已经在这些设备之间建立了套接字连接。我正在一个设备中捕获视频并将流发送到其他设备,但目前我只想保存在接收方移动设备中并保存它。我在一个设备中使用MediaRecorder 进行录制,因此通过设置数据流到接收器我使用parcelfiledescriptor 对象

客户端代码

    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
    mediaRecorder.setOutputFile(pfd.getFileDescriptor());

接收方代码

  pfd= ParcelFileDescriptor.fromSocket(s);
  InputStream in = new FileInputStream(pfd.getFileDescriptor()); 
  DataInputStream clientData = new DataInputStream(in);  
  OutputStream newDatabase = new FileOutputStream(file);
  int available=in.available();
  byte[] buffer = new byte[available];
  int length;


                while((length = in.read(buffer)) > 0)
                {
                    newDatabase.write(buffer, 0, length);

                }
                newDatabase.close();

正在接收方移动设备上创建视频文件,但无法接收任何字节。所以我是否必须在接收端解码即将到来的流,因为发送的视频流是在录制时编码的。那么如何解码接收到的流呢?我找到了一些解决方案,例如 MediaExtractor 和 MediaCodec ......但这是否适用于实时视频捕获,而且我正在 android version 2.3.6 GingerBread 上进行测试 是否可以从 MediaCodec 解码 2.3.6 版的视频流或其他方法可用?

【问题讨论】:

  • 嗨,Divya,你得到解决方案了吗,我也面临同样的问题,如果你找到解决方案,请告诉我
  • Hiiii Dipu 回复 David 我可以保存,但仍有很多问题...请查看我的评论以获取 David 的回复

标签: android sockets video-streaming decode video-capture


【解决方案1】:

正在接收端手机上创建视频文件,但无法接收任何字节。

如果我理解正确,您没有从套接字获取数据。那是一个单独的问题,与视频格式、解码或编码无关。

要调试您的套接字,使用一个单独的应用程序来转储接收到的数据可能会有所帮助。一旦数据看起来正常,您就可以进行下一步 - 解码视频。


问题的第二部分是视频格式。您正在使用 mp4,它不能用于流式传输。 Here is more info about the format structure. 您可以使用 mp4 将视频录制到本地文件中,然后通过套接字将整个文件传输到某处,但由于套接字的不可搜索性质(如链接文章中所述),无法进行真正的实时流式传输.文件开头有一块元数据,它充当“目录”,没有它,以前的数据只是垃圾。问题是,只有在获得所有内容后,您才能组装“目录”。但此时,数据已经通过套接字发送,您无法在其开头插入任何内容。

几乎没有什么替代方法,但这只是为了您未来的研究,我还没有使用它们。

最直观的方法是从 mp4 切换到 mpeg-ts,这是一个专为流媒体设计的容器。看看MediaRecorder.OutputFormat 中一个值为 8 的隐藏常量。

另一种选择是将原始 H.264 数据打包到 RTP/RTCP 数据包中,这也是为流式传输而设计的协议。此外,您的应用程序将能够流式传输到任何支持此协议的设备(例如运行 VLC 的 PC)。要进一步研究,请查看Spydroid IP camera,它确实可以做到这一点。

【讨论】:

  • Hiiii David...我能够通过 parcelfiledescriptor 对象将文件保存在其他设备上...意味着我更改了接收方的代码..意味着我设置了写入文件的条件直到它连接到套接字以将其写入服务器端移动设备..但另一个问题是服务器端保存的视频再次无法在我的默认 android 媒体播放器中播放文件...但它可以由其他媒体播放器,如移动设备上的 MXPlayer,通过 vlc 播放器安装在 PC 上......所以你能建议我如何解码视频和播放.. 方法是什么
  • 而且现在我需要它作为实时视频流,当我从一个设备录制时我需要在其他设备上播放它..我在服务器端和 mediaPlayer.setDataSource 创建了一个 MediaPlayer 对象(pfd.getFileDescriptor());它无法播放视频......它给出了一个例外“无法创建媒体播放器”......所以请你给一些想法如何解决这个问题并播放,因为在我的android应用程序中我只能创建默认的媒体播放器对象哪个不支持播放...如何进行....
  • 你也提到了一旦数据看起来很好,你就可以进入下一步——解码视频......那么该怎么做
  • 我建议你先尝试发送一个常规文件,看看它是否正常。然后你转向视频内容。但同样,您将无法通过写入文件/套接字并在另一端拉回数据来简单地进行流式传输。
  • Hiii 我可以发送一个常规文件...之前已经完成...这个问题只是面临...意味着我也知道我无法播放发送的流直接通过 parcelfiledescriptor 对象进行流式传输...因为它将具有标头和一些与视频相关的信息丢失...所以如何解决此问题意味着我需要获取该流并播放视频
猜你喜欢
  • 2012-08-08
  • 2015-06-14
  • 2012-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多