对于 VoIP 语音质量监控应用程序,我需要将传入的 RTP 音频流与参考信号进行比较。对于信号比较本身,我使用预先存在的专用工具。对于其他部分(除了数据包捕获),Gstreamer 库似乎是一个不错的选择。我使用以下管道来模拟简单的 VoIP 客户端:
filesrc location=foobar.pcap ! pcapparse ! "application/x-rtp, payload=0, clock-rate=8000"
! gstrtpjitterbuffer ! rtppcmudepay ! mulawdec ! audioconvert
! audioresample ! wavenc ! filesink location=foobar.wav
Run Code Online (Sandbox Code Playgroud)
pcap 文件包含单个 RTP 媒体流。我制作了一个捕获文件,该文件丢失了原始 400 个 UDP 数据报中的 50 个。对于给定的音频样本(我的示例为 8 秒长):
[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]
Run Code Online (Sandbox Code Playgroud)
如果出现一定量的连续丢包,我希望输出这样的音频信号(“ -”表示静音):
[XXXXXXXXXXXXXXXXXXXXXXXX-----XXXXXXXXXXX]
Run Code Online (Sandbox Code Playgroud)
然而,音频文件中实际保存的内容是这样的(在我的示例中短了 1 秒):
[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]
Run Code Online (Sandbox Code Playgroud)
抖动缓冲器(该应用程序的关键部分)似乎无法正常工作。这可能是该元素的不兼容/缺陷吗pcapparse?我是否缺少管道中确保时间同步的关键部分?还有什么可能导致这种情况?
我试图了解spydroid(https://code.google.com/p/spydroid-ipcamera/)的工作原理,以便我可以为我的手机编写类似的应用程序。基于spydroid,这是我对RTSP、RTCP和RTP的理解。
RTSP 在指定端口上运行并设置一切。
RTCP 可以在任何端口上运行。有一个客户端端口和一个服务器端口。这是RTP的控制流程
RTP 可以在任何端口上运行。有一个客户端端口和一个服务器端口。其中包含音频和视频流。这很令人困惑,因为它似乎实际上并未在此端口上发送音频和视频。在spydroid中,它在端口5006上发送视频,在5004上发送音频。
Spydroid 正在通过 RTSP 发送此消息以确认端口...传输:RTP/AVP/UDP;单播;destination=123.456.789.00;client_port=65234-65235;server_port=44580-44581;ssrc=ba98a863;mode=play
我认为这意味着客户端(在我的例子中是 VLC)正在使用 UDP 侦听 65234 的 RTP 和 65235 的 RTCP 消息。此外,spydroid 正在侦听 44580 的 RTP 和 44581 的 RTCP。这是正确的吗?
现在,在 RTSP 的 DESCRIBE 序列中,spydroid 告诉客户端 m=video 5006 RTP/AVP 96 我认为这表明它将通过端口 5006 通过 UDP 发送视频。
我在上面的句子中所说的一切听起来都正确吗?
我真正想知道的是如何将此信息转发到正确的端口。客户端端口由 VLC 自动分配。我尝试运行这个命令... vlc "rtsp://192.168.1.104:8086" --rtp-client-port=58866 但VLC似乎忽略它并选择它自己的端口。所以我转发了端口 8086、5004 和 5006,但我不知道为 RTP 和 RTCP 连接转发哪个端口,因为它每次都会改变。我可以完成这项工作的唯一方法是将所有端口转发到我的计算机。(我有一个 linksys 路由器,它有一个 DMZ 选项)但这是一个糟糕的解决方案。有人可以指导我正确的方向吗?
另外,很高兴知道我正在这样做,因为我是通过互联网上的外部 IP 地址发送所有内容。其中spydroid旨在在局域网上使用。
我正在尝试通过 Galaxy S3 中的 madiacodec 解码来自 WIFI 摄像头的 h264 实时流,视频播放正常,但似乎媒体代码低级总是缓冲 1 秒的视频帧,新帧只能由新传入的 NAL 单元解码. 这会导致大约 1 秒的延迟。
当MediaCodec.createDecoderByType("video/avc");被调用时,我可以从 logcat 中看到分配了 22 个缓冲区,
01-04 15:39:02.799: I/ExtendedCodec(13374): Smoothstreaming Enabled
01-04 15:39:02.809: I/ACodec(13374): [OMX.qcom.video.decoder.avc] Now Loaded->Idle
01-04 15:39:02.809: I/ACodec(13374): [OMX.qcom.video.decoder.avc] Allocating 22 buffers from a native window of size 245760 on output port
01-04 15:39:02.889: D/DecodeActivity(13374): Decoder started at --- 1388867942894
01-04 15:39:02.889: I/ACodec(13374): [OMX.qcom.video.decoder.avc] Now Idle->Executing
01-04 15:39:03.019: I/ACodec(13374): [OMX.qcom.video.decoder.avc] Now Executing
Run Code Online (Sandbox Code Playgroud)
我可以看到大约需要将 16 个 NAL 单元推入解码器,然后才能输出任何帧。
我的问题是为什么这个视频缓冲?如果这是问题,我可以尝试以任何方式分配更少的缓冲区。无论如何我可以减少这个视频缓冲吗?
我想在 Android VideoView 中播放 RTP 流。我在 Linux 机器上使用 gstreamer 创建流并将 rtp 流发送到 udp 接收器。
是否可以在没有 RTSP 服务器的情况下在 Android VideoView 中使用此流?
我尝试将视频 URI 设置为“rtp://:@”,但随后出现错误“无法播放视频”。我还考虑过创建一个 SDP 文件并在 Android 设备上使用它。但我不确定这是否有效以及如何创建这样的文件。
谢谢
我在玩 jitsi。得到了示例形式的源代码。我稍微修改了一下。这是我所拥有的。我正在尝试在 ffplay 或任何其他播放器的 VLC 中播放传输的流,但我不能。
我使用这些应用程序参数来运行代码:
--local-port-base=5000 --remote-host=localhost --remote-port-base=10000
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
package com.company;
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
import org.jitsi.service.libjitsi.LibJitsi;
import org.jitsi.service.neomedia.*;
import org.jitsi.service.neomedia.device.MediaDevice;
import org.jitsi.service.neomedia.format.MediaFormat;
import org.jitsi.service.neomedia.format.MediaFormatFactory;
import java.io.PrintStream;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
/**
* Implements an example application in the fashion of JMF's AVTransmit2 example
* which demonstrates the use of the …Run Code Online (Sandbox Code Playgroud) 我见过几个浏览器原生WebRTC 应用程序的例子,比如将存储在服务器上的视频文件流式传输到一个或多个浏览器,但是否可以反过来做?即将网络摄像头从浏览器流式传输到服务器,用 C、C++、Java或其他语言编写?
我从 RTSP 流中得到了 H264 RTP 数据包。所以我想检测帧是否是I帧。
下面是我第一次打开流时得到的第一个数据包。所以我相信它是一个I帧。这是前 160 个字节:
packet:
00 00 00 01 67 4D 00 1F : 95 A8 14 01 6E 40 00 00
00 01 68 EE 3C 80 00 00 : 00 01 06 E5 01 33 80 00
00 00 01 65 B8 00 00 08 : 52 90 9F F6 BE D6 C6 9C
3D F6 D4 2F 49 FB F7 13 : F2 A9 C7 27 2D A4 75 59
6C DB …Run Code Online (Sandbox Code Playgroud) 如果 UDP(或 IP)层进行分段,我不明白为什么我们要在 RTP 级别进行分段。
据我了解,假设我们在以太网链路上,MTU 为 1500 字节。
例如,如果我必须发送 3880 字节,在 IP 层分段,将产生 3 个数据包,分别为 1500、1500 和 940 字节(IP 标头为 20 字节,因此总开销为 60 字节)。
如果我在 UDP 层执行此操作,则开销将为 84 字节(3x 28 字节)。
在 RTP 层,它有 120 字节的开销。
在 H264/NAL 打包层,FU-A 模式多出 3 个字节(因此最终为 123 个字节)。
对于这么小的数据包,初始数据包大小最终增加了 3.1%,而在 IP 层,总体上只会浪费 1.5%。
知道它总是比低层碎片更糟糕,是否有任何正当理由在 RTP 层制定如此复杂的打包规则?
我想使用 ffmpeg 将 RTP 流转码为 MP4(HTTP) 流,所以我可以在 html 视频标签中播放,
但我只能成功转码为 flv 格式。
下面是我的设置:
[/etc/ffserver.conf]
...
<Feed feed1.ffm>
File /tmp/feed1.ffm
FileMaxSize 5M
ACL allow localhost
</Feed>
<Stream flv>
Feed feed1.ffm
Format flv
VideoFrameRate 40
VideoBitRate 128
VideoSize 1920x1080
AVOptionVideo flags +global_header
AudioBitRate 24
AudioChannels 2
AudioSampleRate 44100
AVOptionAudio flags +global_header
</Stream>
<Stream mp4>
Feed feed1.ffm
Format mp4
VideoFrameRate 40
VideoBitRate 128
VideoSize 1920x1080
AVOptionVideo flags +global_header
AudioBitRate 24
AudioChannels 2
AudioSampleRate 44100
AVOptionAudio flags +global_header
</Stream>
<Stream avi>
Feed feed1.ffm
Format …Run Code Online (Sandbox Code Playgroud) 假设我的磁盘上有一个 wav 音频,称之为 MyDummy.wav。我想将它作为 RTP 数据包发送到服务器。但是正如我所看到的,RTP 数据包发送一些时间问题,比如 20 毫秒等等......以及我将如何确定 RTP 数据包的大小......我真的不知道如何做很多事情,而且所有事情都是必要的?
任何人都可以作为伪代码告诉如何将音频文件打包为 RTP 数据包,以及我应该在什么时间发送音频或提供任何我可以调查的示例代码?